Example #1
0
def test_uncle_block_inclusion_validity(vm_fn):
    # This test ensures that a forked block which is behind by
    # more than 6 layers cannot act as an ancestor to the current block

    OTHER_MINER_ADDRESS = 20 * b'\x01'

    chain = build(
        MiningChain,
        vm_fn(0),
        disable_pow_check(),
        genesis(),
        mine_block(),  # 1
        mine_block(),  # 2
    )

    fork_chain = build(
        chain,
        at_block_number(1),
        mine_block(extra_data=b'fork-it!',
                   coinbase=OTHER_MINER_ADDRESS),  # fork 2
    )

    # we don't use canonical head here because the fork chain is non-canonical.
    uncle = fork_chain.get_block_header_by_hash(fork_chain.header.parent_hash)
    assert uncle.block_number == 2

    with pytest.raises(ValidationError):
        chain = build(
            chain,
            # Mines blocks from 3 to 8 (both numbers inclusive)
            mine_blocks(6),
            # Mine block 9 with uncle
            mine_block(uncles=[uncle]),
        )
Example #2
0
def get_chain(vm: Type[BaseVM], genesis_state: GenesisState) -> MiningChain:

    chain = build(MiningChain, fork_at(vm, constants.GENESIS_BLOCK_NUMBER),
                  disable_pow_check(),
                  genesis(params=GENESIS_PARAMS, state=genesis_state))

    return chain
Example #3
0
def test_eip1559_txn_rewards(max_total_price, max_priority_price,
                             expected_miner_tips, funded_address,
                             funded_address_private_key):

    chain = build(
        MiningChain,
        berlin_at(0),
        london_at(1),  # Start London at block one to get easy 1gwei base fee
        disable_pow_check(),
        genesis(
            params=dict(gas_limit=10**7),
            state={funded_address: dict(balance=10**20)},
        ),
    )
    vm = chain.get_vm()
    txn = new_dynamic_fee_transaction(
        vm,
        from_=funded_address,
        to=funded_address,
        private_key=funded_address_private_key,
        max_priority_fee_per_gas=max_priority_price,
        max_fee_per_gas=max_total_price,
    )

    MINER = b'\x0f' * 20
    original_balance = vm.state.get_balance(MINER)
    chain.mine_all([txn], coinbase=MINER)
    new_balance = chain.get_vm().state.get_balance(MINER)

    BLOCK_REWARD = 2 * (10**18)
    assert original_balance + BLOCK_REWARD + expected_miner_tips == new_balance
Example #4
0
def bob_chain():
    chain = build(
        MiningChain,
        latest_mainnet_at(0),
        disable_pow_check(),
        genesis(),
    )
    return chain
Example #5
0
def alice_chain(bob_chain):
    bob_genesis = bob_chain.headerdb.get_canonical_block_header_by_number(0)

    chain = build(
        MiningChain,
        latest_mainnet_at(0),
        disable_pow_check(),
        genesis(params={"timestamp": bob_genesis.timestamp}),
    )
    return chain
Example #6
0
def test_rewards_nephew_uncle_different_vm(vm_fn_uncle, vm_fn_nephew,
                                           miner_1_balance, miner_2_balance):
    OTHER_MINER_ADDRESS = 20 * b'\x01'
    TOTAL_BLOCKS_CANONICAL_CHAIN = 10
    VM_CHANGE_BLOCK_NUMBER = 4

    chain = build(
        MiningChain,
        vm_fn_uncle(0),
        vm_fn_nephew(VM_CHANGE_BLOCK_NUMBER),
        disable_pow_check(),
        genesis(),
        mine_blocks(TOTAL_BLOCKS_CANONICAL_CHAIN - 1),
    )

    fork_chain = build(
        chain,
        at_block_number(3),
        mine_block(extra_data=b'fork-it!',
                   coinbase=OTHER_MINER_ADDRESS),  # fork 2
    )

    # we don't use canonical head here because the fork chain is non-canonical.
    uncle = fork_chain.get_block_header_by_hash(fork_chain.header.parent_hash)
    assert uncle.block_number == 4

    chain = build(
        chain,
        mine_block(uncles=[uncle]),
    )

    header = chain.get_canonical_head()
    block = chain.get_block_by_hash(header.hash)
    assert len(block.uncles) == 1
    assert block.uncles[0] == uncle

    vm = chain.get_vm()
    coinbase_balance = vm.state.get_balance(block.header.coinbase)
    other_miner_balance = vm.state.get_balance(uncle.coinbase)

    uncle_vm = chain.get_vm_class_for_block_number(0)
    nephew_vm = chain.get_vm_class_for_block_number(VM_CHANGE_BLOCK_NUMBER)

    # We first test if the balance matches what we would determine
    # if we made all the API calls involved ourselves.
    assert coinbase_balance == (uncle_vm.get_block_reward() * 3 +
                                nephew_vm.get_block_reward() *
                                (TOTAL_BLOCKS_CANONICAL_CHAIN - 3) +
                                vm.get_nephew_reward())
    assert other_miner_balance == vm.get_uncle_reward(block.number, uncle)

    # But we also ensure the balance matches the numbers that we calculated on paper
    assert coinbase_balance == to_wei(miner_1_balance, 'ether')
    assert other_miner_balance == to_wei(miner_2_balance, 'ether')
Example #7
0
def get_chain(vm: Type[VirtualMachineAPI],
              genesis_state: GenesisState) -> Iterable[MiningChain]:

    with tempfile.TemporaryDirectory() as temp_dir:
        level_db_obj = LevelDB(Path(temp_dir))
        level_db_chain = build(
            MiningChain, fork_at(vm, constants.GENESIS_BLOCK_NUMBER),
            disable_pow_check(),
            genesis(db=level_db_obj,
                    params=GENESIS_PARAMS,
                    state=genesis_state))
        yield level_db_chain
def test_chain_builder_disable_pow_check():
    chain = build(
        MiningChain,
        frontier_at(0),
        disable_pow_check(),
        genesis(),
    )
    block = chain.mine_block()
    with pytest.raises(ValidationError, match='mix hash mismatch'):
        check_pow(
            block.number,
            block.header.mining_hash,
            block.header.mix_hash,
            block.header.nonce,
            block.header.difficulty,
        )
def test_chain_builder_disable_pow_check():
    chain = build(
        MiningChain,
        frontier_at(0),
        disable_pow_check(),
        genesis(),
    )
    block = chain.mine_block()
    # check_eccpow(
    #     block.header.parent_hash,
    #     block.header.mining_hash,
    #     24, 3, 6)
    with pytest.raises(ValidationError, match='mix hash mismatch'):
        # ToDo: Have to change difficulty
        check_eccpow(block.header.parent_hash, block.header.mining_hash, 24, 3,
                     6)
Example #10
0
def test_rewards_uncle_created_at_different_generations(
        vm_fn, fork_at_block_number, miner_1_balance, miner_2_balance):
    OTHER_MINER_ADDRESS = 20 * b'\x01'
    TOTAL_BLOCKS_CANONICAL_CHAIN = 10

    chain = build(
        MiningChain,
        vm_fn(0),
        disable_pow_check(),
        genesis(),
        mine_blocks(TOTAL_BLOCKS_CANONICAL_CHAIN - 1),
    )

    fork_chain = build(
        chain,
        at_block_number(fork_at_block_number),
        mine_block(extra_data=b'fork-it!',
                   coinbase=OTHER_MINER_ADDRESS),  # fork 2
    )

    # we don't use canonical head here because the fork chain is non-canonical.
    uncle = fork_chain.get_block_header_by_hash(fork_chain.header.parent_hash)
    assert uncle.block_number == fork_at_block_number + 1

    chain = build(
        chain,
        mine_block(uncles=[uncle]),
    )

    header = chain.get_canonical_head()
    block = chain.get_block_by_hash(header.hash)

    vm = chain.get_vm()
    coinbase_balance = vm.state.account_db.get_balance(block.header.coinbase)
    other_miner_balance = vm.state.account_db.get_balance(uncle.coinbase)

    # We first test if the balance matches what we would determine
    # if we made all the API calls involved ourselves.
    assert coinbase_balance == (
        vm.get_block_reward() * TOTAL_BLOCKS_CANONICAL_CHAIN +
        vm.get_nephew_reward())

    assert other_miner_balance == vm.get_uncle_reward(block.number, uncle)

    # But we also ensure the balance matches the numbers that we calculated on paper
    assert coinbase_balance == to_wei(miner_1_balance, 'ether')
    assert other_miner_balance == to_wei(miner_2_balance, 'ether')
Example #11
0
def new_chain_from_fixture(fixture, chain_cls=MainnetChain):
    base_db = AtomicDB()

    vm_config = chain_vm_configuration(fixture)

    ChainFromFixture = chain_cls.configure(
        'ChainFromFixture',
        vm_configuration=vm_config,
    )

    if 'sealEngine' in fixture and fixture['sealEngine'] == 'NoProof':
        ChainFromFixture = disable_pow_check(ChainFromFixture)

    return ChainFromFixture.from_genesis(
        base_db,
        genesis_params=genesis_params_from_fixture(fixture),
        genesis_state=fixture['pre'],
    )
def test_disabling_pow_for_already_pow_disabled_chain(chain):
    pow_disabled_chain = disable_pow_check(chain)
    assert issubclass(pow_disabled_chain, NoChainSealValidationMixin)
    again_pow_disabled_chain = disable_pow_check(pow_disabled_chain)
    assert issubclass(again_pow_disabled_chain, NoChainSealValidationMixin)