示例#1
0
 def _load_or_create_node_key(self) -> KeyPair:
     if self.boot_info.args.beacon_nodekey:
         privkey = Secp256k1PrivateKey.new(
             decode_hex(self.boot_info.args.beacon_nodekey)
         )
         key_pair = KeyPair(private_key=privkey, public_key=privkey.get_public_key())
         return key_pair
     else:
         config = self.boot_info.trinity_config
         beacon_nodekey_path = f"{config.nodekey_path}-beacon"
         if os.path.isfile(beacon_nodekey_path):
             with open(beacon_nodekey_path, "rb") as f:
                 key_data = f.read()
             private_key = Secp256k1PrivateKey.new(key_data)
             key_pair = KeyPair(
                 private_key=private_key,
                 public_key=private_key.get_public_key()
             )
             return key_pair
         else:
             key_pair = create_new_key_pair()
             private_key_bytes = key_pair.private_key.to_bytes()
             with open(beacon_nodekey_path, "wb") as f:
                 f.write(private_key_bytes)
             return key_pair
示例#2
0
async def run(port: int,
              destination: str,
              localhost: bool,
              seed: int = None) -> None:
    if localhost:
        ip = "127.0.0.1"
    else:
        ip = urllib.request.urlopen("https://v4.ident.me/").read().decode(
            "utf8")
    transport_opt = f"/ip4/{ip}/tcp/{port}"

    if seed:
        import random

        random.seed(seed)
        secret_number = random.getrandbits(32 * 8)
        secret = secret_number.to_bytes(length=32, byteorder="big")
    else:
        import secrets

        secret = secrets.token_bytes(32)

    host = await new_node(key_pair=create_new_key_pair(secret),
                          transport_opt=[transport_opt])

    print(f"I am {host.get_id().to_string()}")

    await host.get_network().listen(multiaddr.Multiaddr(transport_opt))

    if not destination:  # its the server

        host.set_stream_handler(PROTOCOL_ID, _echo_stream_handler)

        localhost_opt = " --localhost" if localhost else ""

        print(
            f"Run 'python ./examples/echo/echo.py" + localhost_opt +
            f" -p {int(port) + 1} -d /ip4/{ip}/tcp/{port}/p2p/{host.get_id().pretty()}'"
            + " on another console.")
        print("Waiting for incoming connections...")

    else:  # its the client
        maddr = multiaddr.Multiaddr(destination)
        info = info_from_p2p_addr(maddr)
        # Associate the peer with local ip address
        await host.connect(info)

        # Start a stream with the destination.
        # Multiaddress of the destination peer is fetched from the peerstore using 'peerId'.
        stream = await host.new_stream(info.peer_id, [PROTOCOL_ID])

        msg = b"hi, there!\n"

        await stream.write(msg)
        # Notify the other side about EOF
        await stream.close()
        response = await stream.read()

        print(f"Sent: {msg}")
        print(f"Got: {response}")
示例#3
0
def test_public_key_serialize_deserialize_round_trip():
    key_pair = create_new_key_pair()
    public_key = key_pair.public_key

    public_key_bytes = public_key.serialize()
    another_public_key = deserialize_public_key(public_key_bytes)

    assert public_key == another_public_key
示例#4
0
async def run(port: int, destination: str, seed: int = None) -> None:
    localhost_ip = "127.0.0.1"
    listen_addr = multiaddr.Multiaddr(f"/ip4/0.0.0.0/tcp/{port}")

    if seed:
        import random

        random.seed(seed)
        secret_number = random.getrandbits(32 * 8)
        secret = secret_number.to_bytes(length=32, byteorder="big")
    else:
        import secrets

        secret = secrets.token_bytes(32)

    host = new_host(key_pair=create_new_key_pair(secret))
    async with host.run(listen_addrs=[listen_addr]):

        print(f"I am {host.get_id().to_string()}")

        if not destination:  # its the server

            host.set_stream_handler(PROTOCOL_ID, _echo_stream_handler)

            print(
                f"Run 'python ./examples/echo/echo.py "
                f"-p {int(port) + 1} "
                f"-d /ip4/{localhost_ip}/tcp/{port}/p2p/{host.get_id().pretty()}' "
                "on another console.")
            print("Waiting for incoming connections...")
            await trio.sleep_forever()

        else:  # its the client
            maddr = multiaddr.Multiaddr(destination)
            info = info_from_p2p_addr(maddr)
            # Associate the peer with local ip address
            await host.connect(info)

            # Start a stream with the destination.
            # Multiaddress of the destination peer is fetched from the peerstore using 'peerId'.
            stream = await host.new_stream(info.peer_id, [PROTOCOL_ID])

            msg = b"hi, there!\n"

            await stream.write(msg)
            # Notify the other side about EOF
            await stream.close()
            response = await stream.read()

            print(f"Sent: {msg}")
            print(f"Got: {response}")
示例#5
0
async def test_create_secure_session(nursery):
    local_nonce = b"\x01" * NONCE_SIZE
    local_key_pair = create_new_key_pair(b"a")
    local_peer = ID.from_pubkey(local_key_pair.public_key)

    remote_nonce = b"\x02" * NONCE_SIZE
    remote_key_pair = create_new_key_pair(b"b")
    remote_peer = ID.from_pubkey(remote_key_pair.public_key)

    async with raw_conn_factory(nursery) as conns:
        local_conn, remote_conn = conns

        local_secure_conn, remote_secure_conn = None, None

        async def local_create_secure_session():
            nonlocal local_secure_conn
            local_secure_conn = await create_secure_session(
                local_nonce,
                local_peer,
                local_key_pair.private_key,
                local_conn,
                remote_peer,
            )

        async def remote_create_secure_session():
            nonlocal remote_secure_conn
            remote_secure_conn = await create_secure_session(
                remote_nonce, remote_peer, remote_key_pair.private_key,
                remote_conn)

        async with trio.open_nursery() as nursery_1:
            nursery_1.start_soon(local_create_secure_session)
            nursery_1.start_soon(remote_create_secure_session)

        msg = b"abc"
        await local_secure_conn.write(msg)
        received_msg = await remote_secure_conn.read(MAX_READ_LEN)
        assert received_msg == msg
示例#6
0
async def libp2p_node(chain, event_bus):
    key_pair = create_new_key_pair()
    libp2p_node = Node(
        key_pair=key_pair,
        listen_ip="0.0.0.0",
        listen_port=40000,
        preferred_nodes=(),
        chain=chain,
        subnets=(),
        event_bus=event_bus,
    )
    asyncio.ensure_future(libp2p_node.run())
    await asyncio.sleep(0.01)
    return libp2p_node
示例#7
0
async def test_create_secure_session():
    local_nonce = b"\x01" * NONCE_SIZE
    local_key_pair = create_new_key_pair(b"a")
    local_peer = ID.from_pubkey(local_key_pair.public_key)

    remote_nonce = b"\x02" * NONCE_SIZE
    remote_key_pair = create_new_key_pair(b"b")
    remote_peer = ID.from_pubkey(remote_key_pair.public_key)

    local_conn = InMemoryConnection(local_peer, is_initiator=True)
    remote_conn = InMemoryConnection(remote_peer)

    local_pipe_task = asyncio.ensure_future(
        create_pipe(local_conn, remote_conn))
    remote_pipe_task = asyncio.ensure_future(
        create_pipe(remote_conn, local_conn))

    local_session_builder = create_secure_session(local_nonce, local_peer,
                                                  local_key_pair.private_key,
                                                  local_conn, remote_peer)
    remote_session_builder = create_secure_session(remote_nonce, remote_peer,
                                                   remote_key_pair.private_key,
                                                   remote_conn)
    local_secure_conn, remote_secure_conn = await asyncio.gather(
        local_session_builder, remote_session_builder)

    msg = b"abc"
    await local_secure_conn.write(msg)
    received_msg = await remote_secure_conn.read()
    assert received_msg == msg

    await asyncio.gather(local_secure_conn.close(), remote_secure_conn.close())

    local_pipe_task.cancel()
    remote_pipe_task.cancel()
    await local_pipe_task
    await remote_pipe_task
示例#8
0
    def __init__(
        self,
        local_node_key: PrivateKey,
        eth2_config: Eth2Config,
        chain_config: BeaconChainConfig,
        database_dir: Path,
        chain_class: Type[BaseBeaconChain],
        time_provider: TimeProvider = get_unix_time,
    ) -> None:
        self._local_key_pair = create_new_key_pair(local_node_key.to_bytes())
        self._eth2_config = eth2_config

        self._clock = _mk_clock(eth2_config, chain_config.genesis_time,
                                time_provider)

        self._base_db = LevelDB(db_path=database_dir)
        self._chain_db = BeaconChainDB(self._base_db, eth2_config)

        if not is_beacon_database_initialized(self._chain_db):
            initialize_beacon_database(chain_config, self._chain_db,
                                       self._base_db)

        self._chain = chain_class(self._base_db, eth2_config)
示例#9
0
    def do_start(self) -> None:
        trinity_config = self.boot_info.trinity_config
        beacon_app_config = trinity_config.get_app_config(BeaconAppConfig)
        base_db = DBClient.connect(trinity_config.database_ipc_path)
        chain_config = beacon_app_config.get_chain_config()
        attestation_pool = AttestationPool()
        chain = chain_config.beacon_chain_class(base_db, attestation_pool,
                                                chain_config.genesis_config)

        key_pair: KeyPair
        if self.boot_info.args.beacon_nodekey:
            privkey = Secp256k1PrivateKey(
                bytes.fromhex(self.boot_info.args.beacon_nodekey))
            key_pair = KeyPair(private_key=privkey,
                               public_key=privkey.get_public_key())
        else:
            key_pair = create_new_key_pair()

        # TODO: Handle `bootstrap_nodes`.
        libp2p_node = Node(
            key_pair=key_pair,
            listen_ip="127.0.0.1",  # FIXME: Should be configurable
            listen_port=self.boot_info.args.port,
            preferred_nodes=trinity_config.preferred_nodes,
            chain=chain,
        )

        state = chain.get_state_by_slot(
            chain_config.genesis_config.GENESIS_SLOT)
        registry_pubkeys = [v_record.pubkey for v_record in state.validators]

        validator_privkeys = {}
        validator_keymap = chain_config.genesis_data.validator_keymap
        for pubkey in validator_keymap:
            validator_index = cast(ValidatorIndex,
                                   registry_pubkeys.index(pubkey))
            validator_privkeys[validator_index] = validator_keymap[pubkey]

        def fake_get_ready_attestations_fn() -> Tuple[Attestation, ...]:
            return tuple()

        validator = Validator(
            chain=chain,
            p2p_node=libp2p_node,
            validator_privkeys=validator_privkeys,
            event_bus=self.event_bus,
            token=libp2p_node.cancel_token,
            get_ready_attestations_fn=
            fake_get_ready_attestations_fn,  # FIXME: BCCReceiveServer.get_ready_attestations  # noqa: E501
        )

        slot_ticker = SlotTicker(
            genesis_slot=chain_config.genesis_config.GENESIS_SLOT,
            genesis_time=chain_config.genesis_data.genesis_time,
            seconds_per_slot=chain_config.genesis_config.SECONDS_PER_SLOT,
            event_bus=self.event_bus,
            token=libp2p_node.cancel_token,
        )

        asyncio.ensure_future(
            exit_with_services(
                self._event_bus_service,
                libp2p_node,
                slot_ticker,
                validator,
            ))
        asyncio.ensure_future(libp2p_node.run())
        asyncio.ensure_future(slot_ticker.run())
        asyncio.ensure_future(validator.run())
示例#10
0
def node_key_pair(seed=b""):
    if isinstance(seed, str):
        seed = seed.encode()
    return create_new_key_pair(seed.rjust(32, b"\x00"))
示例#11
0
    def __init__(
        self,
        local_node_key: PrivateKey,
        eth2_config: Eth2Config,
        clock: Clock,
        chain: BaseBeaconChain,
        validator_api_port: int,
        client_identifier: str,
        p2p_maddr: Multiaddr,
        preferred_nodes: Collection[Multiaddr],
        bootstrap_nodes: Collection[Multiaddr],
    ) -> None:
        self._local_key_pair = create_new_key_pair(local_node_key.to_bytes())
        self._eth2_config = eth2_config

        self._clock = clock
        self._chain = chain

        self._block_pool: Set[SignedBeaconBlock] = set()
        self._slashable_block_pool: Set[SignedBeaconBlock] = set()

        # FIXME: can we provide `p2p_maddr` as a default listening interface for `_mk_host`?
        peer_id = PeerID.from_pubkey(self._local_key_pair.public_key)
        if "p2p" in p2p_maddr:
            existing_peer_id = p2p_maddr.value_for_protocol("p2p")
            existing_p2p_maddr = Multiaddr(f"/p2p/{existing_peer_id}")
            self.logger.warning(
                "peer identity derived from local key pair %s overriding given identity %s",
                peer_id,
                existing_peer_id,
            )
            p2p_maddr = p2p_maddr.decapsulate(existing_p2p_maddr)
        self._p2p_maddr = p2p_maddr.encapsulate(Multiaddr(f"/p2p/{peer_id}"))

        # TODO: persist metadata and handle updates...
        self._metadata_provider = lambda: MetaData.create()
        self._peer_updater, self._peer_updates = trio.open_memory_channel[
            Tuple[PeerID, Any]](0)
        self._host = Host(
            self._local_key_pair,
            peer_id,
            self._accept_peer_updates,
            self._get_status,
            self._get_finalized_root_by_epoch,
            self._get_block_by_slot,
            self._get_block_by_root,
            self._metadata_provider,
            self._get_fork_digest,
            self._eth2_config,
        )
        self._preferred_nodes = preferred_nodes
        self._bootstrap_nodes = bootstrap_nodes

        self._sync_notifier, self._sync_requests = trio.open_memory_channel[
            SyncRequest](0)
        self._syncer = _mk_syncer()

        api_context = Context(
            client_identifier,
            eth2_config,
            self._syncer,
            self._chain,
            self._clock,
            _mk_block_broadcaster(self),
        )
        self.validator_api_port = validator_api_port
        self._validator_api_server = _mk_validator_api_server(
            self.validator_api_port, api_context)
示例#12
0
def _load_secp256k1_key_pair_from(trinity_config: TrinityConfig) -> KeyPair:
    return create_new_key_pair(trinity_config.nodekey.to_bytes())