Skip to content

Commit 42ecf3b

Browse files
committed
Merge datacarriercost-28+knots
2 parents 570cb5c + da3db67 commit 42ecf3b

File tree

18 files changed

+82
-12
lines changed

18 files changed

+82
-12
lines changed

src/bench/mempool_eviction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ static void AddTx(const CTransactionRef& tx, const CAmount& nFee, CTxMemPool& po
2121
pool.addUnchecked(CTxMemPoolEntry(
2222
tx, nFee, nTime, dPriority, nHeight, sequence,
2323
tx->GetValueOut(),
24-
spendsCoinbase, sigOpCost, lp));
24+
spendsCoinbase, /*extra_weight=*/0, sigOpCost, lp));
2525
}
2626

2727
// Right now this is only testing eviction performance in an extremely small

src/bench/mempool_stress.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ static void AddTx(const CTransactionRef& tx, CTxMemPool& pool) EXCLUSIVE_LOCKS_R
2222
bool spendsCoinbase = false;
2323
unsigned int sigOpCost = 4;
2424
LockPoints lp;
25-
pool.addUnchecked(CTxMemPoolEntry(tx, 1000, nTime, nHeight, sequence, /*entry_tx_inputs_coin_age=*/coin_age, tx->GetValueOut(), spendsCoinbase, sigOpCost, lp));
25+
pool.addUnchecked(CTxMemPoolEntry(tx, 1000, nTime, nHeight, sequence, /*entry_tx_inputs_coin_age=*/coin_age, tx->GetValueOut(), spendsCoinbase, /*extra_weight=*/0, sigOpCost, lp));
2626
}
2727

2828
struct Available {

src/bench/rpc_mempool.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
static void AddTx(const CTransactionRef& tx, const CAmount& fee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
1818
{
1919
LockPoints lp;
20-
pool.addUnchecked(CTxMemPoolEntry(tx, fee, /*time=*/0, /*entry_height=*/0, /*entry_sequence=*/0, /*entry_tx_inputs_coin_age=*/0.0, /*in_chain_input_value=*/0, /*spends_coinbase=*/false, /*sigops_cost=*/4, lp));
20+
pool.addUnchecked(CTxMemPoolEntry(tx, fee, /*time=*/0, /*entry_height=*/0, /*entry_sequence=*/0, /*entry_tx_inputs_coin_age=*/0.0, /*in_chain_input_value=*/0, /*spends_coinbase=*/false, /*extra_weight=*/0, /*sigops_cost=*/4, lp));
2121
}
2222

2323
static void RpcMempool(benchmark::Bench& bench)

src/common/args.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,25 @@ int64_t SettingToInt(const common::SettingsValue& value, int64_t nDefault)
507507
return SettingToInt(value).value_or(nDefault);
508508
}
509509

510+
std::optional<int64_t> ArgsManager::GetFixedPointArg(const std::string& arg, int decimals) const
511+
{
512+
const common::SettingsValue value = GetSetting(arg);
513+
return SettingToFixedPoint(value, decimals);
514+
}
515+
516+
std::optional<int64_t> SettingToFixedPoint(const common::SettingsValue& value, int decimals)
517+
{
518+
if (value.isNull()) return std::nullopt;
519+
if (value.isFalse()) return 0;
520+
if (value.isTrue()) return 1;
521+
if (!value.isNum()) value.get_str(); // throws an exception if type is wrong
522+
int64_t v;
523+
if (!ParseFixedPoint(value.getValStr(), decimals, &v)) {
524+
throw std::runtime_error(strprintf("Parse error ('%s')", value.getValStr()));
525+
}
526+
return v;
527+
}
528+
510529
bool ArgsManager::GetBoolArg(const std::string& strArg, bool fDefault) const
511530
{
512531
return GetBoolArg(strArg).value_or(fDefault);

src/common/args.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ std::optional<std::string> SettingToString(const common::SettingsValue&);
9292
int64_t SettingToInt(const common::SettingsValue&, int64_t);
9393
std::optional<int64_t> SettingToInt(const common::SettingsValue&);
9494

95+
std::optional<int64_t> SettingToFixedPoint(const common::SettingsValue&, int decimals);
96+
9597
bool SettingToBool(const common::SettingsValue&, bool);
9698
std::optional<bool> SettingToBool(const common::SettingsValue&);
9799

@@ -305,6 +307,15 @@ class ArgsManager
305307
int64_t GetIntArg(const std::string& strArg, int64_t nDefault) const;
306308
std::optional<int64_t> GetIntArg(const std::string& strArg) const;
307309

310+
/**
311+
* Return fixed-point argument
312+
*
313+
* @param arg Argument to get (e.g. "-foo")
314+
* @param decimals Number of fractional decimal digits to accept
315+
* @return Command-line argument (0 if invalid number) multiplied by 10**decimals
316+
*/
317+
std::optional<int64_t> GetFixedPointArg(const std::string& arg, int decimals) const;
318+
308319
/**
309320
* Return boolean argument or default value
310321
*

src/init.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,7 @@ void SetupServerArgs(ArgsManager& argsman)
680680
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);
681681
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);
682682
argsman.AddArg("-datacarrier", strprintf("Relay and mine data carrier transactions (default: %u)", DEFAULT_ACCEPT_DATACARRIER), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
683+
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);
683684
argsman.AddArg("-datacarrierfullcount", strprintf("Apply datacarriersize limit to all known datacarrier methods (default: %u)", DEFAULT_DATACARRIER_FULLCOUNT), ArgsManager::ALLOW_ANY | (DEFAULT_DATACARRIER_FULLCOUNT ? uint32_t{ArgsManager::DEBUG_ONLY} : 0), OptionsCategory::NODE_RELAY);
684685
argsman.AddArg("-datacarriersize",
685686
strprintf("Maximum size of data in data carrier transactions we relay and mine, in bytes (default: %u)",
@@ -1087,6 +1088,10 @@ bool AppInitParameterInteraction(const ArgsManager& args)
10871088
}
10881089
}
10891090

1091+
if (auto parsed = args.GetFixedPointArg("-datacarriercost", 2)) {
1092+
g_weight_per_data_byte = ((*parsed * WITNESS_SCALE_FACTOR) + 99) / 100;
1093+
}
1094+
10901095
nBytesPerSigOp = args.GetIntArg("-bytespersigop", nBytesPerSigOp);
10911096
nBytesPerSigOpStrict = args.GetIntArg("-bytespersigopstrict", nBytesPerSigOpStrict);
10921097

src/kernel/mempool_entry.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class CTxMemPoolEntry
9696
const int64_t nTime; //!< Local time when entering the mempool
9797
const uint64_t entry_sequence; //!< Sequence number used to determine whether this transaction is too recent for relay
9898
const int64_t sigOpCost; //!< Total sigop cost
99+
const int32_t m_extra_weight; //!< Policy-only additional transaction weight beyond nTxWeight
99100
const size_t nModSize; //!< Cached modified size for priority
100101
const double entryPriority; //!< Priority when entering the mempool
101102
const unsigned int entryHeight; //!< Chain height when entering the mempool
@@ -127,6 +128,7 @@ class CTxMemPoolEntry
127128
double entry_tx_inputs_coin_age,
128129
CAmount in_chain_input_value,
129130
bool spends_coinbase,
131+
int32_t extra_weight,
130132
int64_t sigops_cost, LockPoints lp)
131133
: tx{tx},
132134
nFee{fee},
@@ -135,6 +137,7 @@ class CTxMemPoolEntry
135137
nTime{time},
136138
entry_sequence{entry_sequence},
137139
sigOpCost{sigops_cost},
140+
m_extra_weight{extra_weight},
138141
nModSize{CalculateModifiedSize(*tx, GetTxSize())},
139142
entryPriority{ComputePriority2(entry_tx_inputs_coin_age, nModSize)},
140143
entryHeight{entry_height},
@@ -177,7 +180,7 @@ class CTxMemPoolEntry
177180
const CAmount& GetFee() const { return nFee; }
178181
int32_t GetTxSize() const
179182
{
180-
return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp);
183+
return GetVirtualTransactionSize(nTxWeight + m_extra_weight, sigOpCost, ::nBytesPerSigOp);
181184
}
182185
int32_t GetTxWeight() const { return nTxWeight; }
183186
std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; }

src/node/interfaces.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ class ChainImpl : public Chain
749749
{
750750
if (!m_node.mempool) return {};
751751
LockPoints lp;
752-
CTxMemPoolEntry entry(tx, 0, 0, 0, 0, 0, 0, false, 0, lp);
752+
CTxMemPoolEntry entry(tx, 0, 0, 0, 0, 0, 0, false, /*extra_weight=*/0, 0, lp);
753753
LOCK(m_node.mempool->cs);
754754
return m_node.mempool->CheckPackageLimits({tx}, entry.GetTxSize());
755755
}

src/node/psbt.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <coins.h>
66
#include <consensus/amount.h>
77
#include <consensus/tx_verify.h>
8+
#include <consensus/validation.h>
89
#include <node/psbt.h>
910
#include <policy/policy.h>
1011
#include <policy/settings.h>
@@ -137,7 +138,7 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
137138

138139
if (success) {
139140
CTransaction ctx = CTransaction(mtx);
140-
size_t size(GetVirtualTransactionSize(ctx, GetTransactionSigOpCost(ctx, view, STANDARD_SCRIPT_VERIFY_FLAGS), ::nBytesPerSigOp));
141+
size_t size(GetVirtualTransactionSize(GetTransactionWeight(ctx) + CalculateExtraTxWeight(ctx, view, ::g_weight_per_data_byte), GetTransactionSigOpCost(ctx, view, STANDARD_SCRIPT_VERIFY_FLAGS), ::nBytesPerSigOp));
141142
result.estimated_vsize = size;
142143
// Estimate fee rate
143144
CFeeRate feerate(fee, size);

src/policy/policy.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,3 +435,26 @@ size_t DatacarrierBytes(const CTransaction& tx, const CCoinsViewCache& view)
435435

436436
return ret;
437437
}
438+
439+
int32_t CalculateExtraTxWeight(const CTransaction& tx, const CCoinsViewCache& view, const unsigned int weight_per_data_byte)
440+
{
441+
int32_t mod_weight{0};
442+
443+
// Add in any extra weight for data bytes
444+
if (weight_per_data_byte > 1) {
445+
for (const CTxIn& txin : tx.vin) {
446+
const CTxOut &utxo = view.AccessCoin(txin.prevout).out;
447+
auto[script, consensus_weight_per_byte] = GetScriptForTransactionInput(utxo.scriptPubKey, txin);
448+
if (weight_per_data_byte > consensus_weight_per_byte) {
449+
mod_weight += script.DatacarrierBytes() * (weight_per_data_byte - consensus_weight_per_byte);
450+
}
451+
}
452+
if (weight_per_data_byte > WITNESS_SCALE_FACTOR) {
453+
for (const CTxOut& txout : tx.vout) {
454+
mod_weight += txout.scriptPubKey.DatacarrierBytes() * (weight_per_data_byte - WITNESS_SCALE_FACTOR);
455+
}
456+
}
457+
}
458+
459+
return mod_weight;
460+
}

0 commit comments

Comments
 (0)