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_block_message_fields_are_stored_in_bytes(field_name, value):
    block_msg = factories.CoinTransferBlockMessageFactory(**{field_name: value})
    block = factories.CoinTransferBlockFactory(message=block_msg)

    compact_dict = block.to_compact_dict(compact_keys=False)['message']

    assert compact_dict[field_name] == bytes.fromhex(value)
Beispiel #3
0
def test_validate_account_root_file_next_block_identifier_mismatch(blockchain_base):
    last_block_identifier = '0' * 64
    block_number = 0
    initial_arf = factories.InitialAccountRootFileFactory()
    block_0 = factories.CoinTransferBlockFactory(
        message=factories.CoinTransferBlockMessageFactory(
            block_number=block_number, block_identifier=last_block_identifier
        ),
        message_hash='e' * 64,
    )
    arf_1 = factories.BlockchainStateFactory(
        last_block_number=block_number,
        last_block_identifier=last_block_identifier,
        next_block_identifier='f' * 64,
    )

    arf_patch = patch.object(blockchain_base, 'yield_blockchain_states', get_generator([initial_arf, arf_1]))
    block_patch = patch.object(blockchain_base, 'yield_blocks', get_generator([block_0]))
    with arf_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_signed_change_request_fields_are_stored_in_bytes(field_name, value):
    signed_change_request = factories.CoinTransferSignedChangeRequestFactory(**{field_name: value})
    block_msg = factories.CoinTransferBlockMessageFactory(signed_change_request=signed_change_request)
    block = factories.CoinTransferBlockFactory(message=block_msg)

    compact_dict = block.to_compact_dict(compact_keys=False)['message']['signed_change_request']

    assert compact_dict[field_name] == bytes.fromhex(value)
Beispiel #5
0
def test_validate_account_root_file_points_to_non_existing_block(blockchain_base):
    initial_arf = factories.InitialAccountRootFileFactory()
    block_0 = factories.CoinTransferBlockFactory(message=factories.CoinTransferBlockMessageFactory(block_number=0))
    arf_5 = factories.BlockchainStateFactory(last_block_number=5)

    arf_patch = patch.object(blockchain_base, 'yield_blockchain_states', get_generator([initial_arf, arf_5]))
    block_patch = patch.object(blockchain_base, 'yield_blocks', get_generator([block_0]))
    with arf_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_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_add_block_is_thread_safe(forced_file_blockchain, blockchain_directory):
    lock_file_path = os.path.join(blockchain_directory, 'file.lock')
    pool = ThreadPoolExecutor()
    block_0 = factories.CoinTransferBlockFactory()

    with filelock.FileLock(lock_file_path):
        future = pool.submit(forced_file_blockchain.add_block, block_0, validate=False)

        with pytest.raises(BlockchainLockedError, match='Blockchain locked*'):
            future.result(timeout=1)
def test_updated_balances_keys_are_stored_in_bytes():
    account = '1be4f03ab7ea1184dbb5e4ff53b8cf0fe1cc400150ca1476fcd10546c1b3cd6a'
    block_account_balance = factories.AccountStateFactory()
    updated_account_states = {
        account: block_account_balance,
    }
    block_msg = factories.CoinTransferBlockMessageFactory(updated_account_states=updated_account_states)
    block = factories.CoinTransferBlockFactory(message=block_msg)

    updated_balances_dict = block.to_compact_dict(compact_keys=False)['message']['updated_account_states']

    assert set(updated_balances_dict.keys()) == {bytes.fromhex(account)}
def test_updated_balances_fields_are_stored_in_bytes(field_name, value):
    account = '1be4f03ab7ea1184dbb5e4ff53b8cf0fe1cc400150ca1476fcd10546c1b3cd6a'
    block_account_balance = factories.AccountStateFactory(**{field_name: value})
    updated_account_states = {
        account: block_account_balance,
    }
    block_msg = factories.CoinTransferBlockMessageFactory(updated_account_states=updated_account_states)
    block = factories.CoinTransferBlockFactory(message=block_msg)

    account_bytes = bytes.fromhex(account)
    compact_dict = block.to_compact_dict(compact_keys=False)['message']['updated_account_states'][account_bytes]

    assert compact_dict[field_name] == bytes.fromhex(value)
def test_block_messagepack_with_compact_values_is_smaller():
    signature = (
        'd1c49087103b631a58228bdf8fb70d4789259cf22d815e207660cfe8d478adad9c'
        '7affe587942203e08be1dc1e14c6dd5a8abd8640f328e45f667a91a7c06a06'
    )
    message_hash = '9677f4cbd7aaf32ba9615416f7bd0991b7de1434a7fa2c31add25c3355ef3959'
    block = factories.CoinTransferBlockFactory(signature=signature, hash=message_hash)

    non_compact_size = len(block.to_messagepack(compact_keys=False, compact_values=False))
    compact_size = len(block.to_messagepack(compact_keys=False, compact_values=True))
    compaction_rate = (non_compact_size - compact_size) / non_compact_size

    assert compaction_rate > 0.3
Beispiel #11
0
def test_non_ascii_memo_is_serialized_correctly():
    # TODO(dmu) HIGH: This test must test transaction without using outer structures
    memo = 'Тестовое сообщение'  # Test message in Russian
    transaction = factories.CoinTransferTransactionFactory(memo=memo)
    transaction.fee = False
    trm = factories.CoinTransferSignedChangeRequestMessageFactory(
        txs=[transaction])
    tr = factories.CoinTransferSignedChangeRequestFactory(message=trm)
    block_message = factories.CoinTransferBlockMessageFactory(
        signed_change_request=tr)
    block = factories.CoinTransferBlockFactory(message=block_message)

    msg_pack = block.to_messagepack()
    restored_block = block.from_messagepack(msg_pack)

    assert restored_block == block
Beispiel #12
0
def test_transaction_optional_keys_are_not_serialized(key, value):
    # TODO(dmu) HIGH: This test must test transaction without using outer structures
    transaction = factories.CoinTransferTransactionFactory(**{key: value})
    trm = factories.CoinTransferSignedChangeRequestMessageFactory(
        txs=[transaction])
    tr = factories.CoinTransferSignedChangeRequestFactory(message=trm)
    block_message = factories.CoinTransferBlockMessageFactory(
        signed_change_request=tr)
    block = factories.CoinTransferBlockFactory(message=block_message)

    compact_dict = block.to_compact_dict(compact_values=False,
                                         compact_keys=False)

    transaction_dict = compact_dict['message']['signed_change_request'][
        'message']['txs'][0]
    assert key not in transaction_dict
from unittest.mock import patch

import pytest

from thenewboston_node.business_logic.tests import factories
from thenewboston_node.business_logic.utils.iter import get_generator

block_0 = factories.CoinTransferBlockFactory(
    message=factories.CoinTransferBlockMessageFactory(block_number=0))

block_1 = factories.CoinTransferBlockFactory(
    message=factories.CoinTransferBlockMessageFactory(block_number=1))

block_2 = factories.CoinTransferBlockFactory(
    message=factories.CoinTransferBlockMessageFactory(block_number=2),
    message_hash='fake-message-hash',
)


def test_can_get_block_count(blockchain_base):
    with patch.object(blockchain_base, 'yield_blocks',
                      get_generator([block_0, block_1, block_2])):
        block_count = blockchain_base.get_block_count()

    assert block_count == 3


def test_can_yield_blocks_from(blockchain_base):
    with patch.object(blockchain_base, 'yield_blocks',
                      get_generator([block_0, block_1, block_2])):
        blocks = list(blockchain_base.yield_blocks_from(block_number=1))
Beispiel #14
0
    USER_ACCOUNT_1:
    factories.AccountStateFactory(balance=100, balance_lock=USER_ACCOUNT_1)
}, )

block_0 = factories.CoinTransferBlockFactory(
    message=factories.CoinTransferBlockMessageFactory(
        block_number=0,
        block_identifier=BLOCK_IDENTIFIER,
        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=11,
                    )
                ])),
        updated_account_states={
            USER_ACCOUNT_1:
            factories.AccountStateFactory(balance=89,
                                          balance_lock=MESSAGE_HASH),
            USER_ACCOUNT_2:
            factories.AccountStateFactory(balance=11, balance_lock=None),
        }),
    message_hash=MESSAGE_HASH,
)


def test_validate_number_of_accounts_mismatch(blockchain_base):
    arf_0 = factories.BlockchainStateFactory(
Beispiel #15
0
def block_0():
    return factories.CoinTransferBlockFactory(message=factories.CoinTransferBlockMessageFactory(block_number=0))
Beispiel #16
0
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,
            )
        }
    ),
    message_hash='fake-message-hash',
)
Beispiel #17
0
def block_2():
    return factories.CoinTransferBlockFactory(
        message=factories.CoinTransferBlockMessageFactory(block_number=2),
        hash='fake-message-hash',
    )
def test_block_fields_are_stored_in_bytes(field_name, value):
    block = factories.CoinTransferBlockFactory(**{field_name: value})

    compact_dict = block.to_compact_dict(compact_keys=False)

    assert compact_dict[field_name] == bytes.fromhex(value)
Beispiel #19
0
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,
    )