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
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sept-en
suggested changes
Jul 31, 2022
sept-en
changed the title
Eth2 to Near Relay prototype
Jul 31, 2022
Eth2-to-Near-relay
: prototype implementation
sept-en
changed the title
Eth2-to-Near-relay: prototype implementation
Jul 31, 2022
Eth2-to-Near-relay
: prototype implementation
karim-en
reviewed
Jul 31, 2022
karim-en
approved these changes
Jul 31, 2022
sept-en
approved these changes
Jul 31, 2022
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Eth2 to Near Relay prototype
Changes
eth2-to-near-relay
;eth-types
: remove redundant feature flags onserde::Serialize
implementationGeneral 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 useclap
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 createEthClientContract
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
: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:
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:
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
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!
andwarn!
we addtarget: "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.