diff --git a/src/blind.h b/src/blind.h index 650f933a27..24d1ede4d4 100644 --- a/src/blind.h +++ b/src/blind.h @@ -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; diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index c49b9fa36b..764d4f137f 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -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) { @@ -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; diff --git a/src/policy/fees.h b/src/policy/fees.h index c8472a12f5..81171f00ef 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -174,8 +174,8 @@ private: * 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 diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index ae5a160c99..f7526c71bc 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -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); @@ -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); @@ -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. @@ -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; } } }