Relayer

Functionalities expected from Relayer:

Validity, finality and synchronization

With Ethereum's The Merge coming in few months we are gaining finality of blocks in ethereum after two epochs, epoch contains 32 slots, slot takes 12s so epoch is around 6,4min and two epochs are 12.8min, so after 13min we are sure that our deposits will not be reverted by some big reorganization. So we are okay to say that everything older then ~100blocks are finalized.

Second finality that we have is related to fuel block attestation time limit, how long are we going to wait until challenge comes. It should be at least longer than ethereum finality. Not relevant for first version.

Example of sliding window: Sliding Window

There are few rules that da_height (da as data availability) need to follow and can be enforced with v2 contract:

In most cases for fuel block da_height can be calculated as current_da_height-1

Validator related stake

Validator stake is deposited on Ethereum contract side.

When deposit happens and finality period passes, stakes are included in validator set.

Delegation: ...

Bridge

Bridging is currently WIP and it is moving as generalizes messages between smart contract gateway.

Implementation

Info about fuel-relayer structure:

Log mod contains type casting from eth log to event that we can digest. bin/testrun.rs is simple run with DummyDb for manual testing.

Communication channels that we have:

On the database side we have:

And some DB variables:

For fetching logs from contract use ethers-rs to fetch data and be consistent what exactly we are getting. We need to be sure that we are receiving/reading all logs from out contracts that we are watching.

Syncing flow

Tricky thing that can happen not so often is in initial synchronization. When do we start log subscription and when do we stop importing log from block. Initial sync is done as:

  1. sync from HardCoddedContractCreatingBlock to (BestEthBlock-EthFinalitySlider)
  2. sync overlap from LastIncludedEthBlock to BestEthBlock and save them in dequeue.
  3. Start listening to eth events
  4. Check if our LastIncludedEthBlock is same as BestEthBlock. If not the same, stop listening to events and do 2,3,4 steps again.
  5. Continue to active listen on eth events. and prune(commit to db) dequeue for older finalized events

To have validity of ValidatorSet we need to have logs from ethereum to reconstruct the set. So It does not matter for us if we start syncing to fuel network if we are not connected to eth client. And in case if fuel-bft ask for validator set of not yet synced relayer, we are going to return error. We probably need to have notification when relayer gets fully synced.

On active sync when initial sync is finished we are watching new eth events and new chained block: For log watch we are doing:

  1. Receive log event:
    1. if it is removal, append them into pending_removal vec
    2. if it is new event. Apply pendingremovalvec and add new event to dequeue.
  2. On new fuel block, check finality and commit changed to db.
    1. just to be sure introduce check of events by calling eth block logs. This is a double check just to be sure that we match with that is inside contract.

For passive sync we are using ethereum pubsub protocol to get logs event: https://geth.ethereum.org/docs/rpc/pubsub . Example of eth log from log subscription:

Block Commitments

When new fuel block is made it needs to be committed to ethereum network. For every block that we don't have fuel commit we try to do our best guess and send block that contracts can include, gaps in height will be discarded by contract.

There is timeframe of few eth blocks where current leader can broadcast block to ethereum network. In case that he do it in time he will receive additional reward. In case that leader does not commit fuel block next leader will have ability to do it for him as bundle block commit, in that case bonus reward will go to second leader that has spend additional gas to push this change to ethereum network. This is still WIP discussion.

Github discussion on fuel sync with L1: https://github.com/FuelLabs/fuel-specs/issues/285