Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eth2-to-Near-relay: prototype implementation #762

Merged
merged 98 commits into from Jul 31, 2022
Merged

Conversation

olga24912
Copy link
Contributor

@olga24912 olga24912 commented Jul 31, 2022

Eth2 to Near Relay prototype

Changes

  • Implemented eth2-to-near-relay;
  • eth-types: remove redundant feature flags on serde::Serialize implementation

General description

In this PR, a simple eth2 to near relay is implemented. This relay transfers from Eth to Near: (1) eth1 block header each slot, (2) finality light client updates each epoch, (3) sync_commite_update each period.

Relay CLI

File: main.rs
The point of entry for working with the relay. To get more information about the command line interface, you can run cargo run -- --help. For parsing command line arguments, we use clap crate.

Main logic

File: eth2near_relay.rs
Here you can find the main logic for the relay. Struct Eth2NearRelay contains two public methods: (1) init for Eth2NearRelay construction, and (2) run for execution. By design, the run method is infinity and takes block headers, and light client updates from Ethereum Block Chain and sends it to the Ethereum Light Client on NEAR. At each loop iteration, it (1) searches for the last known header on the ETH client on NEAR, (2) fetch and send a bunch of eth1 block headers, and (3) send, if necessary new light client update.

Eth on near client contract wrapper

File: eth_client_contract.rs, init_contract.rs
In the struct EthClientContract, we encapsulate interaction with Ethereum Light Client in NEAR. Maybe in the future makes sense to create EthClientContract trait and next implementations (1) DirectEthClientContract, (2) DAOEthClientContract, (3) FileEthClientContract. For now, it directly interacts with this version of the contract.

Public API of EthClientContract:

  • is_known_block -- check if this eth1 execution block hash is in the list of unfinalized blocks in the contract
  • send_light_client_update -- for sending light client update
  • get_finalized_beacon_block_hash -- for getting the beacon block hash of the last known finalized block on the contract
  • send_headers -- for sending the bunch of eth1_block_headers
  • register -- for registration of the current relay at the contract
  • init_contract -- for initializing the contract

For interaction with contract, we use near_jsonrpc_client crate. We have two methods for direct interaction with the contract: (1) call_change_method -- for sending a transaction to the change method on the contract, and (2) call_change_method -- for calling a view method.

Eth RPC API

Files: beacon_rpc_client.rs, eth1_rpc_client.rs

Eth1 API && Eth2 API

For getting Eth1 execution block headers, we should use eth1 API, and for getting Light Client Updates, we need beacon API. And such API is provided by different endpoints. So we need two different endpoints and two different clients:

  • beaconRPCClient -- for beacon API
  • Eth1RPCClient -- for eth1 API

Light client update API

BeaconRPCClient implemented a series of methods that gets LightClientUpdate from Light Client Server (full node with LightClient API).

For using it, the endpoint should provide Light Client API. Not all Beacon endpoints have such an API. Moreover, there can be many ambiguities with API. We use the API from lodestar (can be found here ).

For getting Light Client Update, we have next methods:

  • get_light_client_update -- this method returns LightClientUpdate for period. But it contains the best finality header, NOT THE LAST one.
  • get_finality_light_client_update -- this method returns LightClientUpdate with the last finality header but without sync commity.
  • get_finality_light_client_update_with_sync_commity_update -- it takes LightClientUpdate from get_finality_light_client_update and the sync commity from get_light_client_update

Current lodestar Light Client API is a little outdated and doesn't provide signature_slot. For getting signature_slot we brute force slots and compare SyncAggregation in BeconBlockBody and in LightClientUpdate.

In tests in BeaconRPCClient, you can find two ignored tests we use for printing LightClientUpdate JSON and JSON for Headers with Eth1Data in some range.

LightClientUpdate -- Json Serialization

Files: contracts/near/eth-types/eth2.rs, contracts/near/eth-types/macros.rs

To be able to save LightClientUpdate to a JSON file(for example, for testing) we also add serde JSON serialization for arrays similar to deserialization.

Execution block proof

Files: beacon_block_body_merkle_tree.rs, beacon_block_header_with_execution_data.rs, execution_block_proof.rs
IMG_20220712_170534

When we send light client update for finality block inside light client update, we also send Eth1 execution block hash with the Merkle proof of include to Beacon Block Body. Execution block hash you can find at BeaconBlockBody.execution_payload.block_hash.

So, for creating Merkle proof, we need two levels of Merkle Tree, as shown in the picture. Both Merkle trees you can find in beacon_block_body_merkle_tree.rs The first level Merkle tree for beacon block body and the second level Merkle tree for execution payload.

The execution block hash proof creation you can find in execution_block_proof.rs First, we build two Merkle trees and concatenate together the Merkle proof for block_hash in execution_payload and the Merkle proof of execution_payload in beacon_block_body. The final Merkle proof is shown by the orange vertices on the picture; the orange numbers in the picture are the order of hashes in the proof.

beacon_block_header_with_execution_data.rs contain a structure which consists of beacon_block_header and correspondent execution_block_hash with Merkle proof. This structure is created for finality blocks in a light client update.

Logging

Files: logger.rs

For logging, we use the log crate and just copy SimpleLogger with a small modification from this doc.

Currently, it just prints all logs in the console, but in the future, it can be improved to write it in the file as well.

We use two types of logging: info(for general message) and warn(if some error happens).

Also, In all info! and warn! we add target: "relay" for separating my logs message from messages inside libraries that we use.

For handling errors, we have two strategies:
(1) just unwrap the error at the beginning if the error occurs before we actually start the relay(during initialization, for example). In that case, we can just read the backtrace and restart the relay.
(2) write to log and try again for errors that happen during relays works.

@olga24912 olga24912 requested a review from sept-en as a code owner July 31, 2022 19:22
@sept-en sept-en requested a review from karim-en July 31, 2022 19:31
@sept-en sept-en added relayers rust Pull requests that update Rust code labels Jul 31, 2022
eth2near/contract_wrapper/src/eth_client_contract.rs Outdated Show resolved Hide resolved
eth2near/eth2near-block-relay-rs/src/eth2near_relay.rs Outdated Show resolved Hide resolved
eth2near/contract_wrapper/src/near_contract_wrapper.rs Outdated Show resolved Hide resolved
eth2near/eth2near-block-relay-rs/src/beacon_rpc_client.rs Outdated Show resolved Hide resolved
eth2near/eth2near-block-relay-rs/src/beacon_rpc_client.rs Outdated Show resolved Hide resolved
eth2near/eth2near-block-relay-rs/src/config.rs Outdated Show resolved Hide resolved
eth2near/finality-update-verify/Cargo.toml Outdated Show resolved Hide resolved
@sept-en sept-en changed the title Eth2 to Near Relay prototype Eth2-to-Near-relay: prototype implementation Jul 31, 2022
@sept-en sept-en changed the title Eth2-to-Near-relay: prototype implementation Eth2-to-Near-relay: prototype implementation Jul 31, 2022
@sept-en sept-en merged commit c2c4cf0 into the-merge Jul 31, 2022
@sept-en sept-en deleted the eth2-to-near-relay branch July 31, 2022 23:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
eth-the-merge relayers rust Pull requests that update Rust code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants