Skip to content

Commit

Permalink
[rpc] add vsize_bip141 for non-sigop-adjusted vsize
Browse files Browse the repository at this point in the history
Add a result for users who are expecting BIP141 vsize without sigop
adjustment.
  • Loading branch information
glozow committed Aug 25, 2023
1 parent 6a371bc commit 9cf46b6
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 6 deletions.
7 changes: 7 additions & 0 deletions src/rpc/mempool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ static RPCHelpMan testmempoolaccept()
{RPCResult::Type::BOOL, "allowed", /*optional=*/true, "Whether this tx would be accepted to the mempool and pass client-specified maxfeerate. "
"If not present, the tx was not fully validated due to a failure in another tx in the list."},
{RPCResult::Type::NUM, "vsize", /*optional=*/true, "Maximum of sigop-adjusted size (-bytespersigop) and virtual transaction size as defined in BIP 141."},
{RPCResult::Type::NUM, "vsize_bip141", /*optional=*/true, "Virtual transaction size as defined in BIP 141.\n"
"This is different from actual serialized size for witness transactions as witness data is discounted (only present when 'allowed' is true)."},
{RPCResult::Type::OBJ, "fees", /*optional=*/true, "Transaction fees (only present if 'allowed' is true)",
{
{RPCResult::Type::STR_AMOUNT, "base", "transaction fee in " + CURRENCY_UNIT},
Expand Down Expand Up @@ -223,6 +225,7 @@ static RPCHelpMan testmempoolaccept()
// These can be used to calculate the feerate.
result_inner.pushKV("allowed", true);
result_inner.pushKV("vsize", virtual_size);
result_inner.pushKV("vsize_bip141", GetVirtualTransactionSize(*tx, 0, 0));
UniValue fees(UniValue::VOBJ);
fees.pushKV("base", ValueFromAmount(fee));
fees.pushKV("effective-feerate", ValueFromAmount(tx_result.m_effective_feerate.value().GetFeePerK()));
Expand Down Expand Up @@ -253,6 +256,7 @@ static std::vector<RPCResult> MempoolEntryDescription()
{
return {
RPCResult{RPCResult::Type::NUM, "vsize", "maximum of sigop-adjusted size (-bytespersigop) and virtual transaction size as defined in BIP 141."},
RPCResult{RPCResult::Type::NUM, "vsize_bip141", "virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted."},
RPCResult{RPCResult::Type::NUM, "weight", "transaction weight as defined in BIP 141."},
RPCResult{RPCResult::Type::NUM_TIME, "time", "local time transaction entered pool in seconds since 1 Jan 1970 GMT"},
RPCResult{RPCResult::Type::NUM, "height", "block height when transaction entered pool"},
Expand Down Expand Up @@ -282,6 +286,7 @@ static void entryToJSON(const CTxMemPool& pool, UniValue& info, const CTxMemPool
AssertLockHeld(pool.cs);

info.pushKV("vsize", (int)e.GetTxSize());
info.pushKV("vsize_bip141", GetVirtualTransactionSize(e.GetTx(), 0, 0));
info.pushKV("weight", (int)e.GetTxWeight());
info.pushKV("time", count_seconds(e.GetTime()));
info.pushKV("height", (int)e.GetHeight());
Expand Down Expand Up @@ -841,6 +846,7 @@ static RPCHelpMan submitpackage()
{RPCResult::Type::STR_HEX, "txid", "The transaction hash in hex"},
{RPCResult::Type::STR_HEX, "other-wtxid", /*optional=*/true, "The wtxid of a different transaction with the same txid but different witness found in the mempool. This means the submitted transaction was ignored."},
{RPCResult::Type::NUM, "vsize", "Maximum of sigop-adjusted size (-bytespersigop) and virtual transaction size as defined in BIP 141."},
{RPCResult::Type::NUM, "vsize_bip141", "Virtual transaction size as defined in BIP 141."},
{RPCResult::Type::OBJ, "fees", "Transaction fees", {
{RPCResult::Type::STR_AMOUNT, "base", "transaction fee in " + CURRENCY_UNIT},
{RPCResult::Type::STR_AMOUNT, "effective-feerate", /*optional=*/true, "if the transaction was not already in the mempool, the effective feerate in " + CURRENCY_UNIT + " per KvB. For example, the package feerate and/or feerate with modified fees from prioritisetransaction."},
Expand Down Expand Up @@ -939,6 +945,7 @@ static RPCHelpMan submitpackage()
if (it->second.m_result_type == MempoolAcceptResult::ResultType::VALID ||
it->second.m_result_type == MempoolAcceptResult::ResultType::MEMPOOL_ENTRY) {
result_inner.pushKV("vsize", int64_t{it->second.m_vsize.value()});
result_inner.pushKV("vsize_bip141", GetVirtualTransactionSize(*tx, 0, 0));
UniValue fees(UniValue::VOBJ);
fees.pushKV("base", ValueFromAmount(it->second.m_base_fees.value()));
if (tx_result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
Expand Down
15 changes: 10 additions & 5 deletions test/functional/mempool_accept.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ def run_test(self):
raw_tx_0 = tx.serialize().hex()
txid_0 = tx.rehash()
self.check_mempool_result(
result_expected=[{'txid': txid_0, 'allowed': True, 'vsize': tx.get_vsize(), 'fees': {'base': fee}}],
result_expected=[{'txid': txid_0, 'allowed': True, 'vsize': tx.get_vsize(),
'vsize_bip141': tx.get_vsize(), 'fees': {'base': fee}}],
rawtxs=[raw_tx_0],
)

Expand All @@ -118,7 +119,8 @@ def run_test(self):
tx = tx_from_hex(raw_tx_final)
fee_expected = Decimal('50.0') - output_amount
self.check_mempool_result(
result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(), 'fees': {'base': fee_expected}}],
result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(),
'vsize_bip141': tx.get_vsize(), 'fees': {'base': fee_expected}}],
rawtxs=[tx.serialize().hex()],
maxfeerate=0,
)
Expand All @@ -140,7 +142,8 @@ def run_test(self):
raw_tx_0 = tx.serialize().hex()
txid_0 = tx.rehash()
self.check_mempool_result(
result_expected=[{'txid': txid_0, 'allowed': True, 'vsize': tx.get_vsize(), 'fees': {'base': (2 * fee)}}],
result_expected=[{'txid': txid_0, 'allowed': True, 'vsize': tx.get_vsize(),
'vsize_bip141': tx.get_vsize(), 'fees': {'base': (2 * fee)}}],
rawtxs=[raw_tx_0],
)

Expand Down Expand Up @@ -197,7 +200,8 @@ def run_test(self):
raw_tx_reference = tx.serialize().hex()
# Reference tx should be valid on itself
self.check_mempool_result(
result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(), 'fees': { 'base': Decimal('0.1') - Decimal('0.05')}}],
result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(),
'vsize_bip141': tx.get_vsize(), 'fees': { 'base': Decimal('0.1') - Decimal('0.05')}}],
rawtxs=[tx.serialize().hex()],
maxfeerate=0,
)
Expand Down Expand Up @@ -367,7 +371,8 @@ def run_test(self):
tx.vout[0] = CTxOut(COIN - 1000, DUMMY_MIN_OP_RETURN_SCRIPT)
assert_equal(len(tx.serialize_without_witness()), MIN_STANDARD_TX_NONWITNESS_SIZE)
self.check_mempool_result(
result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(), 'fees': { 'base': Decimal('0.00001000')}}],
result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(),
'vsize_bip141': tx.get_vsize(), 'fees': { 'base': Decimal('0.00001000')}}],
rawtxs=[tx.serialize().hex()],
maxfeerate=0,
)
Expand Down
4 changes: 3 additions & 1 deletion test/functional/mempool_sigoplimit.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ def test_sigops_limit(self, bytes_per_sigop, num_sigops):
tx.vout[0].scriptPubKey = CScript([OP_RETURN, b'X'*(256+vsize_to_pad+1)])
res = self.nodes[0].testmempoolaccept([tx.serialize().hex()])[0]
assert_equal(res['allowed'], True)
assert_equal(res['vsize'], sigop_equivalent_vsize+1)
assert_equal(res['vsize'], sigop_equivalent_vsize + 1)
assert_equal(res['vsize_bip141'], tx.get_vsize())

# decrease the tx's vsize to be right below the sigop-limit equivalent size
# => tx's vsize in mempool should stick at the sigop-limit equivalent
Expand All @@ -107,6 +108,7 @@ def test_sigops_limit(self, bytes_per_sigop, num_sigops):
res = self.nodes[0].testmempoolaccept([tx.serialize().hex()])[0]
assert_equal(res['allowed'], True)
assert_equal(res['vsize'], sigop_equivalent_vsize)
assert_equal(res['vsize_bip141'], tx.get_vsize())

# check that the ancestor and descendant size calculations in the mempool
# also use the same max(sigop_equivalent_vsize, serialized_vsize) logic
Expand Down
2 changes: 2 additions & 0 deletions test/functional/p2p_segwit.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,7 @@ def test_standardness_v0(self):
'wtxid': tx3.getwtxid(),
'allowed': True,
'vsize': tx3.get_vsize(),
'vsize_bip141': tx3.get_vsize(),
'fees': {
'base': Decimal('0.00001000'),
},
Expand All @@ -650,6 +651,7 @@ def test_standardness_v0(self):
'wtxid': tx3.getwtxid(),
'allowed': True,
'vsize': tx3.get_vsize(),
'vsize_bip141': tx3.get_vsize(),
'fees': {
'base': Decimal('0.00011000'),
},
Expand Down
1 change: 1 addition & 0 deletions test/functional/rpc_packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ def test_submit_child_with_parents(self, num_parents, partial_submit):
tx_result = submitpackage_result["tx-results"][wtxid]
assert_equal(tx_result["txid"], tx.rehash())
assert_equal(tx_result["vsize"], tx.get_vsize())
assert_equal(tx_result["vsize_bip141"], tx.get_vsize())
assert_equal(tx_result["fees"]["base"], DEFAULT_FEE)
if wtxid not in presubmitted_wtxids:
assert_fee_amount(DEFAULT_FEE, tx.get_vsize(), tx_result["fees"]["effective-feerate"])
Expand Down

0 comments on commit 9cf46b6

Please sign in to comment.