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

Initial p2p sync implementation #1674

Merged
merged 10 commits into from
Jan 25, 2024
Merged

Initial p2p sync implementation #1674

merged 10 commits into from
Jan 25, 2024

Conversation

Mirko-von-Leipzig
Copy link
Contributor

@Mirko-von-Leipzig Mirko-von-Leipzig commented Jan 12, 2024

Initial stab at a p2p sync implementation. This only implements the header sync portion and is not yet connected to the binary at all.

Note

This has changed significantly from the original demo. The original used tasks connected via channels whereas this new design uses streams and stream adapters which I think is much easier to read.

Design

The driving idea is that we can speed up disk IO by only syncing one type of data at a time e.g. only block headers, then transaction data etc. This has the additional advantage of keeping processing simple since much less needs to be done by a single process.

This PR implements the sync skeleton and then the header sync portion of it.

Nomenclature

I use two "definitions" throughout the code and comments:

  1. checkpoint An L1 starknet checkpoint aka EthereumStateUpdate
  2. anchor The latest checkpoint used locally for sync purposes. This acts as an "anchor" for the rest of the sync process.

Design

To keep things simple and easy to reason about, but also secure, the sync process will only consider blocks that are secured by L1. This enables the following algorithm:

  1. Fetch the latest checkpoint from L1.
  2. Clean up any local data that is invalidated by the new checkpoint.
  3. Sync headers in reverse chronological order from checkpoint to genesis. Since we use the checkpoint as a known anchor position, and sync in reverse we can guarantee the security of the synced headers.
  4. Sync the rest of the data in chronological order, using the headers for security.

Data is also persisted to disk in chunks.

Known issues

This only syncs up to the latest L1 checkpoint, so this might leave a rather large gap of unsynced blocks still. I don't think we should worry about that at this stage. I prefer having a more secure sync, supplemented by using a non-sync approach for the rest. Ideally the gap would be small enough that we can reach the tip of L2 from the L1 checkpoint in one swoop.

There is a missing loop, which should repeat the overall sync procedure as after the first iteration we will again be behind the next L1 checkpoint. But that's easy to add.

RPC will be dodgy while this sync happens, but I think that's fine.

We need to be careful about any storage invariants we may break during sync. But if we find any such cases, we should prefer adjusting storage instead of malforming p2p sync to fit it.

Current status

  • header sync PoC skeleton
  • header sync details
  • body sync
  • optimisations (only in the final iteration)

However I think to keep the PR manageable this is a good place to stop for now.

Comment on lines 94 to 139
pub fn next_ancestor(
&self,
block: BlockNumber,
) -> anyhow::Result<Option<(BlockNumber, BlockHash)>> {
block::next_ancestor(self, block)
}

pub fn next_ancestor_without_parent(
&self,
block: BlockNumber,
) -> anyhow::Result<Option<(BlockNumber, BlockHash)>> {
block::next_ancestor_without_parent(self, block)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better names for these would be appreciated.

Copy link
Member

@CHr15F0x CHr15F0x left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like where this is heading 👍

@Mirko-von-Leipzig Mirko-von-Leipzig force-pushed the mirko/p2p-sync-demo branch 4 times, most recently from b19c3b2 to 62d7cb5 Compare January 22, 2024 11:52
@Mirko-von-Leipzig Mirko-von-Leipzig force-pushed the mirko/p2p-sync-demo branch 2 times, most recently from d18d373 to 109796b Compare January 24, 2024 11:02
@Mirko-von-Leipzig Mirko-von-Leipzig force-pushed the mirko/p2p-sync-demo branch 2 times, most recently from 7a97fc8 to 9287d1d Compare January 24, 2024 11:25
@Mirko-von-Leipzig Mirko-von-Leipzig changed the title wip: p2p sync demo Intial p2p sync implementation Jan 24, 2024
@Mirko-von-Leipzig Mirko-von-Leipzig marked this pull request as ready for review January 24, 2024 11:35
@Mirko-von-Leipzig Mirko-von-Leipzig requested a review from a team as a code owner January 24, 2024 11:35
Comment on lines 188 to 192
Direction::Backward => start.parent().unwrap_or_default(),
};


yield PeerData::new(peer, signed_header);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting nit

Suggested change
Direction::Backward => start.parent().unwrap_or_default(),
};
yield PeerData::new(peer, signed_header);
Direction::Backward => start.parent().unwrap_or_default(),
};
yield PeerData::new(peer, signed_header);

Comment on lines 135 to 136
/// Performs [analysis](Self::analyse) of the [LocalState] by comparing it with a given L1 checkpoint, and
/// and [handles](Self::handle) the result.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo nit

Suggested change
/// Performs [analysis](Self::analyse) of the [LocalState] by comparing it with a given L1 checkpoint, and
/// and [handles](Self::handle) the result.
/// Performs [analysis](Self::analyse) of the [LocalState] by comparing it with a given L1 checkpoint,
/// and [handles](Self::handle) the result.

@Mirko-von-Leipzig Mirko-von-Leipzig changed the title Intial p2p sync implementation Initial p2p sync implementation Jan 24, 2024
@Mirko-von-Leipzig Mirko-von-Leipzig merged commit 47e209a into main Jan 25, 2024
7 checks passed
@Mirko-von-Leipzig Mirko-von-Leipzig deleted the mirko/p2p-sync-demo branch January 25, 2024 09:01
Co-authored-by: Nikša Sporin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants