Description
As agreed upon within the team we want to start with implementing a full sync mechanism before going over to something more sophisticated (like e.g. beam sync, see #992), since full sync is the most simple and purist way of syncing and getting to a recent network state.
For a full sync overview see e.g. Ethhub, we will likely want to have some differentiated look at the several properties and will likely not just implement everything down on first round (respectively, also one possibility: ever) but concentrate on the properties we want to prioritize.
Note that this won't be mainnet
ready implementation - minimally on first round - but it is rather targeted to be ready for some more lightweight testnets as well as serve simulation, test and development purposes.
Here is some checklist for a first round on what might be the tasks (it's always really helpful to have a look at our diagram to see how things work together):
1. Syncing the blockchain
- Subclass of sync/sync.ts, I wonder if we have anything
fast
sync related already in the code (needs some investigation or evidence) and if we should simply repurpose (respectively eventually just: "rename") e.g. FastSynchronizer ->FullSynchronizer
, alternative ways of integration respectively inheritance hierarchies, TBD by the sync method properties, needs a more close look into the implemented methods:- Synchronizer -> FullSynchronizer
- Synchronizer -> FastSynchronizer -> FullSynchronizer
- Synchronizer -> FullSynchronizer -> FastSynchronizer
2. Storing received blocks
- This is already done in the BlockFetcher I would say
3. Block validation
- Consistency: Turn on
validateBLocks
(always? triggered by sync mode choice?) on chain creation? - Consensus: the
validateConsensus
(old:validatePow
) option, leave for PoW for now for performance reasons? Prioritization question on PoA, is a PoA implementation needed right now (what happens if left out on a relatively intimate network like the Yolo network?)
4. Block verification
I'll take this as: verify the block hash by running the VM, correct me if this is the wrong semantics), on some thought this might be really relatively simple for now, my suggestion:
- Add
vm
option to Config, initialize with defaultv5
VM
if no VM passed in (I think it's attractive to do this exposure early on, not much extra cost and then people can directly start playing with their own customized/modfied VM instances) - Add VM execution either in the
BlockFetcher
(e.g. store()) or - maybe better - along thefetched
event in the synchronizer - Question: does this need an extra
vm.ts
orBlockVerifier.ts
wrapper (I didn't get the suggestion:client.ts
TBH) or is directly executing on the VM enough for now? - I guess if block verification fails (so this for sure means: there is a consensus bug, right?) I think a respective error should be propagated as an event or channeled through the existing event pipeline and the block synchronization should halt and an error message should be displayed?
5. Serving the network
Serving already synced data to other peers to be a good network citizen 😄
- Handled in FastEthereumService, not sure on the state there (what is already supported? what needs to be supported minimally?)
Phew, also not un-complex, I would say on first round. But doable. 😄
That's a summary of my current view on this as some basis for further reflection, discussion and implementation. We might want to open dedicated issues on single items if things get too complex and keep this as a tracking issue. But let's see how things evolve.