def test_get_recent_block_hashes(contract): w3 = contract.web3 block0 = w3.eth.getBlock(0) block1 = w3.eth.getBlock(1) recent_block_hashes = get_recent_block_hashes(w3, HISTORY_SIZE) assert len(recent_block_hashes) == 2 assert block0['hash'] == recent_block_hashes[0] assert block1['hash'] == recent_block_hashes[1] mine(w3, 2) block2 = w3.eth.getBlock(2) block3 = w3.eth.getBlock(3) recent_block_hashes = get_recent_block_hashes(w3, HISTORY_SIZE) assert len(recent_block_hashes) == 4 assert block2['hash'] == recent_block_hashes[2] assert block3['hash'] == recent_block_hashes[3]
def test_get_canonical_chain_with_forks(contract): w3 = contract.web3 counter = itertools.count() recent_block_hashes = get_recent_block_hashes(w3, HISTORY_SIZE) # snapshot when blockNumber=1 snapshot_id = take_snapshot(w3) current_block_number = w3.eth.blockNumber # counter == 0 in block2 contract.transact(default_tx_detail).emit_log(next(counter)) mine(w3, 1) block2 = w3.eth.getBlock('latest') revoked_hashes, new_block_hashes = get_canonical_chain( w3, recent_block_hashes, HISTORY_SIZE, ) assert revoked_hashes == tuple() assert block2['hash'] in new_block_hashes if len(revoked_hashes) != 0: unchanged_block_hashes = recent_block_hashes[:-1 * len(revoked_hashes)] else: unchanged_block_hashes = recent_block_hashes new_recent_block_hashes = unchanged_block_hashes + new_block_hashes recent_block_hashes = new_recent_block_hashes[-1 * HISTORY_SIZE:] revert_to_snapshot(w3, snapshot_id) assert w3.eth.blockNumber == current_block_number mine(w3, 1) # block2_prime block2_prime = w3.eth.getBlock('latest') # counter == 1 in block3_prime contract.transact(default_tx_detail).emit_log(next(counter)) mine(w3, 1) block3_prime = w3.eth.getBlock('latest') # counter == 2 in block4_prime contract.transact(default_tx_detail).emit_log(next(counter)) mine(w3, 1) block4_prime = w3.eth.getBlock('latest') revoked_hashes, new_block_hashes = get_canonical_chain( w3, recent_block_hashes, HISTORY_SIZE, ) assert block2['hash'] in revoked_hashes assert len(revoked_hashes) == 1 # ensure that the block in the behind of new_block_hashes is newer assert block2_prime['hash'] == new_block_hashes[-3] assert block3_prime['hash'] == new_block_hashes[-2] assert block4_prime['hash'] == new_block_hashes[-1]
def test_check_chain_head_without_forks(contract): w3 = contract.web3 recent_block_hashes = get_recent_block_hashes(w3, HISTORY_SIZE) revoked_hashes, new_block_hashes = check_chain_head( w3, recent_block_hashes, HISTORY_SIZE) assert revoked_hashes == tuple() assert new_block_hashes == tuple() if len(revoked_hashes) != 0: unchanged_block_hashes = recent_block_hashes[:-1 * len(revoked_hashes)] else: unchanged_block_hashes = recent_block_hashes new_recent_block_hashes = unchanged_block_hashes + new_block_hashes recent_block_hashes = new_recent_block_hashes[-1 * HISTORY_SIZE:] mine(w3, 1) block2 = w3.eth.getBlock('latest') revoked_hashes, new_block_hashes = check_chain_head( w3, recent_block_hashes, HISTORY_SIZE, ) assert revoked_hashes == tuple() assert len(new_block_hashes) == 1 assert block2['hash'] in new_block_hashes if len(revoked_hashes) != 0: unchanged_block_hashes = recent_block_hashes[:-1 * len(revoked_hashes)] else: unchanged_block_hashes = recent_block_hashes new_recent_block_hashes = unchanged_block_hashes + new_block_hashes recent_block_hashes = new_recent_block_hashes[-1 * HISTORY_SIZE:] mine(w3, 3) block3 = w3.eth.getBlock(3) block4 = w3.eth.getBlock(4) block5 = w3.eth.getBlock(5) revoked_hashes, new_block_hashes = check_chain_head( w3, recent_block_hashes, HISTORY_SIZE, ) assert revoked_hashes == tuple() assert len(new_block_hashes) == 3 assert block3['hash'] == new_block_hashes[0] assert block4['hash'] == new_block_hashes[1] assert block5['hash'] == new_block_hashes[2]