forked from bitcoin/bitcoin
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmempool_accept_wtxid.py
More file actions
executable file
·90 lines (73 loc) · 3.64 KB
/
mempool_accept_wtxid.py
File metadata and controls
executable file
·90 lines (73 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env python3
# Copyright (c) 2021-present The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""
Test mempool acceptance in case of an already known transaction
with identical non-witness data but different witness.
"""
from test_framework.p2p import P2PTxInvStore
from test_framework.script_util import build_malleated_tx_package
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_not_equal,
assert_equal,
)
from test_framework.wallet import (
MiniWallet,
)
class MempoolWtxidTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
def run_test(self):
node = self.nodes[0]
mini_wallet = MiniWallet(node)
self.log.info('Start with pre-generated blocks')
assert_equal(node.getmempoolinfo()['size'], 0)
self.log.info("Submit parent with multiple script branches to mempool")
parent = mini_wallet.create_self_transfer()["tx"]
parent_amount = parent.vout[0].nValue - 10000
child_amount = parent_amount - 10000
parent, child_one, child_two = build_malleated_tx_package(
parent=parent,
rebalance_parent_output_amount=parent_amount,
child_amount=child_amount
)
mini_wallet.sendrawtransaction(from_node=node, tx_hex=parent.serialize().hex())
self.generate(node, 1)
peer_wtxid_relay = node.add_p2p_connection(P2PTxInvStore())
assert_equal(child_one.txid_hex, child_two.txid_hex)
assert_not_equal(child_one.wtxid_hex, child_two.wtxid_hex)
self.log.info("Submit child_one to the mempool")
txid_submitted = node.sendrawtransaction(child_one.serialize().hex())
assert_equal(node.getmempoolentry(txid_submitted)['wtxid'], child_one.wtxid_hex)
peer_wtxid_relay.wait_for_broadcast([child_one.wtxid_hex])
assert_equal(node.getmempoolinfo()["unbroadcastcount"], 0)
# testmempoolaccept reports the "already in mempool" error
assert_equal(node.testmempoolaccept([child_one.serialize().hex()]), [{
"txid": child_one.txid_hex,
"wtxid": child_one.wtxid_hex,
"allowed": False,
"reject-reason": "txn-already-in-mempool",
"reject-details": "txn-already-in-mempool"
}])
assert_equal(node.testmempoolaccept([child_two.serialize().hex()])[0], {
"txid": child_two.txid_hex,
"wtxid": child_two.wtxid_hex,
"allowed": False,
"reject-reason": "txn-same-nonwitness-data-in-mempool",
"reject-details": "txn-same-nonwitness-data-in-mempool"
})
# sendrawtransaction will not throw but quits early when the exact same transaction is already in mempool
node.sendrawtransaction(child_one.serialize().hex())
self.log.info("Connect another peer that hasn't seen child_one before")
peer_wtxid_relay_2 = node.add_p2p_connection(P2PTxInvStore())
self.log.info("Submit child_two to the mempool")
# sendrawtransaction will not throw but quits early when a transaction with the same non-witness data is already in mempool
node.sendrawtransaction(child_two.serialize().hex())
# The node should rebroadcast the transaction using the wtxid of the correct transaction
# (child_one, which is in its mempool).
peer_wtxid_relay_2.wait_for_broadcast([child_one.wtxid_hex])
assert_equal(node.getmempoolinfo()["unbroadcastcount"], 0)
if __name__ == '__main__':
MempoolWtxidTest(__file__).main()