Changeset View
Changeset View
Standalone View
Standalone View
test/functional/feature_assumevalid.py
Show First 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | def send_blocks_until_disconnected(self, p2p_conn): | ||||
assert not p2p_conn.is_connected | assert not p2p_conn.is_connected | ||||
break | break | ||||
def run_test(self): | def run_test(self): | ||||
p2p0 = self.nodes[0].add_p2p_connection(BaseNode()) | p2p0 = self.nodes[0].add_p2p_connection(BaseNode()) | ||||
# Build the blockchain | # Build the blockchain | ||||
self.tip = int(self.nodes[0].getbestblockhash(), 16) | self.tip = int(self.nodes[0].getbestblockhash(), 16) | ||||
self.block_time = self.nodes[0].getblock( | self.block_time = ( | ||||
self.nodes[0].getbestblockhash())['time'] + 1 | self.nodes[0].getblock(self.nodes[0].getbestblockhash())["time"] + 1 | ||||
) | |||||
self.blocks = [] | self.blocks = [] | ||||
# Get a pubkey for the coinbase TXO | # Get a pubkey for the coinbase TXO | ||||
coinbase_key = ECKey() | coinbase_key = ECKey() | ||||
coinbase_key.generate() | coinbase_key.generate() | ||||
coinbase_pubkey = coinbase_key.get_pubkey().get_bytes() | coinbase_pubkey = coinbase_key.get_pubkey().get_bytes() | ||||
# Create the first block with a coinbase output to our key | # Create the first block with a coinbase output to our key | ||||
height = 1 | height = 1 | ||||
block = create_block(self.tip, create_coinbase( | block = create_block( | ||||
height, coinbase_pubkey), self.block_time) | self.tip, create_coinbase(height, coinbase_pubkey), self.block_time | ||||
) | |||||
self.blocks.append(block) | self.blocks.append(block) | ||||
self.block_time += 1 | self.block_time += 1 | ||||
block.solve() | block.solve() | ||||
# Save the coinbase for later | # Save the coinbase for later | ||||
self.block1 = block | self.block1 = block | ||||
self.tip = block.sha256 | self.tip = block.sha256 | ||||
height += 1 | height += 1 | ||||
# Bury the block 100 deep so the coinbase output is spendable | # Bury the block 100 deep so the coinbase output is spendable | ||||
for _ in range(100): | for _ in range(100): | ||||
block = create_block( | block = create_block(self.tip, create_coinbase(height), self.block_time) | ||||
self.tip, create_coinbase(height), self.block_time) | |||||
block.solve() | block.solve() | ||||
self.blocks.append(block) | self.blocks.append(block) | ||||
self.tip = block.sha256 | self.tip = block.sha256 | ||||
self.block_time += 1 | self.block_time += 1 | ||||
height += 1 | height += 1 | ||||
# Create a transaction spending the coinbase output with an invalid | # Create a transaction spending the coinbase output with an invalid | ||||
# (null) signature | # (null) signature | ||||
tx = CTransaction() | tx = CTransaction() | ||||
tx.vin.append( | tx.vin.append(CTxIn(COutPoint(self.block1.vtx[0].sha256, 0), scriptSig=b"")) | ||||
CTxIn(COutPoint(self.block1.vtx[0].sha256, 0), scriptSig=b"")) | |||||
tx.vout.append(CTxOut(49 * 100000000, CScript([OP_TRUE]))) | tx.vout.append(CTxOut(49 * 100000000, CScript([OP_TRUE]))) | ||||
pad_tx(tx) | pad_tx(tx) | ||||
tx.calc_sha256() | tx.calc_sha256() | ||||
block102 = create_block( | block102 = create_block(self.tip, create_coinbase(height), self.block_time) | ||||
self.tip, create_coinbase(height), self.block_time) | |||||
self.block_time += 1 | self.block_time += 1 | ||||
block102.vtx.extend([tx]) | block102.vtx.extend([tx]) | ||||
block102.hashMerkleRoot = block102.calc_merkle_root() | block102.hashMerkleRoot = block102.calc_merkle_root() | ||||
block102.rehash() | block102.rehash() | ||||
block102.solve() | block102.solve() | ||||
self.blocks.append(block102) | self.blocks.append(block102) | ||||
self.tip = block102.sha256 | self.tip = block102.sha256 | ||||
self.block_time += 1 | self.block_time += 1 | ||||
height += 1 | height += 1 | ||||
# Bury the assumed valid block 2100 deep | # Bury the assumed valid block 2100 deep | ||||
for _ in range(2100): | for _ in range(2100): | ||||
block = create_block( | block = create_block(self.tip, create_coinbase(height), self.block_time) | ||||
self.tip, create_coinbase(height), self.block_time) | |||||
block.nVersion = 4 | block.nVersion = 4 | ||||
block.solve() | block.solve() | ||||
self.blocks.append(block) | self.blocks.append(block) | ||||
self.tip = block.sha256 | self.tip = block.sha256 | ||||
self.block_time += 1 | self.block_time += 1 | ||||
height += 1 | height += 1 | ||||
self.nodes[0].disconnect_p2ps() | self.nodes[0].disconnect_p2ps() | ||||
Show All 20 Lines | def run_test(self): | ||||
assert_equal(self.nodes[0].getblockcount(), 101) | assert_equal(self.nodes[0].getblockcount(), 101) | ||||
# Send all blocks to node1. All blocks will be accepted. | # Send all blocks to node1. All blocks will be accepted. | ||||
for i in range(2202): | for i in range(2202): | ||||
p2p1.send_message(msg_block(self.blocks[i])) | p2p1.send_message(msg_block(self.blocks[i])) | ||||
# Syncing 2200 blocks can take a while on slow systems. Give it plenty | # Syncing 2200 blocks can take a while on slow systems. Give it plenty | ||||
# of time to sync. | # of time to sync. | ||||
p2p1.sync_with_ping(960) | p2p1.sync_with_ping(960) | ||||
assert_equal(self.nodes[1].getblock( | assert_equal( | ||||
self.nodes[1].getbestblockhash())['height'], 2202) | self.nodes[1].getblock(self.nodes[1].getbestblockhash())["height"], 2202 | ||||
) | |||||
# Send blocks to node2. Block 102 will be rejected. | # Send blocks to node2. Block 102 will be rejected. | ||||
self.send_blocks_until_disconnected(p2p2) | self.send_blocks_until_disconnected(p2p2) | ||||
self.wait_until(lambda: self.nodes[2].getblockcount() >= 101) | self.wait_until(lambda: self.nodes[2].getblockcount() >= 101) | ||||
assert_equal(self.nodes[2].getblockcount(), 101) | assert_equal(self.nodes[2].getblockcount(), 101) | ||||
if __name__ == '__main__': | if __name__ == "__main__": | ||||
AssumeValidTest().main() | AssumeValidTest().main() |