Esempio n. 1
0
def initialize_database(chain_config: Eth1ChainConfig,
                        chaindb: ChainDatabaseAPI,
                        base_db: AtomicDatabaseAPI) -> None:
    try:
        chaindb.get_canonical_head()
    except CanonicalHeadNotFound:
        chain_config.initialize_chain(base_db)
def test_chain_config_from_preconfigured_network(network_id):
    chain_config = Eth1ChainConfig.from_preconfigured_network(network_id)
    chain = chain_config.initialize_chain(AtomicDB(MemoryDB()))

    if network_id == MAINNET_NETWORK_ID:
        assert chain_config.chain_id == MainnetChain.chain_id
        assert_vm_configuration_equal(chain_config.vm_configuration, MainnetChain.vm_configuration)
        assert chain.get_canonical_head() == MAINNET_GENESIS_HEADER
    elif network_id == ROPSTEN_NETWORK_ID:
        assert chain_config.chain_id == RopstenChain.chain_id
        assert_vm_configuration_equal(chain_config.vm_configuration, RopstenChain.vm_configuration)
        assert chain.get_canonical_head() == ROPSTEN_GENESIS_HEADER
    else:
        raise AssertionError("Invariant: unreachable code path")
def test_chain_config_from_eip1085_genesis_config():
    chain_config = Eth1ChainConfig.from_eip1085_genesis_config(EIP1085_GENESIS_CONFIG)

    assert chain_config.chain_id == 1234
    assert len(chain_config.vm_configuration) == 1
    fork_block, fork_vm = chain_config.vm_configuration[0]
    assert fork_block == 0
    assert fork_vm.fork == 'constantinople'

    params = chain_config.genesis_params

    assert params.nonce == decode_hex(EIP1085_GENESIS_CONFIG['genesis']['nonce'])
    assert params.difficulty == to_int(hexstr=EIP1085_GENESIS_CONFIG['genesis']['difficulty'])
    assert params.coinbase == decode_hex(EIP1085_GENESIS_CONFIG['genesis']['author'])
    assert params.timestamp == to_int(hexstr=EIP1085_GENESIS_CONFIG['genesis']['timestamp'])
    assert params.extra_data == decode_hex(EIP1085_GENESIS_CONFIG['genesis']['extraData'])
    assert params.gas_limit == to_int(hexstr=EIP1085_GENESIS_CONFIG['genesis']['gasLimit'])
Esempio n. 4
0
async def _main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument('-db', type=str, required=True)
    parser.add_argument('-light', action="store_true")
    parser.add_argument('-nodekey', type=str)
    parser.add_argument('-enode',
                        type=str,
                        required=False,
                        help="The enode we should connect to")
    parser.add_argument('-debug', action="store_true")
    args = parser.parse_args()

    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s %(levelname)s: %(message)s',
                        datefmt='%H:%M:%S')
    log_level = logging.INFO
    if args.debug:
        log_level = logging.DEBUG

    loop = asyncio.get_event_loop()

    base_db = LevelDB(args.db)
    headerdb = AsyncHeaderDB(AtomicDB(base_db))
    chaindb = AsyncChainDB(AtomicDB(base_db))
    try:
        genesis = chaindb.get_canonical_block_header_by_number(BlockNumber(0))
    except HeaderNotFound:
        genesis = ROPSTEN_GENESIS_HEADER
        chaindb.persist_header(genesis)

    peer_pool_class: Type[Union[ETHPeerPool, LESPeerPool]] = ETHPeerPool
    if args.light:
        peer_pool_class = LESPeerPool

    if genesis.hash == ROPSTEN_GENESIS_HEADER.hash:
        chain_id = RopstenChain.chain_id
        vm_config = ROPSTEN_VM_CONFIGURATION
    elif genesis.hash == MAINNET_GENESIS_HEADER.hash:
        chain_id = MainnetChain.chain_id
        vm_config = MAINNET_VM_CONFIGURATION  # type: ignore
    else:
        raise RuntimeError("Unknown genesis: %s", genesis)

    if args.nodekey:
        privkey = load_nodekey(Path(args.nodekey))
    else:
        privkey = ecies.generate_privkey()

    chain_config = Eth1ChainConfig.from_preconfigured_network(chain_id)
    chain = chain_config.initialize_chain(base_db)
    context = ChainContext(
        headerdb=headerdb,
        network_id=chain_id,
        vm_configuration=vm_config,
        client_version_string=construct_trinity_client_identifier(),
        listen_port=30309,
        p2p_version=DEVP2P_V5,
    )

    peer_pool = peer_pool_class(privkey=privkey, context=context)

    if args.enode:
        nodes = tuple([Node.from_uri(args.enode)])
    else:
        nodes = DEFAULT_PREFERRED_NODES[chain_id]

    async with background_asyncio_service(peer_pool):
        await peer_pool.connect_to_nodes(nodes)
        assert len(peer_pool) == 1
        syncer: Service = None
        if args.light:
            syncer = LightChainSyncer(chain, headerdb,
                                      cast(LESPeerPool, peer_pool))
        else:
            syncer = RegularChainSyncer(chain, chaindb,
                                        cast(ETHPeerPool, peer_pool))
        logging.getLogger().setLevel(log_level)

        async with background_asyncio_service(syncer) as syncer_manager:
            for sig in [signal.SIGINT, signal.SIGTERM]:
                loop.add_signal_handler(sig, syncer_manager.cancel)

            await syncer_manager.wait_finished()
Esempio n. 5
0
async def test_sync_integration(request, caplog, geth_ipc_path, enode,
                                geth_process):
    """Test a regular chain sync against a running geth instance.

    In order to run this manually, you can use `tox -e py37-sync_integration` or:

        pytest --integration --capture=no tests/integration/test_sync.py

    The fixture for this test was generated with:

        geth --ropsten --syncmode full

    It only needs the first 11 blocks for this test to succeed.
    """
    if not request.config.getoption("--integration"):
        pytest.skip("Not asked to run integration tests")

    # will almost certainly want verbose logging in a failure
    caplog.set_level(logging.DEBUG)

    # make sure geth has been launched
    wait_for_socket(geth_ipc_path)

    remote = Node.from_uri(enode)
    base_db = AtomicDB()
    chaindb = AsyncChainDB(base_db)
    chaindb.persist_header(ROPSTEN_GENESIS_HEADER)
    headerdb = AsyncHeaderDB(base_db)
    chain_config = Eth1ChainConfig.from_preconfigured_network(
        ROPSTEN_NETWORK_ID)
    chain = chain_config.initialize_chain(base_db)
    context = ChainContext(
        headerdb=headerdb,
        network_id=ROPSTEN_NETWORK_ID,
        vm_configuration=ROPSTEN_VM_CONFIGURATION,
        client_version_string='trinity-test',
        listen_port=30303,
        p2p_version=DEVP2P_V5,
    )
    peer_pool = ETHPeerPool(privkey=ecies.generate_privkey(), context=context)
    syncer = RegularChainSyncer(chain, chaindb, peer_pool)

    async with background_asyncio_service(peer_pool) as manager:
        await manager.wait_started()
        await peer_pool.connect_to_nodes([remote])
        assert len(peer_pool) == 1

        async with background_asyncio_service(syncer) as syncer_manager:
            await syncer_manager.wait_started()

            n = 11

            manager.logger.info(f"Waiting for the chain to sync {n} blocks")

            async def wait_for_header_sync(block_number):
                while chaindb.get_canonical_head().block_number < block_number:
                    await asyncio.sleep(0.1)

            await asyncio.wait_for(wait_for_header_sync(n), 5)

            # https://ropsten.etherscan.io/block/11
            header = chaindb.get_canonical_block_header_by_number(n)
            transactions = chaindb.get_block_transactions(
                header, BaseTransactionFields)
            assert len(transactions) == 15

            receipts = chaindb.get_receipts(header, Receipt)
            assert len(receipts) == 15
            assert encode_hex(keccak(rlp.encode(receipts[0]))) == (
                '0xf709ed2c57efc18a1675e8c740f3294c9e2cb36ba7bb3b89d3ab4c8fef9d8860'
            )