Skip to content

Commit 9cf46b6

Browse files
committed
[rpc] add vsize_bip141 for non-sigop-adjusted vsize
Add a result for users who are expecting BIP141 vsize without sigop adjustment.
1 parent 6a371bc commit 9cf46b6

File tree

5 files changed

+23
-6
lines changed

5 files changed

+23
-6
lines changed

src/rpc/mempool.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ static RPCHelpMan testmempoolaccept()
131131
{RPCResult::Type::BOOL, "allowed", /*optional=*/true, "Whether this tx would be accepted to the mempool and pass client-specified maxfeerate. "
132132
"If not present, the tx was not fully validated due to a failure in another tx in the list."},
133133
{RPCResult::Type::NUM, "vsize", /*optional=*/true, "Maximum of sigop-adjusted size (-bytespersigop) and virtual transaction size as defined in BIP 141."},
134+
{RPCResult::Type::NUM, "vsize_bip141", /*optional=*/true, "Virtual transaction size as defined in BIP 141.\n"
135+
"This is different from actual serialized size for witness transactions as witness data is discounted (only present when 'allowed' is true)."},
134136
{RPCResult::Type::OBJ, "fees", /*optional=*/true, "Transaction fees (only present if 'allowed' is true)",
135137
{
136138
{RPCResult::Type::STR_AMOUNT, "base", "transaction fee in " + CURRENCY_UNIT},
@@ -223,6 +225,7 @@ static RPCHelpMan testmempoolaccept()
223225
// These can be used to calculate the feerate.
224226
result_inner.pushKV("allowed", true);
225227
result_inner.pushKV("vsize", virtual_size);
228+
result_inner.pushKV("vsize_bip141", GetVirtualTransactionSize(*tx, 0, 0));
226229
UniValue fees(UniValue::VOBJ);
227230
fees.pushKV("base", ValueFromAmount(fee));
228231
fees.pushKV("effective-feerate", ValueFromAmount(tx_result.m_effective_feerate.value().GetFeePerK()));
@@ -253,6 +256,7 @@ static std::vector<RPCResult> MempoolEntryDescription()
253256
{
254257
return {
255258
RPCResult{RPCResult::Type::NUM, "vsize", "maximum of sigop-adjusted size (-bytespersigop) and virtual transaction size as defined in BIP 141."},
259+
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."},
256260
RPCResult{RPCResult::Type::NUM, "weight", "transaction weight as defined in BIP 141."},
257261
RPCResult{RPCResult::Type::NUM_TIME, "time", "local time transaction entered pool in seconds since 1 Jan 1970 GMT"},
258262
RPCResult{RPCResult::Type::NUM, "height", "block height when transaction entered pool"},
@@ -282,6 +286,7 @@ static void entryToJSON(const CTxMemPool& pool, UniValue& info, const CTxMemPool
282286
AssertLockHeld(pool.cs);
283287

284288
info.pushKV("vsize", (int)e.GetTxSize());
289+
info.pushKV("vsize_bip141", GetVirtualTransactionSize(e.GetTx(), 0, 0));
285290
info.pushKV("weight", (int)e.GetTxWeight());
286291
info.pushKV("time", count_seconds(e.GetTime()));
287292
info.pushKV("height", (int)e.GetHeight());
@@ -841,6 +846,7 @@ static RPCHelpMan submitpackage()
841846
{RPCResult::Type::STR_HEX, "txid", "The transaction hash in hex"},
842847
{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."},
843848
{RPCResult::Type::NUM, "vsize", "Maximum of sigop-adjusted size (-bytespersigop) and virtual transaction size as defined in BIP 141."},
849+
{RPCResult::Type::NUM, "vsize_bip141", "Virtual transaction size as defined in BIP 141."},
844850
{RPCResult::Type::OBJ, "fees", "Transaction fees", {
845851
{RPCResult::Type::STR_AMOUNT, "base", "transaction fee in " + CURRENCY_UNIT},
846852
{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."},
@@ -939,6 +945,7 @@ static RPCHelpMan submitpackage()
939945
if (it->second.m_result_type == MempoolAcceptResult::ResultType::VALID ||
940946
it->second.m_result_type == MempoolAcceptResult::ResultType::MEMPOOL_ENTRY) {
941947
result_inner.pushKV("vsize", int64_t{it->second.m_vsize.value()});
948+
result_inner.pushKV("vsize_bip141", GetVirtualTransactionSize(*tx, 0, 0));
942949
UniValue fees(UniValue::VOBJ);
943950
fees.pushKV("base", ValueFromAmount(it->second.m_base_fees.value()));
944951
if (tx_result.m_result_type == MempoolAcceptResult::ResultType::VALID) {

test/functional/mempool_accept.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ def run_test(self):
103103
raw_tx_0 = tx.serialize().hex()
104104
txid_0 = tx.rehash()
105105
self.check_mempool_result(
106-
result_expected=[{'txid': txid_0, 'allowed': True, 'vsize': tx.get_vsize(), 'fees': {'base': fee}}],
106+
result_expected=[{'txid': txid_0, 'allowed': True, 'vsize': tx.get_vsize(),
107+
'vsize_bip141': tx.get_vsize(), 'fees': {'base': fee}}],
107108
rawtxs=[raw_tx_0],
108109
)
109110

@@ -118,7 +119,8 @@ def run_test(self):
118119
tx = tx_from_hex(raw_tx_final)
119120
fee_expected = Decimal('50.0') - output_amount
120121
self.check_mempool_result(
121-
result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(), 'fees': {'base': fee_expected}}],
122+
result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(),
123+
'vsize_bip141': tx.get_vsize(), 'fees': {'base': fee_expected}}],
122124
rawtxs=[tx.serialize().hex()],
123125
maxfeerate=0,
124126
)
@@ -140,7 +142,8 @@ def run_test(self):
140142
raw_tx_0 = tx.serialize().hex()
141143
txid_0 = tx.rehash()
142144
self.check_mempool_result(
143-
result_expected=[{'txid': txid_0, 'allowed': True, 'vsize': tx.get_vsize(), 'fees': {'base': (2 * fee)}}],
145+
result_expected=[{'txid': txid_0, 'allowed': True, 'vsize': tx.get_vsize(),
146+
'vsize_bip141': tx.get_vsize(), 'fees': {'base': (2 * fee)}}],
144147
rawtxs=[raw_tx_0],
145148
)
146149

@@ -197,7 +200,8 @@ def run_test(self):
197200
raw_tx_reference = tx.serialize().hex()
198201
# Reference tx should be valid on itself
199202
self.check_mempool_result(
200-
result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(), 'fees': { 'base': Decimal('0.1') - Decimal('0.05')}}],
203+
result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(),
204+
'vsize_bip141': tx.get_vsize(), 'fees': { 'base': Decimal('0.1') - Decimal('0.05')}}],
201205
rawtxs=[tx.serialize().hex()],
202206
maxfeerate=0,
203207
)
@@ -367,7 +371,8 @@ def run_test(self):
367371
tx.vout[0] = CTxOut(COIN - 1000, DUMMY_MIN_OP_RETURN_SCRIPT)
368372
assert_equal(len(tx.serialize_without_witness()), MIN_STANDARD_TX_NONWITNESS_SIZE)
369373
self.check_mempool_result(
370-
result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(), 'fees': { 'base': Decimal('0.00001000')}}],
374+
result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(),
375+
'vsize_bip141': tx.get_vsize(), 'fees': { 'base': Decimal('0.00001000')}}],
371376
rawtxs=[tx.serialize().hex()],
372377
maxfeerate=0,
373378
)

test/functional/mempool_sigoplimit.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ def test_sigops_limit(self, bytes_per_sigop, num_sigops):
9797
tx.vout[0].scriptPubKey = CScript([OP_RETURN, b'X'*(256+vsize_to_pad+1)])
9898
res = self.nodes[0].testmempoolaccept([tx.serialize().hex()])[0]
9999
assert_equal(res['allowed'], True)
100-
assert_equal(res['vsize'], sigop_equivalent_vsize+1)
100+
assert_equal(res['vsize'], sigop_equivalent_vsize + 1)
101+
assert_equal(res['vsize_bip141'], tx.get_vsize())
101102

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

111113
# check that the ancestor and descendant size calculations in the mempool
112114
# also use the same max(sigop_equivalent_vsize, serialized_vsize) logic

test/functional/p2p_segwit.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,7 @@ def test_standardness_v0(self):
631631
'wtxid': tx3.getwtxid(),
632632
'allowed': True,
633633
'vsize': tx3.get_vsize(),
634+
'vsize_bip141': tx3.get_vsize(),
634635
'fees': {
635636
'base': Decimal('0.00001000'),
636637
},
@@ -650,6 +651,7 @@ def test_standardness_v0(self):
650651
'wtxid': tx3.getwtxid(),
651652
'allowed': True,
652653
'vsize': tx3.get_vsize(),
654+
'vsize_bip141': tx3.get_vsize(),
653655
'fees': {
654656
'base': Decimal('0.00011000'),
655657
},

test/functional/rpc_packages.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ def test_submit_child_with_parents(self, num_parents, partial_submit):
312312
tx_result = submitpackage_result["tx-results"][wtxid]
313313
assert_equal(tx_result["txid"], tx.rehash())
314314
assert_equal(tx_result["vsize"], tx.get_vsize())
315+
assert_equal(tx_result["vsize_bip141"], tx.get_vsize())
315316
assert_equal(tx_result["fees"]["base"], DEFAULT_FEE)
316317
if wtxid not in presubmitted_wtxids:
317318
assert_fee_amount(DEFAULT_FEE, tx.get_vsize(), tx_result["fees"]["effective-feerate"])

0 commit comments

Comments
 (0)