Changeset View
Changeset View
Standalone View
Standalone View
test/functional/bipdersig-p2p.py
Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
class BIP66Test(BitcoinTestFramework): | class BIP66Test(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.num_nodes = 1 | self.num_nodes = 1 | ||||
self.extra_args = [ | self.extra_args = [ | ||||
['-promiscuousmempoolflags=1', '-whitelist=127.0.0.1']] | ['-promiscuousmempoolflags=1', '-whitelist=127.0.0.1']] | ||||
self.setup_clean_chain = True | self.setup_clean_chain = True | ||||
def run_test(self): | def run_test(self): | ||||
node0 = NodeConnCB() | self.nodes[0].add_p2p_connection(NodeConnCB()) | ||||
connections = [] | |||||
connections.append( | # Start up network handling in another thread | ||||
NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], node0)) | NetworkThread().start() | ||||
node0.add_connection(connections[0]) | |||||
NetworkThread().start() # Start up network handling in another thread | |||||
# wait_for_verack ensures that the P2P connection is fully up. | # wait_for_verack ensures that the P2P connection is fully up. | ||||
node0.wait_for_verack() | self.nodes[0].p2p.wait_for_verack() | ||||
self.log.info("Mining %d blocks", DERSIG_HEIGHT - 1) | self.log.info("Mining %d blocks", DERSIG_HEIGHT - 1) | ||||
self.coinbase_blocks = self.nodes[0].generate(DERSIG_HEIGHT - 1) | self.coinbase_blocks = self.nodes[0].generate(DERSIG_HEIGHT - 1) | ||||
self.nodeaddress = self.nodes[0].getnewaddress() | self.nodeaddress = self.nodes[0].getnewaddress() | ||||
self.log.info("Test that blocks must now be at least version 3") | self.log.info("Test that blocks must now be at least version 3") | ||||
tip = self.nodes[0].getbestblockhash() | tip = self.nodes[0].getbestblockhash() | ||||
block_time = self.nodes[0].getblockheader(tip)['mediantime'] + 1 | block_time = self.nodes[0].getblockheader(tip)['mediantime'] + 1 | ||||
block = create_block( | block = create_block( | ||||
int(tip, 16), create_coinbase(DERSIG_HEIGHT), block_time) | int(tip, 16), create_coinbase(DERSIG_HEIGHT), block_time) | ||||
block.nVersion = 2 | block.nVersion = 2 | ||||
block.rehash() | block.rehash() | ||||
block.solve() | block.solve() | ||||
node0.send_and_ping(msg_block(block)) | self.nodes[0].p2p.send_and_ping(msg_block(block)) | ||||
assert_equal(self.nodes[0].getbestblockhash(), tip) | assert_equal(self.nodes[0].getbestblockhash(), tip) | ||||
wait_until(lambda: "reject" in node0.last_message.keys(), | wait_until(lambda: "reject" in self.nodes[0].p2p.last_message.keys(), | ||||
lock=mininode_lock) | lock=mininode_lock) | ||||
with mininode_lock: | with mininode_lock: | ||||
assert_equal(node0.last_message["reject"].code, REJECT_OBSOLETE) | |||||
assert_equal( | assert_equal( | ||||
node0.last_message["reject"].reason, b'bad-version(0x00000002)') | self.nodes[0].p2p.last_message["reject"].code, REJECT_OBSOLETE) | ||||
assert_equal(node0.last_message["reject"].data, block.sha256) | assert_equal( | ||||
del node0.last_message["reject"] | self.nodes[0].p2p.last_message["reject"].reason, b'bad-version(0x00000002)') | ||||
assert_equal( | |||||
self.nodes[0].p2p.last_message["reject"].data, block.sha256) | |||||
del self.nodes[0].p2p.last_message["reject"] | |||||
self.log.info( | self.log.info( | ||||
"Test that transactions with non-DER signatures cannot appear in a block") | "Test that transactions with non-DER signatures cannot appear in a block") | ||||
block.nVersion = 3 | block.nVersion = 3 | ||||
spendtx = create_transaction(self.nodes[0], self.coinbase_blocks[1], | spendtx = create_transaction(self.nodes[0], self.coinbase_blocks[1], | ||||
self.nodeaddress, 1.0) | self.nodeaddress, 1.0) | ||||
unDERify(spendtx) | unDERify(spendtx) | ||||
spendtx.rehash() | spendtx.rehash() | ||||
# Now we verify that a block with this transaction is invalid. | # Now we verify that a block with this transaction is invalid. | ||||
block.vtx.append(spendtx) | block.vtx.append(spendtx) | ||||
block.hashMerkleRoot = block.calc_merkle_root() | block.hashMerkleRoot = block.calc_merkle_root() | ||||
block.rehash() | block.rehash() | ||||
block.solve() | block.solve() | ||||
node0.send_and_ping(msg_block(block)) | self.nodes[0].p2p.send_and_ping(msg_block(block)) | ||||
assert_equal(self.nodes[0].getbestblockhash(), tip) | assert_equal(self.nodes[0].getbestblockhash(), tip) | ||||
wait_until(lambda: "reject" in node0.last_message.keys(), | wait_until(lambda: "reject" in self.nodes[0].p2p.last_message.keys(), | ||||
lock=mininode_lock) | lock=mininode_lock) | ||||
with mininode_lock: | with mininode_lock: | ||||
# We can receive different reject messages depending on whether | # We can receive different reject messages depending on whether | ||||
# bitcoind is running with multiple script check threads. If script | # bitcoind is running with multiple script check threads. If script | ||||
# check threads are not in use, then transaction script validation | # check threads are not in use, then transaction script validation | ||||
# happens sequentially, and bitcoind produces more specific reject | # happens sequentially, and bitcoind produces more specific reject | ||||
# reasons. | # reasons. | ||||
assert node0.last_message["reject"].code in [ | assert self.nodes[0].p2p.last_message["reject"].code in [ | ||||
REJECT_INVALID, REJECT_NONSTANDARD] | REJECT_INVALID, REJECT_NONSTANDARD] | ||||
assert_equal(node0.last_message["reject"].data, block.sha256) | assert_equal( | ||||
if node0.last_message["reject"].code == REJECT_INVALID: | self.nodes[0].p2p.last_message["reject"].data, block.sha256) | ||||
if self.nodes[0].p2p.last_message["reject"].code == REJECT_INVALID: | |||||
# Generic rejection when a block is invalid | # Generic rejection when a block is invalid | ||||
assert_equal( | assert_equal( | ||||
node0.last_message["reject"].reason, b'blk-bad-inputs') | self.nodes[0].p2p.last_message["reject"].reason, b'blk-bad-inputs') | ||||
else: | else: | ||||
assert b'Non-canonical DER signature' in node0.last_message["reject"].reason | assert b'Non-canonical DER signature' in self.nodes[0].p2p.last_message["reject"].reason | ||||
self.log.info( | self.log.info( | ||||
"Test that a version 3 block with a DERSIG-compliant transaction is accepted") | "Test that a version 3 block with a DERSIG-compliant transaction is accepted") | ||||
block.vtx[1] = create_transaction(self.nodes[0], | block.vtx[1] = create_transaction(self.nodes[0], | ||||
self.coinbase_blocks[1], self.nodeaddress, 1.0) | self.coinbase_blocks[1], self.nodeaddress, 1.0) | ||||
block.hashMerkleRoot = block.calc_merkle_root() | block.hashMerkleRoot = block.calc_merkle_root() | ||||
block.rehash() | block.rehash() | ||||
block.solve() | block.solve() | ||||
node0.send_and_ping(msg_block(block)) | self.nodes[0].p2p.send_and_ping(msg_block(block)) | ||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) | assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
BIP66Test().main() | BIP66Test().main() |