Beispiel #1
0
 async def resetToGenesisFixture(self, chain_info: Any) -> BaseChain:
     '''
     This method is a special case. It returns a new chain object
     which is then replaced inside :class:`~trinity.rpc.main.RPCServer`
     for all future calls.
     '''
     return new_chain_from_fixture(chain_info, type(self._chain))
Beispiel #2
0
def test_blockchain_fixtures(fixture_data, fixture):
    try:
        chain = new_chain_from_fixture(fixture)
    except ValueError as e:
        raise AssertionError("could not load chain for {}".format(
            (fixture_data, ))) from e

    genesis_params = genesis_params_from_fixture(fixture)
    expected_genesis_header = BlockHeader(**genesis_params)

    # TODO: find out if this is supposed to pass?
    # if 'genesisRLP' in fixture:
    #     assert rlp.encode(genesis_header) == fixture['genesisRLP']

    genesis_block = chain.get_canonical_block_by_number(0)
    genesis_header = genesis_block.header

    assert_imported_genesis_header_unchanged(expected_genesis_header,
                                             genesis_header)

    # 1 - mine the genesis block
    # 2 - loop over blocks:
    #     - apply transactions
    #     - mine block
    # 3 - diff resulting state with expected state
    # 4 - check that all previous blocks were valid

    for block_fixture in fixture['blocks']:
        should_be_good_block = 'blockHeader' in block_fixture

        if 'rlp_error' in block_fixture:
            assert not should_be_good_block
            continue

        if should_be_good_block:
            (block, mined_block, block_rlp) = apply_fixture_block_to_chain(
                block_fixture,
                chain,
                perform_validation=False  # we manually validate below
            )
            assert_mined_block_unchanged(block, mined_block)
            chain.validate_block(block)
        else:
            try:
                apply_fixture_block_to_chain(block_fixture, chain)
            except (TypeError, rlp.DecodingError, rlp.DeserializationError,
                    ValidationError) as err:
                # failure is expected on this bad block
                pass
            else:
                raise AssertionError(
                    "Block should have caused a validation error")

    latest_block_hash = chain.get_canonical_block_by_number(
        chain.get_block().number - 1).hash
    if latest_block_hash != fixture['lastblockhash']:
        verify_account_db(fixture['postState'],
                          chain.get_vm().state.account_db)
Beispiel #3
0
    async def resetToGenesisFixture(self, chain_info: Any) -> ChainAPI:
        """
        This method is a special case. It returns a new chain object
        which is then replaced inside :class:`~trinity.rpc.main.RPCServer`
        for all future calls.
        """
        chain = new_chain_from_fixture(chain_info, type(self.chain))

        await self.event_bus.broadcast(ChainReplacementEvent(chain),
                                       BroadcastConfig(internal=True))

        return chain
Beispiel #4
0
def test_blockchain_fixtures(fixture_data, fixture):
    try:
        chain = new_chain_from_fixture(fixture)
    except ValueError as e:
        raise AssertionError(f"could not load chain for {fixture_data}") from e

    genesis_fields = genesis_fields_from_fixture(fixture)

    genesis_block = chain.get_canonical_block_by_number(0)
    genesis_header = genesis_block.header

    # Validate the genesis header RLP against the generated header
    if 'genesisRLP' in fixture:
        # Super hacky, but better than nothing: extract the header, then re-decode it
        fixture_decoded_block = rlp.decode(fixture['genesisRLP'])
        fixture_encoded_header = rlp.encode(fixture_decoded_block[0])
        fixture_header = rlp.decode(fixture_encoded_header, sedes=HeaderSedes)
        # Error message with pretty output if header doesn't match
        assert_headers_eq(fixture_header, genesis_header)
        # Last gut check that transactions & receipts are valid, too
        assert rlp.encode(genesis_block) == fixture['genesisRLP']

    assert_imported_genesis_header_unchanged(genesis_fields, genesis_header)

    # 1 - mine the genesis block
    # 2 - loop over blocks:
    #     - apply transactions
    #     - mine block
    # 3 - diff resulting state with expected state
    # 4 - check that all previous blocks were valid

    for block_fixture in fixture['blocks']:
        should_be_good_block = 'expectException' not in block_fixture

        if 'rlp_error' in block_fixture:
            assert not should_be_good_block
            continue

        if should_be_good_block:
            (original_block, executed_block,
             block_rlp) = apply_fixture_block_to_chain(
                 block_fixture,
                 chain,
                 perform_validation=False  # we manually validate below
             )
            assert_mined_block_unchanged(original_block, executed_block)
            chain.validate_block(original_block)
        else:
            try:
                apply_fixture_block_to_chain(block_fixture, chain)
            except EXPECTED_BAD_BLOCK_EXCEPTIONS:
                # failure is expected on this bad block
                pass
            else:
                raise AssertionError(
                    "Block should have caused a validation error")

    latest_block_hash = chain.get_canonical_block_by_number(
        chain.get_block().number - 1).hash
    if latest_block_hash != fixture['lastblockhash']:
        verify_state(fixture['postState'], chain.get_vm().state)