def test_can_get_nodes_blocks_node_overrides_genesis_state_node( blockchain_directory, blockchain_genesis_state, user_account_key_pair ): blockchain = FileBlockchain(base_directory=blockchain_directory) account_number = user_account_key_pair.public blockchain_state_node = baker.make( Node, network_addresses=['https://192.168.0.32:8555/'], identifier=account_number ) blockchain_genesis_state.account_states[account_number] = AccountState(node=blockchain_state_node) blockchain.add_blockchain_state(blockchain_genesis_state) blockchain.validate() request = NodeDeclarationSignedChangeRequest.create( network_addresses=['https://127.0.0.1:8555/'], fee_amount=3, signing_key=user_account_key_pair.private ) blocks_node = request.message.node assert blocks_node.identifier block = Block.create_from_signed_change_request(blockchain, request, get_node_signing_key()) blockchain.add_block(block) assert blocks_node != blockchain_state_node assert list(blockchain.yield_nodes()) == [blocks_node]
def test_can_add_block( blockchain_directory, blockchain_genesis_state, treasury_account_key_pair: KeyPair, user_account_key_pair: KeyPair, primary_validator_key_pair: KeyPair, node_key_pair: KeyPair, ): blockchain = FileBlockchain(base_directory=blockchain_directory) blockchain.add_blockchain_state(blockchain_genesis_state) blockchain.validate() treasury_account = treasury_account_key_pair.public treasury_initial_balance = blockchain.get_account_current_balance(treasury_account) assert treasury_initial_balance is not None user_account = user_account_key_pair.public pv_account = primary_validator_key_pair.public node_account = node_key_pair.public total_fees = 1 + 4 block0 = Block.create_from_main_transaction( blockchain, user_account, 30, signing_key=treasury_account_key_pair.private ) blockchain.add_block(block0) assert blockchain.get_account_current_balance(user_account) == 30 assert blockchain.get_account_current_balance(treasury_account) == treasury_initial_balance - 30 - total_fees assert blockchain.get_account_current_balance(node_account) == 1 assert blockchain.get_account_current_balance(pv_account) == 4 with pytest.raises(ValidationError, match='Block number must be equal to next block number.*'): blockchain.add_block(block0) block1 = Block.create_from_main_transaction( blockchain, user_account, 10, signing_key=treasury_account_key_pair.private ) blockchain.add_block(block1) assert blockchain.get_account_current_balance(user_account) == 40 assert blockchain.get_account_current_balance(treasury_account ) == (treasury_initial_balance - 30 - 10 - 2 * total_fees) assert blockchain.get_account_current_balance(node_account) == 1 * 2 assert blockchain.get_account_current_balance(pv_account) == 4 * 2 block2 = Block.create_from_main_transaction( blockchain, treasury_account, 5, signing_key=user_account_key_pair.private ) blockchain.add_block(block2) assert blockchain.get_account_current_balance(user_account) == 40 - 5 - total_fees assert blockchain.get_account_current_balance(treasury_account ) == (treasury_initial_balance - 30 - 10 + 5 - 2 * total_fees) assert blockchain.get_account_current_balance(node_account) == 1 * 3 assert blockchain.get_account_current_balance(pv_account) == 4 * 3
def test_can_get_nodes_single_node_from_blockchain_genesis_state( blockchain_directory, blockchain_genesis_state, user_account_key_pair ): blockchain = FileBlockchain(base_directory=blockchain_directory) account_number = user_account_key_pair.public node = baker.make(Node, identifier=account_number) blockchain_genesis_state.account_states[account_number] = AccountState(node=node) blockchain.add_blockchain_state(blockchain_genesis_state) blockchain.validate() assert list(blockchain.yield_nodes()) == [node]
def test_can_get_nodes_single_node_from_blocks(blockchain_directory, blockchain_genesis_state, user_account_key_pair): blockchain = FileBlockchain(base_directory=blockchain_directory) blockchain.add_blockchain_state(blockchain_genesis_state) blockchain.validate() request = NodeDeclarationSignedChangeRequest.create( network_addresses=['https://127.0.0.1:8555/'], fee_amount=3, signing_key=user_account_key_pair.private ) node = request.message.node assert node.identifier block = Block.create_from_signed_change_request(blockchain, request, get_node_signing_key()) blockchain.add_block(block) assert list(blockchain.yield_nodes()) == [node]
def test_can_get_nodes_from_different_block_numbers( blockchain_directory, blockchain_genesis_state, user_account_key_pair ): account_number = user_account_key_pair.public blockchain = FileBlockchain(base_directory=blockchain_directory) blockchain_state_node = baker.make( Node, network_addresses=['https://192.168.0.29:8555/'], identifier=account_number ) blockchain_genesis_state.account_states[account_number] = AccountState(node=blockchain_state_node) blockchain.add_blockchain_state(blockchain_genesis_state) blockchain.validate() request = NodeDeclarationSignedChangeRequest.create( network_addresses=['https://192.168.0.30:8555/'], fee_amount=3, signing_key=user_account_key_pair.private ) node0 = request.message.node blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key())) request = NodeDeclarationSignedChangeRequest.create( network_addresses=['https://192.168.0.31:8555/'], fee_amount=3, signing_key=user_account_key_pair.private ) node1 = request.message.node blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key())) request = NodeDeclarationSignedChangeRequest.create( network_addresses=['https://192.168.0.32:8555/'], fee_amount=3, signing_key=user_account_key_pair.private ) node2 = request.message.node blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key())) assert list(blockchain.yield_nodes()) == [node2] assert list(blockchain.yield_nodes(block_number=2)) == [node2] assert list(blockchain.yield_nodes(block_number=1)) == [node1] assert list(blockchain.yield_nodes(block_number=0)) == [node0] assert list(blockchain.yield_nodes(block_number=-1)) == [blockchain_state_node]
def test_can_get_nodes_empty_list(blockchain_directory, blockchain_genesis_state): blockchain = FileBlockchain(base_directory=blockchain_directory) blockchain.add_blockchain_state(blockchain_genesis_state) blockchain.validate() assert list(blockchain.yield_nodes()) == []
def test_can_get_nodes_from_complex_blockchain(blockchain_directory, blockchain_genesis_state): key_pair1 = generate_key_pair() key_pair2 = generate_key_pair() key_pair3 = generate_key_pair() key_pair4 = generate_key_pair() key_pair5 = generate_key_pair() key_pair6 = generate_key_pair() assert len({ key_pair1.public, key_pair2.public, key_pair3.public, key_pair4.public, key_pair5.public, key_pair6.public }) == 6 blockchain = FileBlockchain(base_directory=blockchain_directory) node1 = baker.make(Node, network_addresses=['https://192.168.0.29:8555/'], identifier=key_pair1.public) blockchain_genesis_state.account_states[node1.identifier] = AccountState(node=node1) blockchain.add_blockchain_state(blockchain_genesis_state) blockchain.validate() # Block 0 request = NodeDeclarationSignedChangeRequest.create( network_addresses=['https://192.168.0.30:8555/'], fee_amount=3, signing_key=key_pair2.private ) node2 = request.message.node blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key())) # Block 1 request = NodeDeclarationSignedChangeRequest.create( network_addresses=['https://192.168.0.31:8555/'], fee_amount=3, signing_key=key_pair3.private ) node3_old = request.message.node blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key())) # Block 2 request = NodeDeclarationSignedChangeRequest.create( network_addresses=['https://192.168.0.32:8555/'], fee_amount=3, signing_key=key_pair4.private ) node4 = request.message.node blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key())) def sort_key(value): return value.network_addresses def sort_me(list_): return sorted(list_, key=sort_key) assert sort_me(blockchain.yield_nodes(block_number=2)) == sort_me([node4, node3_old, node2, node1]) blockchain.snapshot_blockchain_state() # Block 3 request = NodeDeclarationSignedChangeRequest.create( network_addresses=['https://192.168.0.33:8555/'], fee_amount=3, signing_key=key_pair3.private ) node3 = request.message.node blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key())) # Block 4 request = NodeDeclarationSignedChangeRequest.create( network_addresses=['https://192.168.0.34:8555/'], fee_amount=3, signing_key=key_pair5.private ) node5 = request.message.node blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key())) # Block 5 request = NodeDeclarationSignedChangeRequest.create( network_addresses=['https://192.168.0.35:8555/'], fee_amount=3, signing_key=key_pair6.private ) node6 = request.message.node blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key())) assert sort_me(blockchain.yield_nodes()) == sort_me([node6, node5, node3, node4, node2, node1]) assert sort_me(blockchain.yield_nodes(block_number=5)) == sort_me([node6, node5, node3, node4, node2, node1]) assert sort_me(blockchain.yield_nodes(block_number=4)) == sort_me([node5, node3, node4, node2, node1]) assert sort_me(blockchain.yield_nodes(block_number=3)) == sort_me([node3, node4, node2, node1]) assert sort_me(blockchain.yield_nodes(block_number=2)) == sort_me([node4, node3_old, node2, node1]) assert sort_me(blockchain.yield_nodes(block_number=1)) == sort_me([node3_old, node2, node1]) assert sort_me(blockchain.yield_nodes(block_number=0)) == sort_me([node2, node1]) assert sort_me(blockchain.yield_nodes(block_number=-1)) == sort_me([node1])
def test_blockchain_state_is_created_every_x_block( blockchain_path, blockchain_genesis_state, treasury_account_key_pair: KeyPair, user_account_key_pair: KeyPair, ): assert not os.path.isfile( str(blockchain_path / 'account-root-files/0/0/0/0/0/0/0/0/000000000.-arf.msgpack')) blockchain = FileBlockchain( base_directory=str(blockchain_path), snapshot_period_in_blocks=5, account_root_files_subdir='account-root-files', account_root_files_storage_kwargs={'compressors': ()}) blockchain.add_blockchain_state(blockchain_genesis_state) assert os.path.isfile( str(blockchain_path / 'account-root-files/0/0/0/0/0/0/0/0/000000000.-arf.msgpack')) blockchain.validate() user_account = user_account_key_pair.public for _ in range(4): block = Block.create_from_main_transaction( blockchain, user_account, 30, signing_key=treasury_account_key_pair.private) assert not os.path.isfile( str(blockchain_path / f'account-root-files/0/0/0/0/0/0/0/0/000000000{block.message.block_number}-arf.msgpack' )) blockchain.add_block(block) block = Block.create_from_main_transaction( blockchain, user_account, 30, signing_key=treasury_account_key_pair.private) blockchain.add_block(block) assert os.path.isfile( str(blockchain_path / f'account-root-files/0/0/0/0/0/0/0/0/000000000{block.message.block_number}-arf.msgpack' )) for _ in range(4): block = Block.create_from_main_transaction( blockchain, user_account, 30, signing_key=treasury_account_key_pair.private) assert not os.path.isfile( str(blockchain_path / f'account-root-files/0/0/0/0/0/0/0/0/000000000{block.message.block_number}-arf.msgpack' )) blockchain.add_block(block) block = Block.create_from_main_transaction( blockchain, user_account, 30, signing_key=treasury_account_key_pair.private) blockchain.add_block(block) assert os.path.isfile( str(blockchain_path / f'account-root-files/0/0/0/0/0/0/0/0/000000000{block.message.block_number}-arf.msgpack' ))