def test_can_create_block_from_main_transaction(
    forced_mock_blockchain, treasury_account_key_pair: KeyPair, user_account_key_pair: KeyPair,
    primary_validator_key_pair: KeyPair, node_key_pair: KeyPair
):

    def get_account_balance(self, account, on_block_number):
        return 430 if account == treasury_account_key_pair.public else 0

    with patch.object(MockBlockchain, 'get_account_balance', new=get_account_balance):
        block = Block.create_from_main_transaction(
            forced_mock_blockchain, user_account_key_pair.public, 20, signing_key=treasury_account_key_pair.private
        )

    # Assert block
    assert block.message
    assert block.hash
    assert block.signature

    block.validate_signature()
    assert block.signer
    assert block.signer == derive_verify_key(get_node_signing_key())

    # Assert block.message
    block_message = block.message
    assert block_message
    assert isinstance(block_message.timestamp, datetime)
    assert block_message.timestamp.tzinfo is None
    assert block_message.timestamp - datetime.utcnow() < timedelta(seconds=1)

    assert block_message.block_number == 0
    assert block_message.block_identifier == 'next-block-identifier'
    updated_account_states = block_message.updated_account_states

    assert isinstance(updated_account_states, dict)
    assert len(updated_account_states) == 4

    assert updated_account_states[treasury_account_key_pair.public].balance == 430 - 25
    assert updated_account_states[treasury_account_key_pair.public].balance_lock

    assert updated_account_states[user_account_key_pair.public].balance == 20
    assert updated_account_states[user_account_key_pair.public].balance_lock is None

    assert updated_account_states[primary_validator_key_pair.public].balance == 4
    assert updated_account_states[primary_validator_key_pair.public].balance_lock is None

    assert updated_account_states[node_key_pair.public].balance == 1
    assert updated_account_states[node_key_pair.public].balance_lock is None

    # Assert block_message.signed_change_request
    signed_change_request = block_message.signed_change_request
    assert signed_change_request.signer == treasury_account_key_pair.public
    assert signed_change_request.signature

    # Assert block_message.signed_change_request.message
    coin_transfer_signed_request_message = signed_change_request.message
    assert isinstance(coin_transfer_signed_request_message, CoinTransferSignedChangeRequestMessage)
    assert coin_transfer_signed_request_message.balance_lock
    assert len(coin_transfer_signed_request_message.txs) == 3
    txs_dict = {tx.recipient: tx for tx in coin_transfer_signed_request_message.txs}
    assert len(txs_dict) == 3

    assert txs_dict[user_account_key_pair.public].amount == 20
    assert txs_dict[user_account_key_pair.public].is_fee is False

    assert txs_dict[primary_validator_key_pair.public].amount == 4
    assert txs_dict[primary_validator_key_pair.public].is_fee

    assert txs_dict[node_key_pair.public].amount == 1
    assert txs_dict[node_key_pair.public].is_fee

    assert coin_transfer_signed_request_message.get_total_amount() == 25
Esempio n. 2
0
def test_can_add_coin_transfer_block(
    forced_memory_blockchain: MemoryBlockchain,
    treasury_account_key_pair: KeyPair,
    user_account_key_pair: KeyPair,
    primary_validator_key_pair: KeyPair,
    node_key_pair: KeyPair,
):
    blockchain = forced_memory_blockchain

    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