Skip to content

Commit

Permalink
Merge ElementsProject#843: Support fee estimation for fees lower than…
Browse files Browse the repository at this point in the history
… 1 sat/byte

8aab8a2 Optimize size estimation in FundTransaction (Steven Roose)
6939a72 Support fee estimation for fees lower than 1 sat/byte (Steven Roose)

Pull request description:

  The fee estimation buckets also have a minimum of 1000 sat/kB.

  This PR lowers that limit and also discards old estimates files.

Tree-SHA512: a097915b4f8f31cb2185afbbf6a247816945f1bfe01469260a1f4c90fed36eea2b7ec63b85143c35e335f9fc6877d7392b8969fc2ab1811c27e67bc94b4d6133
  • Loading branch information
stevenroose committed Mar 31, 2020
2 parents c84e718 + 8aab8a2 commit b47d087
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 5 deletions.
2 changes: 2 additions & 0 deletions src/blind.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
//! ELEMENTS:
// 52-bit rangeproof size
static const size_t DEFAULT_RANGEPROOF_SIZE = 4174;
// constant-size surjection proof
static const size_t SURJECTION_PROOF_SIZE = 67;
// 32 bytes of asset type, 32 bytes of asset blinding factor in sidechannel
static const size_t SIDECHANNEL_MSG_SIZE = 64;

Expand Down
7 changes: 6 additions & 1 deletion src/policy/fees.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,9 @@ bool CBlockPolicyEstimator::Write(CAutoFile& fileout) const
{
try {
LOCK(m_cs_fee_estimator);
fileout << 149900; // version required to read: 0.14.99 or later
//ELEMENTS: We upped this from 0.14.99 in upstream because
// we changed the bucket sizes.
fileout << 180107; // version required to read: 0.18.1.7
fileout << CLIENT_VERSION; // version that wrote the file
fileout << nBestSeenHeight;
if (BlockSpan() > HistoricalBlockSpan()/2) {
Expand Down Expand Up @@ -938,6 +940,9 @@ bool CBlockPolicyEstimator::Read(CAutoFile& filein)

if (nVersionRequired < 149900) {
LogPrintf("%s: incompatible old fee estimation data (non-fatal). Version: %d\n", __func__, nVersionRequired);
} else if (nVersionThatWrote < 180107) {
//ELEMENTS: we changed the buckets in 0.18.1.7
LogPrintf("%s: incompatible old fee estimation data (non-fatal). Version: %d\n", __func__, nVersionThatWrote);
} else { // New format introduced in 149900
unsigned int nFileHistoricalFirst, nFileHistoricalBest;
filein >> nFileHistoricalFirst >> nFileHistoricalBest;
Expand Down
4 changes: 2 additions & 2 deletions src/policy/fees.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ class CBlockPolicyEstimator
* invalidates old estimates files. So leave it at 1000 unless it becomes
* necessary to lower it, and then lower it substantially.
*/
static constexpr double MIN_BUCKET_FEERATE = 1000;
static constexpr double MAX_BUCKET_FEERATE = 1e7;
static constexpr double MIN_BUCKET_FEERATE = 100;
static constexpr double MAX_BUCKET_FEERATE = 1e6;

/** Spacing of FeeRate buckets
* We have to lump transactions into buckets based on feerate, but we want to be able
Expand Down
17 changes: 15 additions & 2 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3223,6 +3223,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
change_prototype_txout.nAsset.vchCommitment.resize(33);
coin_selection_params.change_output_size = GetSerializeSize(change_prototype_txout);
coin_selection_params.change_output_size += DEFAULT_RANGEPROOF_SIZE/WITNESS_SCALE_FACTOR;
coin_selection_params.change_output_size += SURJECTION_PROOF_SIZE/WITNESS_SCALE_FACTOR;
}

CFeeRate discard_rate = GetDiscardRate(*this, ::feeEstimator);
Expand Down Expand Up @@ -3266,6 +3267,14 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std

// vouts to the payees
coin_selection_params.tx_noinputs_size = 11; // Static vsize overhead + outputs vsize. 4 nVersion, 4 nLocktime, 1 input count, 1 output count, 1 witness overhead (dummy, flag, stack size)

// Account for the fee output in the tx.
if (g_con_elementsmode) {
CTxOut fee(::policyAsset, nFeeRet, CScript());
assert(fee.IsFee());
coin_selection_params.tx_noinputs_size += ::GetSerializeSize(fee, PROTOCOL_VERSION);
}

for (const CRecipient& recipient : vecSend)
{
CTxOut txout(recipient.asset, recipient.nAmount, recipient.scriptPubKey);
Expand All @@ -3287,8 +3296,6 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
txout.nValue = txout.nValue.GetAmount() - nFeeRet % nSubtractFeeFromAmount;
}
}
// Include the fee cost for outputs. Note this is only used for BnB right now
coin_selection_params.tx_noinputs_size += ::GetSerializeSize(txout, PROTOCOL_VERSION);
// ELEMENTS: Core's logic isn't great here. We should be computing
// cost of making output + future spend. We're not as concerned
// about dust anyways, so let's focus upstream.
Expand All @@ -3305,12 +3312,18 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
strFailReason = _("Transaction amount too small");
return false;
}

// Include the fee cost for outputs. Note this is only used for BnB right now
coin_selection_params.tx_noinputs_size += ::GetSerializeSize(txout, PROTOCOL_VERSION);
txNew.vout.push_back(txout);

if (blind_details) {
blind_details->o_pubkeys.push_back(recipient.confidentiality_key);
if (blind_details->o_pubkeys.back().IsFullyValid()) {
blind_details->num_to_blind++;
blind_details->only_recipient_blind_index = txNew.vout.size()-1;
coin_selection_params.tx_noinputs_size += DEFAULT_RANGEPROOF_SIZE/WITNESS_SCALE_FACTOR;
coin_selection_params.tx_noinputs_size += SURJECTION_PROOF_SIZE/WITNESS_SCALE_FACTOR;
}
}
}
Expand Down

0 comments on commit b47d087

Please sign in to comment.