示例#1
0
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_yield_blocks_from_cache(blockchain_directory):
    blockchain = FileBlockchain(base_directory=blockchain_directory)
    blockchain.blocks_cache[0] = block0 = CoinTransferBlockFactory(hash='0')
    blockchain.blocks_cache[1] = block1 = CoinTransferBlockFactory(hash='1')
    blockchain.blocks_cache[2] = block2 = CoinTransferBlockFactory(hash='2')
    blockchain.blocks_cache[3] = block3 = CoinTransferBlockFactory(hash='3')
    assert block0

    assert list(blockchain._yield_blocks_from_cache(1, 10, 1)) == [block1, block2, block3]
    assert list(blockchain._yield_blocks_from_cache(1, 2, 1)) == [block1, block2]
    assert list(blockchain._yield_blocks_from_cache(0, 3, -1)) == [block3, block2, block1, block0]
    assert list(blockchain._yield_blocks_from_cache(1, 2, -1)) == [block2, block1]
示例#3
0
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]
示例#4
0
    def handle(self, size, path=None, do_not_validate=False, *args, **options):
        validate = not do_not_validate
        if path:
            os.makedirs(path, exist_ok=True)

            if os.listdir(path):
                raise CommandError(f'Path {path} contains files')

            blockchain = FileBlockchain(base_directory=os.path.abspath(path))
        else:
            blockchain = MemoryBlockchain()

        generate_blockchain(blockchain, size, validate=validate)
示例#5
0
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]
示例#6
0
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]
示例#7
0
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()) == []
示例#8
0
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])
示例#9
0
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'
            ))
示例#10
0
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

    node_signing_key = get_node_signing_key()
    block0 = Block.create_from_main_transaction(
        blockchain=blockchain,
        recipient=user_account,
        amount=30,
        request_signing_key=treasury_account_key_pair.private,
        pv_signing_key=node_signing_key,
    )
    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=blockchain,
        recipient=user_account,
        amount=10,
        request_signing_key=treasury_account_key_pair.private,
        pv_signing_key=node_signing_key,
    )
    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=blockchain,
        recipient=treasury_account,
        amount=5,
        request_signing_key=user_account_key_pair.private,
        pv_signing_key=node_signing_key,
    )
    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