def test_validate_account_root_file_next_block_identifier_mismatch(blockchain_base): last_block_identifier = '0' * 64 block_number = 0 blockchain_genesis_state = factories.InitialBlockchainStateFactory() block_0 = factories.CoinTransferBlockFactory( message=factories.CoinTransferBlockMessageFactory( block_number=block_number, block_identifier=last_block_identifier ), hash='e' * 64, ) state_1 = factories.BlockchainStateFactory( last_block_number=block_number, last_block_identifier=last_block_identifier, next_block_identifier='f' * 64, ) blockchain_state_patch = patch_blockchain_states(blockchain_base, [blockchain_genesis_state, state_1]) block_patch = patch_blocks(blockchain_base, [block_0]) with blockchain_state_patch, block_patch: with pytest.raises( ValidationError, match='Account root file next_block_identifier does not match ' 'last_block_number message hash' ): blockchain_base.validate_account_root_files(is_partial_allowed=True)
def test_get_expected_block_identifier_from_last_block( blockchain_base, blockchain_genesis_state, block_0, block_1, block_2): with patch_blocks(blockchain_base, [block_0, block_1, block_2]): block_identifier = blockchain_base.get_expected_block_identifier( block_number=3) assert block_identifier == block_2.hash
def test_yield_blocks_till_snapshot_with_no_account_root_file( blockchain_base, block_0, block_1, block_2): with patch_blocks(blockchain_base, [block_0, block_1, block_2]), patch_blockchain_states( blockchain_base, []): with pytest.raises(InvalidBlockchain): list(blockchain_base.yield_blocks_till_snapshot())
def test_yield_blocks_till_snapshot_with_no_account_root_file( blockchain_base, block_0, block_1, block_2): with patch_blocks(blockchain_base, [block_0, block_1, block_2]), patch_blockchain_states( blockchain_base, []): blocks = list(blockchain_base.yield_blocks_till_snapshot()) assert blocks == []
def test_validate_account_root_file_points_to_non_existing_block(blockchain_base): blockchain_genesis_state = factories.InitialBlockchainStateFactory() block_0 = factories.CoinTransferBlockFactory(message=factories.CoinTransferBlockMessageFactory(block_number=0)) state_5 = factories.BlockchainStateFactory(last_block_number=5) blockchain_state_patch = patch_blockchain_states(blockchain_base, [blockchain_genesis_state, state_5]) block_patch = patch_blocks(blockchain_base, [block_0]) with blockchain_state_patch, block_patch: with pytest.raises(ValidationError, match='Account root file last_block_number points to non-existing block'): blockchain_base.validate_account_root_files(is_partial_allowed=True)
def test_can_yield_blocks_till_snapshot(blockchain_base, blockchain_genesis_state, account_root_file_block_number, from_block_number, expected_block_numbers, block_0, block_1, block_2): blockchain_state_patch = patch_blockchain_states(blockchain_base, [ blockchain_genesis_state, factories.BlockchainStateFactory( last_block_number=account_root_file_block_number), ]) blocks_patch = patch_blocks(blockchain_base, [block_0, block_1, block_2]) with blocks_patch, blockchain_state_patch: blocks = list( blockchain_base.yield_blocks_till_snapshot( from_block_number=from_block_number)) assert list(map(attrgetter('message.block_number'), blocks)) == expected_block_numbers
def test_can_get_block_count(blockchain_base, block_0, block_1, block_2): with patch_blocks(blockchain_base, [block_0, block_1, block_2]): block_count = blockchain_base.get_block_count() assert block_count == 3
def test_can_get_last_block(blockchain_base, block_0, block_1, block_2): with patch_blocks(blockchain_base, [block_0, block_1, block_2]): last_block = blockchain_base.get_last_block() assert last_block == block_2
def test_can_get_last_block_at_init(blockchain_base): with patch_blocks(blockchain_base, []): last_block = blockchain_base.get_last_block() assert last_block is None
def test_get_block_by_number_returns_none_if_block_doesnt_exist( blockchain_base, block_0, block_1, block_2): with patch_blocks(blockchain_base, [block_0, block_2]): block = blockchain_base.get_block_by_number(block_number=1) assert block is None
def test_can_get_block_by_number(blockchain_base, block_0, block_1, block_2): with patch_blocks(blockchain_base, [block_0, block_1, block_2]): block = blockchain_base.get_block_by_number(block_number=1) assert block == block_1
def test_can_yield_blocks_reversed(blockchain_base, block_0, block_1, block_2): with patch_blocks(blockchain_base, [block_0, block_1, block_2]): blocks = list(blockchain_base.yield_blocks_reversed()) assert blocks == [block_2, block_1, block_0]
def test_can_yield_blocks_from(blockchain_base, block_0, block_1, block_2): with patch_blocks(blockchain_base, [block_0, block_1, block_2]): blocks = list(blockchain_base.yield_blocks_from(block_number=1)) assert blocks == [block_1, block_2]
def test_generate_blockchain_state(blockchain_base): blockchain_genesis_state = factories.InitialBlockchainStateFactory( account_states={USER_ACCOUNT_1: factories.AccountStateFactory( balance=1000, balance_lock=USER_ACCOUNT_1, )} ) block_0 = factories.CoinTransferBlockFactory( message=factories.CoinTransferBlockMessageFactory( block_number=0, block_identifier='fake-block-identifier-0', timestamp=datetime(2021, 1, 1), signed_change_request=factories.CoinTransferSignedChangeRequestFactory( signer=USER_ACCOUNT_1, message=factories.CoinTransferSignedChangeRequestMessageFactory( balance_lock=USER_ACCOUNT_1, txs=[ factories.CoinTransferTransactionFactory( recipient=USER_ACCOUNT_2, amount=99, ), ] ), ), updated_account_states={ USER_ACCOUNT_1: factories.AccountStateFactory( balance=901, balance_lock='user-account-1-lock', ), USER_ACCOUNT_2: factories.AccountStateFactory( balance=99, balance_lock=None, ) } ), hash='fake-message-hash', ) blockchain_state_patch = patch_blockchain_states(blockchain_base, [blockchain_genesis_state]) block_patch = patch_blocks(blockchain_base, [block_0]) with blockchain_state_patch, block_patch: blockchain_state = blockchain_base.generate_blockchain_state() assert blockchain_state == factories.BlockchainStateFactory( account_states={ USER_ACCOUNT_1: factories.AccountStateFactory( balance=901, balance_lock='user-account-1-lock', node=None, ), USER_ACCOUNT_2: factories.AccountStateFactory( balance=99, balance_lock=None, node=None, ) }, last_block_number=0, last_block_identifier=block_0.message.block_identifier, last_block_timestamp=block_0.message.timestamp, next_block_identifier=block_0.hash, )