def test_can_get_account_root_file_count(blockchain_base, blockchain_state_10, blockchain_state_20): with patch_blockchain_states(blockchain_base, [blockchain_state_10, blockchain_state_20]): arf_count = blockchain_base.get_blockchain_states_count() assert arf_count == 2
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_can_get_first_blockchain_state(blockchain_base, blockchain_state_10, blockchain_state_20): with patch_blockchain_states(blockchain_base, [blockchain_state_10, blockchain_state_20]): first_arf = blockchain_base.get_first_blockchain_state() assert first_arf == blockchain_state_10
def test_get_expected_block_identifier_with_blockchain_genesis_state( blockchain_base, blockchain_genesis_state): with patch_blockchain_states(blockchain_base, [blockchain_genesis_state]): block_identifier = blockchain_base.get_expected_block_identifier( block_number=0) assert block_identifier == blockchain_genesis_state.get_hash()
def test_get_expected_block_identifier_without_blockchain_genesis_state( blockchain_base): with patch_blockchain_states(blockchain_base, []): block_identifier = blockchain_base.get_expected_block_identifier( block_number=0) assert block_identifier is None
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_exclude_non_existing_account_root_file_from_closest( blockchain_base, blockchain_state_10, blockchain_state_20): with patch_blockchain_states(blockchain_base, [blockchain_state_10, blockchain_state_20]): retrieved_arf = blockchain_base.get_blockchain_state_by_block_number( 21) assert retrieved_arf == blockchain_state_20
def test_can_get_blockchain_genesis_state(blockchain_base, blockchain_genesis_state, blockchain_state_10): with patch_blockchain_states( blockchain_base, [blockchain_genesis_state, blockchain_state_10]): retrieved_arf = blockchain_base.get_closest_blockchain_state_snapshot( excludes_block_number=-1) assert retrieved_arf == blockchain_genesis_state
def test_can_yield_blockchain_states_reversed(blockchain_base, blockchain_state_10, blockchain_state_20): with patch_blockchain_states(blockchain_base, [blockchain_state_10, blockchain_state_20]): account_root_files = list( blockchain_base.yield_blockchain_states_reversed()) assert account_root_files == [blockchain_state_20, blockchain_state_10]
def test_can_get_blockchain_genesis_state(blockchain_base, blockchain_genesis_state, blockchain_state_10): with patch_blockchain_states( blockchain_base, [blockchain_genesis_state, blockchain_state_10]): retrieved_arf = blockchain_base.get_blockchain_state_by_block_number( -1) assert retrieved_arf == blockchain_genesis_state
def test_can_exclude_last_from_closest_account_root_files( blockchain_base, excludes_block_number, blockchain_state_10, blockchain_state_20): with patch_blockchain_states(blockchain_base, [blockchain_state_10, blockchain_state_20]): retrieved_arf = blockchain_base.get_blockchain_state_by_block_number( excludes_block_number) assert retrieved_arf == blockchain_state_10
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_closest_account_root_file_not_found(blockchain_base, excludes_block_number, blockchain_state_10, blockchain_state_20): with patch_blockchain_states(blockchain_base, [blockchain_state_10, blockchain_state_20]): retrieved_arf = blockchain_base.get_closest_blockchain_state_snapshot( excludes_block_number=excludes_block_number) assert retrieved_arf is None
def test_closest_account_root_file_not_found(blockchain_base, excludes_block_number, blockchain_state_10, blockchain_state_20): with patch_blockchain_states(blockchain_base, [blockchain_state_10, blockchain_state_20]): with pytest.raises( InvalidBlockchain, match=r'Blockchain state before block number \d+ is not found' ): blockchain_base.get_blockchain_state_by_block_number( excludes_block_number)
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_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, )
def test_get_expected_block_identifier_without_blockchain_genesis_state( blockchain_base): with patch_blockchain_states(blockchain_base, []): with pytest.raises(InvalidBlockchain, match='Blockchain must contain a blockchain state'): blockchain_base.get_expected_block_identifier(block_number=0)
def test_blockchain_genesis_state_not_found(blockchain_base): with patch_blockchain_states(blockchain_base, []): with pytest.raises(InvalidBlockchain, match='Blockchain must contain a blockchain state'): blockchain_base.get_blockchain_state_by_block_number(-1)
def test_blockchain_without_blockchain_genesis_state_is_validated(blockchain_base): non_initial_blockchain_state = factories.BlockchainStateFactory() with patch_blockchain_states(blockchain_base, [non_initial_blockchain_state]): blockchain_base.validate_account_root_files(is_partial_allowed=True)
def test_first_account_root_file_is_none(blockchain_base): with patch_blockchain_states(blockchain_base, []): with pytest.raises(InvalidBlockchain, match='Blockchain must contain a blockchain state'): blockchain_base.get_first_blockchain_state()
def test_blockchain_must_have_at_least_blockchain_genesis_state(blockchain_base): with patch_blockchain_states(blockchain_base, []): with pytest.raises(ValidationError, match='Blockchain must contain at least one account root file'): blockchain_base.validate_account_root_files()
def test_blockchain_must_start_with_blockchain_genesis_state(blockchain_base): non_initial_blockchain_state = factories.BlockchainStateFactory() with patch_blockchain_states(blockchain_base, [non_initial_blockchain_state]): with pytest.raises(ValidationError, match='Blockchain must start with initial account root file'): blockchain_base.validate_account_root_files(is_partial_allowed=False)
def test_blockchain_blockchain_genesis_state_is_validated(blockchain_base): blockchain_genesis_state = factories.InitialBlockchainStateFactory() with patch_blockchain_states(blockchain_base, [blockchain_genesis_state]): blockchain_base.validate_account_root_files(is_partial_allowed=False)
def test_blockchain_genesis_state_not_found(blockchain_base): with patch_blockchain_states(blockchain_base, []): initial_arf = blockchain_base.get_closest_blockchain_state_snapshot( excludes_block_number=-1) assert initial_arf is None
def test_first_account_root_file_is_none(blockchain_base): with patch_blockchain_states(blockchain_base, []): first_arf = blockchain_base.get_first_blockchain_state() assert first_arf is None
def test_last_account_root_file_is_none(blockchain_base, blockchain_state_10, blockchain_state_20): with patch_blockchain_states(blockchain_base, []): last_arf = blockchain_base.get_last_blockchain_state() assert last_arf is None