mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-05-13 03:30:42 +02:00
Merge datacarriercost-25+knots
This commit is contained in:
commit
06ff2c34e3
@ -19,7 +19,7 @@ static void AddTx(const CTransactionRef& tx, const CAmount& nFee, CTxMemPool& po
|
||||
LockPoints lp;
|
||||
pool.addUnchecked(CTxMemPoolEntry(
|
||||
tx, nFee, nTime, dPriority, nHeight,
|
||||
tx->GetValueOut(), spendsCoinbase, sigOpCost, lp));
|
||||
tx->GetValueOut(), spendsCoinbase, /*extra_weight=*/0, sigOpCost, lp));
|
||||
}
|
||||
|
||||
// Right now this is only testing eviction performance in an extremely small
|
||||
|
@ -19,7 +19,7 @@ static void AddTx(const CTransactionRef& tx, CTxMemPool& pool) EXCLUSIVE_LOCKS_R
|
||||
bool spendsCoinbase = false;
|
||||
unsigned int sigOpCost = 4;
|
||||
LockPoints lp;
|
||||
pool.addUnchecked(CTxMemPoolEntry(tx, 1000, nTime, coinage_priority, nHeight, tx->GetValueOut(), spendsCoinbase, sigOpCost, lp));
|
||||
pool.addUnchecked(CTxMemPoolEntry(tx, 1000, nTime, coinage_priority, nHeight, tx->GetValueOut(), spendsCoinbase, /*extra_weight=*/0, sigOpCost, lp));
|
||||
}
|
||||
|
||||
struct Available {
|
||||
|
@ -17,7 +17,7 @@
|
||||
static void AddTx(const CTransactionRef& tx, const CAmount& fee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
|
||||
{
|
||||
LockPoints lp;
|
||||
pool.addUnchecked(CTxMemPoolEntry(tx, fee, /*time=*/0, /*entry_priority=*/0, /*entry_height=*/0, /*in_chain_input_value=*/0, /*spends_coinbase=*/false, /*sigops_cost=*/4, lp));
|
||||
pool.addUnchecked(CTxMemPoolEntry(tx, fee, /*time=*/0, /*entry_priority=*/0, /*entry_height=*/0, /*in_chain_input_value=*/0, /*spends_coinbase=*/false, /*extra_weight=*/0, /*sigops_cost=*/4, lp));
|
||||
}
|
||||
|
||||
static void RpcMempool(benchmark::Bench& bench)
|
||||
|
@ -608,6 +608,7 @@ void SetupServerArgs(ArgsManager& argsman)
|
||||
argsman.AddArg("-bytespersigop", strprintf("Equivalent bytes per sigop in transactions for relay and mining (default: %u)", DEFAULT_BYTES_PER_SIGOP), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
argsman.AddArg("-bytespersigopstrict", strprintf("Minimum bytes per sigop in transactions we relay and mine (default: %u)", DEFAULT_BYTES_PER_SIGOP_STRICT), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
argsman.AddArg("-datacarrier", strprintf("Relay and mine data carrier transactions (default: %u)", DEFAULT_ACCEPT_DATACARRIER), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
argsman.AddArg("-datacarriercost", strprintf("Treat extra data in transactions as at least N vbytes per actual byte (default: %s)", DEFAULT_WEIGHT_PER_DATA_BYTE / 4.0), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
argsman.AddArg("-datacarrierfullcount", strprintf("Apply datacarriersize limit to all known datacarrier methods (default: %s)", DEFAULT_DATACARRIER_FULLCOUNT), ArgsManager::ALLOW_ANY | (DEFAULT_DATACARRIER_FULLCOUNT ? uint32_t{ArgsManager::DEBUG_ONLY} : 0), OptionsCategory::NODE_RELAY);
|
||||
argsman.AddArg("-datacarriersize", strprintf("Maximum size of data in data carrier transactions we relay and mine (default: %u)", MAX_OP_RETURN_RELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
argsman.AddArg("-mempoolfullrbf", strprintf("Accept transaction replace-by-fee without requiring replaceability signaling (default: %u)", (DEFAULT_MEMPOOL_RBF_POLICY == RBFPolicy::Always)), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
@ -998,6 +999,10 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
|
||||
}
|
||||
}
|
||||
|
||||
if (auto parsed = args.GetFixedPointArg("-datacarriercost", 2)) {
|
||||
g_weight_per_data_byte = ((*parsed * WITNESS_SCALE_FACTOR) + 99) / 100;
|
||||
}
|
||||
|
||||
nBytesPerSigOp = args.GetIntArg("-bytespersigop", nBytesPerSigOp);
|
||||
nBytesPerSigOpStrict = args.GetIntArg("-bytespersigopstrict", nBytesPerSigOpStrict);
|
||||
|
||||
|
@ -96,6 +96,7 @@ private:
|
||||
CAmount inChainInputValue; //!< Sum of all txin values that are already in blockchain
|
||||
const bool spendsCoinbase; //!< keep track of transactions that spend a coinbase
|
||||
const int64_t sigOpCost; //!< Total sigop cost
|
||||
const int32_t m_extra_weight; //!< Policy-only additional transaction weight beyond nTxWeight
|
||||
const size_t nModSize; //!< Cached modified size for priority
|
||||
CAmount m_modified_fee; //!< Used for determining the priority of the transaction for mining in a block
|
||||
LockPoints lockPoints; //!< Track the height and time at which tx was final
|
||||
@ -117,6 +118,7 @@ public:
|
||||
CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
|
||||
int64_t time, double entry_priority, unsigned int entry_height,
|
||||
CAmount in_chain_input_value, bool spends_coinbase,
|
||||
int32_t extra_weight,
|
||||
int64_t sigops_cost, LockPoints lp)
|
||||
: tx{tx},
|
||||
nFee{fee},
|
||||
@ -131,6 +133,7 @@ public:
|
||||
inChainInputValue{in_chain_input_value},
|
||||
spendsCoinbase{spends_coinbase},
|
||||
sigOpCost{sigops_cost},
|
||||
m_extra_weight{extra_weight},
|
||||
nModSize{CalculateModifiedSize(*tx, GetTxSize())},
|
||||
m_modified_fee{nFee},
|
||||
lockPoints{lp},
|
||||
@ -159,7 +162,7 @@ public:
|
||||
const CAmount& GetFee() const { return nFee; }
|
||||
size_t GetTxSize() const
|
||||
{
|
||||
return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp);
|
||||
return GetVirtualTransactionSize(nTxWeight + m_extra_weight, sigOpCost, ::nBytesPerSigOp);
|
||||
}
|
||||
size_t GetTxWeight() const { return nTxWeight; }
|
||||
std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; }
|
||||
|
@ -708,7 +708,7 @@ public:
|
||||
{
|
||||
if (!m_node.mempool) return true;
|
||||
LockPoints lp;
|
||||
CTxMemPoolEntry entry(tx, 0, 0, 0, 0, 0, false, 0, lp);
|
||||
CTxMemPoolEntry entry(tx, 0, 0, 0, 0, 0, false, /*extra_weight=*/0, 0, lp);
|
||||
const CTxMemPool::Limits& limits{m_node.mempool->m_limits};
|
||||
LOCK(m_node.mempool->cs);
|
||||
return m_node.mempool->CalculateMemPoolAncestors(entry, limits).has_value();
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <coins.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <consensus/tx_verify.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <node/psbt.h>
|
||||
#include <policy/policy.h>
|
||||
#include <policy/settings.h>
|
||||
@ -137,7 +138,7 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
|
||||
|
||||
if (success) {
|
||||
CTransaction ctx = CTransaction(mtx);
|
||||
size_t size(GetVirtualTransactionSize(ctx, GetTransactionSigOpCost(ctx, view, STANDARD_SCRIPT_VERIFY_FLAGS), ::nBytesPerSigOp));
|
||||
size_t size(GetVirtualTransactionSize(GetTransactionWeight(ctx) + CalculateExtraTxWeight(ctx, view, ::g_weight_per_data_byte), GetTransactionSigOpCost(ctx, view, STANDARD_SCRIPT_VERIFY_FLAGS), ::nBytesPerSigOp));
|
||||
result.estimated_vsize = size;
|
||||
// Estimate fee rate
|
||||
CFeeRate feerate(fee, size);
|
||||
|
@ -426,3 +426,26 @@ size_t DatacarrierBytes(const CTransaction& tx, const CCoinsViewCache& view)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t CalculateExtraTxWeight(const CTransaction& tx, const CCoinsViewCache& view, const unsigned int weight_per_data_byte)
|
||||
{
|
||||
int32_t mod_weight{0};
|
||||
|
||||
// Add in any extra weight for data bytes
|
||||
if (weight_per_data_byte > 1) {
|
||||
for (const CTxIn& txin : tx.vin) {
|
||||
const CTxOut &utxo = view.AccessCoin(txin.prevout).out;
|
||||
auto[script, consensus_weight_per_byte] = GetScriptForTransactionInput(utxo.scriptPubKey, txin);
|
||||
if (weight_per_data_byte > consensus_weight_per_byte) {
|
||||
mod_weight += script.DatacarrierBytes() * (weight_per_data_byte - consensus_weight_per_byte);
|
||||
}
|
||||
}
|
||||
if (weight_per_data_byte > WITNESS_SCALE_FACTOR) {
|
||||
for (const CTxOut& txout : tx.vout) {
|
||||
mod_weight += txout.scriptPubKey.DatacarrierBytes() * (weight_per_data_byte - WITNESS_SCALE_FACTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mod_weight;
|
||||
}
|
||||
|
@ -45,6 +45,8 @@ static constexpr unsigned int DEFAULT_INCREMENTAL_RELAY_FEE{1000};
|
||||
static constexpr unsigned int DEFAULT_BYTES_PER_SIGOP{20};
|
||||
/** Default for -bytespersigopstrict */
|
||||
static constexpr unsigned int DEFAULT_BYTES_PER_SIGOP_STRICT{20};
|
||||
/** Default for -datacarriercost (multiplied by WITNESS_SCALE_FACTOR) */
|
||||
static constexpr unsigned int DEFAULT_WEIGHT_PER_DATA_BYTE{1};
|
||||
/** Default for -permitbaremultisig */
|
||||
static constexpr bool DEFAULT_PERMIT_BAREMULTISIG{true};
|
||||
/** The maximum number of witness stack items in a standard P2WSH script */
|
||||
@ -172,4 +174,6 @@ std::pair<CScript, unsigned int> GetScriptForTransactionInput(CScript prevScript
|
||||
|
||||
size_t DatacarrierBytes(const CTransaction& tx, const CCoinsViewCache& view);
|
||||
|
||||
int32_t CalculateExtraTxWeight(const CTransaction& tx, const CCoinsViewCache& view, const unsigned int weight_per_data_byte);
|
||||
|
||||
#endif // BITCOIN_POLICY_POLICY_H
|
||||
|
@ -9,3 +9,4 @@
|
||||
|
||||
unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP;
|
||||
unsigned int nBytesPerSigOpStrict = DEFAULT_BYTES_PER_SIGOP_STRICT;
|
||||
unsigned int g_weight_per_data_byte = DEFAULT_WEIGHT_PER_DATA_BYTE;
|
||||
|
@ -8,5 +8,6 @@
|
||||
|
||||
extern unsigned int nBytesPerSigOp;
|
||||
extern unsigned int nBytesPerSigOpStrict;
|
||||
extern unsigned int g_weight_per_data_byte;
|
||||
|
||||
#endif // BITCOIN_POLICY_SETTINGS_H
|
||||
|
@ -38,6 +38,7 @@ CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzzed_data_provider,
|
||||
const double coinage_priority = fuzzed_data_provider.ConsumeFloatingPoint<double>();
|
||||
const unsigned int entry_height = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, std::numeric_limits<unsigned int>::max() - 1);
|
||||
const bool spends_coinbase = fuzzed_data_provider.ConsumeBool();
|
||||
const int32_t extra_weight = fuzzed_data_provider.ConsumeIntegralInRange<int32_t>(0, GetTransactionWeight(tx) * 3);
|
||||
const unsigned int sig_op_cost = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, MAX_BLOCK_SIGOPS_COST);
|
||||
return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, coinage_priority, entry_height, tx.GetValueOut(), spends_coinbase, sig_op_cost, {}};
|
||||
return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, coinage_priority, entry_height, tx.GetValueOut(), spends_coinbase, extra_weight, sig_op_cost, {}};
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ std::vector<CTransactionRef> TestChain100Setup::PopulateMempool(FastRandomContex
|
||||
double dPriority = GetPriority(*ptx, active_chainstate.CoinsTip(), height + 1, in_chain_input_value);
|
||||
m_node.mempool->addUnchecked(CTxMemPoolEntry(ptx, /*fee=*/(total_in - num_outputs * amount_per_output),
|
||||
/*time=*/0, /*entry_priority=*/ dPriority, /*entry_height=*/ height,
|
||||
in_chain_input_value, /*spends_coinbase=*/false, /*sigops_cost=*/4, lp));
|
||||
in_chain_input_value, /*spends_coinbase=*/false, /*extra_weight=*/0, /*sigops_cost=*/4, lp));
|
||||
}
|
||||
--num_transactions;
|
||||
}
|
||||
|
@ -36,5 +36,5 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransactionRef& tx) const
|
||||
{
|
||||
const double dPriority = 0;
|
||||
const CAmount inChainValue = 0;
|
||||
return CTxMemPoolEntry{tx, nFee, TicksSinceEpoch<std::chrono::seconds>(time), dPriority, nHeight, inChainValue, spendsCoinbase, sigOpCost, lp};
|
||||
return CTxMemPoolEntry{tx, nFee, TicksSinceEpoch<std::chrono::seconds>(time), dPriority, nHeight, inChainValue, spendsCoinbase, /*extra_weight=*/0, sigOpCost, lp};
|
||||
}
|
||||
|
@ -535,6 +535,25 @@ int64_t SettingToInt(const util::SettingsValue& value, int64_t nDefault)
|
||||
return SettingToInt(value).value_or(nDefault);
|
||||
}
|
||||
|
||||
std::optional<int64_t> ArgsManager::GetFixedPointArg(const std::string& arg, int decimals) const
|
||||
{
|
||||
const util::SettingsValue value = GetSetting(arg);
|
||||
return SettingToFixedPoint(value, decimals);
|
||||
}
|
||||
|
||||
std::optional<int64_t> SettingToFixedPoint(const util::SettingsValue& value, int decimals)
|
||||
{
|
||||
if (value.isNull()) return std::nullopt;
|
||||
if (value.isFalse()) return 0;
|
||||
if (value.isTrue()) return 1;
|
||||
if (!value.isNum()) value.get_str(); // throws an exception if type is wrong
|
||||
int64_t v;
|
||||
if (!ParseFixedPoint(value.getValStr(), decimals, &v)) {
|
||||
throw std::runtime_error(strprintf("Parse error ('%s')", value.getValStr()));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
bool ArgsManager::GetBoolArg(const std::string& strArg, bool fDefault) const
|
||||
{
|
||||
return GetBoolArg(strArg).value_or(fDefault);
|
||||
|
@ -102,6 +102,8 @@ std::optional<std::string> SettingToString(const util::SettingsValue&);
|
||||
int64_t SettingToInt(const util::SettingsValue&, int64_t);
|
||||
std::optional<int64_t> SettingToInt(const util::SettingsValue&);
|
||||
|
||||
std::optional<int64_t> SettingToFixedPoint(const util::SettingsValue&, int decimals);
|
||||
|
||||
bool SettingToBool(const util::SettingsValue&, bool);
|
||||
std::optional<bool> SettingToBool(const util::SettingsValue&);
|
||||
|
||||
@ -314,6 +316,15 @@ protected:
|
||||
int64_t GetIntArg(const std::string& strArg, int64_t nDefault) const;
|
||||
std::optional<int64_t> GetIntArg(const std::string& strArg) const;
|
||||
|
||||
/**
|
||||
* Return fixed-point argument
|
||||
*
|
||||
* @param arg Argument to get (e.g. "-foo")
|
||||
* @param decimals Number of fractional decimal digits to accept
|
||||
* @return Command-line argument (0 if invalid number) multiplied by 10**decimals
|
||||
*/
|
||||
std::optional<int64_t> GetFixedPointArg(const std::string& arg, int decimals) const;
|
||||
|
||||
/**
|
||||
* Return boolean argument or default value
|
||||
*
|
||||
|
@ -950,8 +950,9 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
||||
}
|
||||
}
|
||||
|
||||
int32_t extra_weight = CalculateExtraTxWeight(*ptx, m_view, ::g_weight_per_data_byte);
|
||||
entry.reset(new CTxMemPoolEntry(ptx, ws.m_base_fees, nAcceptTime, dPriority, m_active_chainstate.m_chain.Height(),
|
||||
inChainInputValue, fSpendsCoinbase, nSigOpsCost, lock_points.value()));
|
||||
inChainInputValue, fSpendsCoinbase, extra_weight, nSigOpsCost, lock_points.value()));
|
||||
ws.m_vsize = entry->GetTxSize();
|
||||
entry->mapSPK = mapSPK;
|
||||
|
||||
|
@ -15,7 +15,7 @@ import re
|
||||
|
||||
FOLDER_GREP = 'src'
|
||||
FOLDER_TEST = 'src/test/'
|
||||
REGEX_ARG = r'\b(?:GetArg|GetArgs|GetBoolArg|GetIntArg|GetPathArg|IsArgSet|get_net)\("(-[^"]+)"'
|
||||
REGEX_ARG = r'\b(?:GetArg|GetArgs|GetBoolArg|GetIntArg|GetFixedPointArg|GetPathArg|IsArgSet|get_net)\("(-[^"]+)"'
|
||||
REGEX_DOC = r'AddArg\("(-[^"=]+?)(?:=|")'
|
||||
CMD_ROOT_DIR = '$(git rev-parse --show-toplevel)/{}'.format(FOLDER_GREP)
|
||||
CMD_GREP_ARGS = r"git grep --perl-regexp '{}' -- {} ':(exclude){}'".format(REGEX_ARG, CMD_ROOT_DIR, FOLDER_TEST)
|
||||
|
Loading…
Reference in New Issue
Block a user