Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc-minimaldata.py
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
class MinimaldataTest(BitcoinTestFramework): | class MinimaldataTest(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.num_nodes = 1 | self.num_nodes = 1 | ||||
self.block_heights = {} | self.block_heights = {} | ||||
self.extra_args = [['-acceptnonstdtxn=1']] | self.extra_args = [['-acceptnonstdtxn=1']] | ||||
def bootstrap_p2p(self, *, num_connections=1): | def reconnect_p2p(self): | ||||
"""Add a P2P connection to the node. | |||||
Helper to connect and wait for version handshake.""" | |||||
for _ in range(num_connections): | |||||
self.nodes[0].add_p2p_connection(P2PDataStore()) | |||||
def reconnect_p2p(self, **kwargs): | |||||
"""Tear down and bootstrap the P2P connection to the node. | """Tear down and bootstrap the P2P connection to the node. | ||||
The node gets disconnected several times in this test. This helper | The node gets disconnected several times in this test. This helper | ||||
method reconnects the p2p and restarts the network thread.""" | method reconnects the p2p and restarts the network thread.""" | ||||
self.nodes[0].disconnect_p2ps() | self.nodes[0].disconnect_p2ps() | ||||
self.bootstrap_p2p(**kwargs) | self.peer = self.nodes[0].add_p2p_connection(P2PDataStore()) | ||||
Fabien: `peer` is not an attribute of `BitcoinTestFramework` but an attribute of a node, so `self.peer`… | |||||
def getbestblock(self, node): | def getbestblock(self, node): | ||||
"""Get the best block. Register its height so we can use build_block.""" | """Get the best block. Register its height so we can use build_block.""" | ||||
block_height = node.getblockcount() | block_height = node.getblockcount() | ||||
blockhash = node.getblockhash(block_height) | blockhash = node.getblockhash(block_height) | ||||
block = FromHex(CBlock(), node.getblock(blockhash, 0)) | block = FromHex(CBlock(), node.getblock(blockhash, 0)) | ||||
block.calc_sha256() | block.calc_sha256() | ||||
self.block_heights[block.sha256] = block_height | self.block_heights[block.sha256] = block_height | ||||
Show All 15 Lines | def build_block(self, parent, transactions=(), nTime=None): | ||||
block.solve() | block.solve() | ||||
self.block_heights[block.sha256] = block_height | self.block_heights[block.sha256] = block_height | ||||
return block | return block | ||||
def check_for_ban_on_rejected_tx(self, tx, reject_reason=None): | def check_for_ban_on_rejected_tx(self, tx, reject_reason=None): | ||||
"""Check we are disconnected when sending a txn that the node rejects. | """Check we are disconnected when sending a txn that the node rejects. | ||||
(Can't actually get banned, since bitcoind won't ban local peers.)""" | (Can't actually get banned, since bitcoind won't ban local peers.)""" | ||||
self.nodes[0].p2p.send_txs_and_test( | self.peer.send_txs_and_test( | ||||
[tx], self.nodes[0], success=False, expect_disconnect=True, reject_reason=reject_reason) | [tx], self.nodes[0], success=False, expect_disconnect=True, reject_reason=reject_reason) | ||||
self.reconnect_p2p() | self.reconnect_p2p() | ||||
def check_for_ban_on_rejected_block(self, block, reject_reason=None): | def check_for_ban_on_rejected_block(self, block, reject_reason=None): | ||||
"""Check we are disconnected when sending a block that the node rejects. | """Check we are disconnected when sending a block that the node rejects. | ||||
(Can't actually get banned, since bitcoind won't ban local peers.)""" | (Can't actually get banned, since bitcoind won't ban local peers.)""" | ||||
self.nodes[0].p2p.send_blocks_and_test( | self.peer.send_blocks_and_test( | ||||
[block], self.nodes[0], success=False, reject_reason=reject_reason, expect_disconnect=True) | [block], self.nodes[0], success=False, reject_reason=reject_reason, expect_disconnect=True) | ||||
self.reconnect_p2p() | self.reconnect_p2p() | ||||
def run_test(self): | def run_test(self): | ||||
node, = self.nodes | node, = self.nodes | ||||
self.bootstrap_p2p() | self.peer = self.nodes[0].add_p2p_connection(P2PDataStore()) | ||||
tip = self.getbestblock(node) | tip = self.getbestblock(node) | ||||
self.log.info("Create some blocks with OP_1 coinbase for spending.") | self.log.info("Create some blocks with OP_1 coinbase for spending.") | ||||
blocks = [] | blocks = [] | ||||
for _ in range(10): | for _ in range(10): | ||||
tip = self.build_block(tip) | tip = self.build_block(tip) | ||||
blocks.append(tip) | blocks.append(tip) | ||||
node.p2p.send_blocks_and_test(blocks, node, success=True) | self.peer.send_blocks_and_test(blocks, node, success=True) | ||||
spendable_outputs = [block.vtx[0] for block in blocks] | spendable_outputs = [block.vtx[0] for block in blocks] | ||||
self.log.info("Mature the blocks and get out of IBD.") | self.log.info("Mature the blocks and get out of IBD.") | ||||
node.generatetoaddress(100, node.get_deterministic_priv_key().address) | node.generatetoaddress(100, node.get_deterministic_priv_key().address) | ||||
tip = self.getbestblock(node) | tip = self.getbestblock(node) | ||||
self.log.info("Setting up spends to test and mining the fundings.") | self.log.info("Setting up spends to test and mining the fundings.") | ||||
Show All 26 Lines | def run_test(self): | ||||
txspend.rehash() | txspend.rehash() | ||||
return txspend | return txspend | ||||
# Non minimal tx are invalid. | # Non minimal tx are invalid. | ||||
nonminimaltx = create_fund_and_spend_tx() | nonminimaltx = create_fund_and_spend_tx() | ||||
tip = self.build_block(tip, fundings) | tip = self.build_block(tip, fundings) | ||||
node.p2p.send_blocks_and_test([tip], node) | self.peer.send_blocks_and_test([tip], node) | ||||
self.log.info("Trying to mine a minimaldata violation.") | self.log.info("Trying to mine a minimaldata violation.") | ||||
self.check_for_ban_on_rejected_block( | self.check_for_ban_on_rejected_block( | ||||
self.build_block(tip, [nonminimaltx]), BADINPUTS_ERROR) | self.build_block(tip, [nonminimaltx]), BADINPUTS_ERROR) | ||||
self.log.info( | self.log.info( | ||||
"If we try to submit it by mempool or RPC we are banned") | "If we try to submit it by mempool or RPC we are banned") | ||||
assert_raises_rpc_error(-26, MINIMALPUSH_ERROR, | assert_raises_rpc_error(-26, MINIMALPUSH_ERROR, | ||||
node.sendrawtransaction, ToHex(nonminimaltx)) | node.sendrawtransaction, ToHex(nonminimaltx)) | ||||
self.check_for_ban_on_rejected_tx( | self.check_for_ban_on_rejected_tx( | ||||
nonminimaltx, MINIMALPUSH_ERROR) | nonminimaltx, MINIMALPUSH_ERROR) | ||||
self.log.info("Mine a normal block") | self.log.info("Mine a normal block") | ||||
tip = self.build_block(tip) | tip = self.build_block(tip) | ||||
node.p2p.send_blocks_and_test([tip], node) | self.peer.send_blocks_and_test([tip], node) | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
MinimaldataTest().main() | MinimaldataTest().main() |
peer is not an attribute of BitcoinTestFramework but an attribute of a node, so self.peer is not appropriated here and this is a case where you should use self.nodes[0].p2ps[0] imo