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

fix(katana): prevent from resending messages to L1 #2354

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

ybensacq
Copy link
Contributor

@ybensacq ybensacq commented Aug 28, 2024

Description

  1. add gather_from_block to genesis file
  2. persist send_from_block & gather_from_block in database
  3. service use send_from_block & gather_from_block in messaging service

Related issue

Fixes #2033

Tests

  • Yes
  • No, because they aren't needed
  • No, because I need help

Added to documentation?

  • README.md
  • Dojo Book
  • No documentation needed

Checklist

  • I've formatted my code (scripts/prettier.sh, scripts/rust_fmt.sh, scripts/cairo_fmt.sh)
  • I've linted my code (scripts/clippy.sh, scripts/docs.sh)
  • I've commented my code
  • I've requested a review after addressing the comments

Summary by CodeRabbit

  • New Features

    • Introduced a new MessagingProvider trait to manage messaging operations across various providers.
    • Added gather_from_block field to Genesis and GenesisJson configurations, enabling specific block number tracking.
    • Enhanced DbProvider and ForkedProvider to manage messaging-related block numbers with new methods.
    • Updated CacheDb to include messaging information storage.
  • Bug Fixes

    • Improved error message formatting for better readability in ProviderError.
  • Documentation

    • Enhanced documentation strings for better clarity and readability in the Migrate command description.

Copy link

coderabbitai bot commented Aug 28, 2024

Walkthrough

The changes introduce a new MessagingProvider trait and its implementations across various provider structures within the Katana project. This enhancement allows for better management of messaging-related functionalities, specifically block numbers for sending and gathering messages. Additionally, existing structures and enums are updated to incorporate new fields and methods, improving the overall messaging capabilities of the system.

Changes

Files Change Summary
bin/sozo/src/commands/mod.rs Reformatted documentation string for the Migrate command to improve readability.
crates/dojo-lang/src/inline_macros/get.rs Modified formatting in GetMacro implementation for better readability without changing logic.
crates/katana/core/src/backend/storage.rs Added MessagingProvider trait dependency to Database trait, enhancing its capabilities.
crates/katana/core/src/service/messaging/service.rs Updated MessagingService initialization logic for dynamic block number retrieval and improved error handling.
crates/katana/primitives/src/genesis/json.rs Introduced gather_from_block field in GenesisJson struct and updated conversion and tests accordingly.
crates/katana/primitives/src/genesis/mod.rs Added gather_from_block field to Genesis struct and updated default implementation and tests.
crates/katana/storage/db/src/tables.rs Increased NUM_TABLES from 23 to 24 and added MessagingInfo table to database schema.
crates/katana/storage/provider/src/error.rs Reformatted error message for MissingContractNonceChangeEntry variant in ProviderError enum for improved readability.
crates/katana/storage/provider/src/lib.rs Implemented MessagingProvider trait for BlockchainProvider<Db>, adding methods for block number management.
crates/katana/storage/provider/src/providers/db/mod.rs Implemented MessagingProvider for DbProvider, adding methods for handling messaging-related block numbers.
crates/katana/storage/provider/src/providers/fork/mod.rs Implemented MessagingProvider for ForkedProvider, adding messaging-related methods.
crates/katana/storage/provider/src/providers/in_memory/cache.rs Added messaging_info field to CacheDb struct to store messaging-related information.
crates/katana/storage/provider/src/providers/in_memory/mod.rs Implemented MessagingProvider for InMemoryProvider, adding methods for block number management.
crates/katana/storage/provider/src/traits/messaging.rs Introduced MessagingProvider trait defining methods for block number management in messaging operations.
crates/katana/storage/provider/src/traits/mod.rs Added new messaging module to organize messaging-related traits.

Assessment against linked issues

Objective Addressed Explanation
Previous Messages Resent to L1 on Katana Restart (#2033) The changes do not explicitly address message persistence between restarts.

🐇 In the meadow, hopping with glee,
New messages dance, as happy as can be!
With blocks in a row, they gather and send,
In Katana's heart, where messages blend.
A tale of new traits, oh what a delight,
In the world of blockchain, they sparkle so bright! 🌼✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@ybensacq ybensacq marked this pull request as draft August 28, 2024 14:43
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 94e4508 and 3d4f790.

Files selected for processing (15)
  • bin/sozo/src/commands/mod.rs (1 hunks)
  • crates/dojo-lang/src/inline_macros/get.rs (1 hunks)
  • crates/katana/core/src/backend/storage.rs (3 hunks)
  • crates/katana/core/src/service/messaging/service.rs (5 hunks)
  • crates/katana/primitives/src/genesis/json.rs (4 hunks)
  • crates/katana/primitives/src/genesis/mod.rs (3 hunks)
  • crates/katana/storage/db/src/tables.rs (5 hunks)
  • crates/katana/storage/provider/src/error.rs (1 hunks)
  • crates/katana/storage/provider/src/lib.rs (2 hunks)
  • crates/katana/storage/provider/src/providers/db/mod.rs (2 hunks)
  • crates/katana/storage/provider/src/providers/fork/mod.rs (2 hunks)
  • crates/katana/storage/provider/src/providers/in_memory/cache.rs (2 hunks)
  • crates/katana/storage/provider/src/providers/in_memory/mod.rs (2 hunks)
  • crates/katana/storage/provider/src/traits/messaging.rs (1 hunks)
  • crates/katana/storage/provider/src/traits/mod.rs (1 hunks)
Files skipped from review due to trivial changes (3)
  • bin/sozo/src/commands/mod.rs
  • crates/dojo-lang/src/inline_macros/get.rs
  • crates/katana/storage/provider/src/error.rs
Additional comments not posted (36)
crates/katana/storage/provider/src/traits/mod.rs (1)

4-4: LGTM!

The addition of the messaging module enhances the modular design of the codebase.

The code changes are approved.

crates/katana/storage/provider/src/traits/messaging.rs (4)

1-2: LGTM!

The import of BlockNumber is appropriate and necessary for the trait methods.

The code changes are approved.


3-4: LGTM!

The import of ProviderResult is appropriate and necessary for the trait methods.

The code changes are approved.


5-6: LGTM!

The constants SEND_FROM_BLOCK_KEY and GATHER_FROM_BLOCK_KEY are well-defined and appropriately named.

The code changes are approved.


8-18: LGTM!

The MessagingProvider trait is well-defined with appropriate methods for setting and getting block numbers. The use of auto_impl is a good practice for flexibility.

The code changes are approved.

crates/katana/storage/provider/src/providers/in_memory/cache.rs (2)

88-88: LGTM!

The addition of the messaging_info field enhances the data structure by allowing it to store additional messaging-related information associated with block numbers.

The code changes are approved.


121-121: LGTM!

The initialization of the messaging_info field with a default value ensures that the field is properly set up during the instantiation of the struct.

The code changes are approved.

crates/katana/storage/provider/src/lib.rs (5)

19-19: LGTM!

The import of MessagingProvider is necessary for the implementation.

The code changes are approved.


384-387: LGTM!

The implementation of MessagingProvider for BlockchainProvider<Db> is necessary to integrate messaging capabilities.

The code changes are approved.


388-390: LGTM!

The get_send_from_block method correctly delegates the call to the underlying provider.

The code changes are approved.


392-394: LGTM!

The set_send_from_block method correctly delegates the call to the underlying provider.

The code changes are approved.


396-402: LGTM!

The get_gather_from_block and set_gather_from_block methods correctly delegate the calls to the underlying provider.

The code changes are approved.

crates/katana/core/src/backend/storage.rs (2)

12-12: LGTM!

The addition of MessagingProvider to the Database trait is necessary to ensure that any type implementing Database also implements MessagingProvider.

The code changes are approved.

Also applies to: 35-35


56-56: LGTM!

The addition of MessagingProvider to the implementation of Database for generic types is necessary to ensure that all types conforming to Database also adhere to the MessagingProvider requirement.

The code changes are approved.

crates/katana/core/src/service/messaging/service.rs (3)

12-12: LGTM!

The import of MessagingProvider is necessary for the modifications in the MessagingService implementation.

The code changes are approved.


50-70: LGTM!

The retrieval of gather_from_block and send_from_block from the provider, along with the error handling, ensures that the messaging service operates with the correct block numbers and fails fast in case of misconfiguration.

The code changes are approved.


225-229: LGTM!

The calls to set_gather_from_block and set_send_from_block ensure that the provider is updated with the latest block numbers, improving synchronization between the messaging service and the blockchain.

The code changes are approved.

Also applies to: 255-256

crates/katana/storage/db/src/tables.rs (4)

47-47: LGTM!

The NUM_TABLES constant is correctly updated to reflect the addition of a new table.

The code changes are approved.


170-171: LGTM!

The MessagingInfo table is correctly added to the define_tables_enum! macro.

The code changes are approved.


229-230: LGTM!

The MessagingInfo table is correctly added to the tables! macro.

The code changes are approved.


264-264: LGTM!

The test module is correctly updated to include assertions for the MessagingInfo table.

The code changes are approved.

Also applies to: 289-289

crates/katana/storage/provider/src/providers/in_memory/mod.rs (3)

29-29: LGTM!

The MessagingProvider trait and related constants are correctly imported.

The code changes are approved.


571-571: LGTM!

The MessagingProvider trait is correctly implemented for InMemoryProvider.

The code changes are approved.


572-589: LGTM!

The methods to get and set send_from_block and gather_from_block are correctly implemented.

The code changes are approved.

crates/katana/storage/provider/src/providers/fork/mod.rs (3)

33-33: LGTM!

The MessagingProvider trait is correctly imported.

The code changes are approved.


577-577: LGTM!

The MessagingProvider trait is correctly implemented for ForkedProvider.

The code changes are approved.


578-593: LGTM!

The methods to get and set send_from_block and gather_from_block are correctly implemented.

The code changes are approved.

crates/katana/primitives/src/genesis/mod.rs (3)

103-104: LGTM!

The addition of the gather_from_block field enhances the functionality of the Genesis struct by enabling it to track the specific block for message retrieval.

The code changes are approved.


300-300: LGTM!

The update to the Default implementation ensures that any instance of Genesis created using the default constructor will have a defined starting point for message gathering.

The code changes are approved.


416-416: LGTM!

The update to the test module ensures that the new gather_from_block field is accounted for in both the default behavior and the testing scenarios, thereby maintaining consistency across the implementation.

The code changes are approved.

crates/katana/storage/provider/src/providers/db/mod.rs (4)

750-750: LGTM!

The implementation of the MessagingProvider trait allows the DbProvider to manage messaging-related functionalities, enhancing its role in the broader application architecture.

The code changes are approved.


751-756: LGTM!

The get_send_from_block method correctly retrieves the block number associated with the SEND_FROM_BLOCK_KEY from the database transaction, ensuring proper transaction handling with commit operations.

The code changes are approved.


758-763: LGTM!

The set_send_from_block method correctly updates the database with a new block number for the SEND_FROM_BLOCK_KEY, encapsulated in a closure that manages the database transaction.

The code changes are approved.


765-777: LGTM!

The get_gather_from_block and set_gather_from_block methods correctly handle the retrieval and updating of the block number for the GATHER_FROM_BLOCK_KEY in the database, ensuring proper transaction handling with commit operations.

The code changes are approved.

crates/katana/primitives/src/genesis/json.rs (2)

219-219: LGTM!

The gather_from_block field is correctly added to the GenesisJson struct.

The code changes are approved.


476-476: LGTM!

The gather_from_block field is correctly added to the impl TryFrom<GenesisJson> for Genesis.

The code changes are approved.

Copy link
Collaborator

@glihm glihm left a comment

Choose a reason for hiding this comment

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

Thanks for the work here @ybensacq!

As mentioned, if it's possible to have the max_block and the chunk_size in the config, that would be perfect. :)

Ok(Some(block)) => block,
Ok(None) => 0,
Err(_) => {
panic!(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Prefer an error instead of panicking for all the one present in this function, and instead propagate in the new to ensure error is correctly displayed.

Comment on lines 384 to 428
impl<Db> MessagingProvider for BlockchainProvider<Db>
where
Db: MessagingProvider,
{
fn get_send_from_block(&self) -> ProviderResult<Option<BlockNumber>> {
self.provider.get_send_from_block()
}

fn set_send_from_block(&self, send_from_block: BlockNumber) -> ProviderResult<()> {
self.provider.set_send_from_block(send_from_block)
}

fn get_gather_from_block(&self) -> ProviderResult<Option<BlockNumber>> {
self.provider.get_gather_from_block()
}

fn set_gather_from_block(&self, gather_from_block: BlockNumber) -> ProviderResult<()> {
self.provider.set_gather_from_block(gather_from_block)
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

As seen, we should also keep track of a pointer on the message.
L1->L2, we can use the nonce of the message.
L2->L1, let's use the index of the message in the block as they are always ordered.

Copy link
Member

@kariy kariy left a comment

Choose a reason for hiding this comment

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

hey @ybensacq thanks for the contribution. sorry for the late review.

mostly looks good, but i left some comments mostly about some conventions that we should use.

Comment on lines 5 to 6
pub const SEND_FROM_BLOCK_KEY: u64 = 1;
pub const GATHER_FROM_BLOCK_KEY: u64 = 2;
Copy link
Member

Choose a reason for hiding this comment

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

lets remove this. the provider traits are meant to abstract how data are stored in the underlying storage so it doesn't make sense for these values to be presented here. anyway, we don need to use this for in-memory db. this make sense for on-disk db but for in-memory db, a simple struct that stores both values is more than enough.

so lets move this value to the db crate instead. i would also prefer to represent the keys as enum instead.

enum MessagingCheckpointId {
   Send,
   Gather
}

and implement the Encode and Decode traits for it.

pub const GATHER_FROM_BLOCK_KEY: u64 = 2;

#[auto_impl::auto_impl(&, Box, Arc)]
pub trait MessagingProvider: Send + Sync {
Copy link
Member

Choose a reason for hiding this comment

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

better to have more descriptive name

Suggested change
pub trait MessagingProvider: Send + Sync {
pub trait MessagingCheckpointProvider: Send + Sync {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

Comment on lines 577 to 632
impl MessagingProvider for ForkedProvider {
fn get_send_from_block(&self) -> ProviderResult<Option<BlockNumber>> {
Ok(None)
}

fn set_send_from_block(&self, _send_from_block: BlockNumber) -> ProviderResult<()> {
Ok(())
}

fn get_gather_from_block(&self) -> ProviderResult<Option<BlockNumber>> {
Ok(None)
}

fn set_gather_from_block(&self, _gather_from_block: BlockNumber) -> ProviderResult<()> {
Ok(())
}
}
Copy link
Member

Choose a reason for hiding this comment

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

ForkedProvider use the same underlying struct as InMemoryProvider. so can just copy what we did for InMemoryProvider

Copy link
Contributor Author

Choose a reason for hiding this comment

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

right!

@@ -85,6 +85,7 @@ pub struct CacheDb<Db> {
pub(crate) transaction_hashes: HashMap<TxNumber, TxHash>,
pub(crate) transaction_numbers: HashMap<TxHash, TxNumber>,
pub(crate) transaction_block: HashMap<TxNumber, BlockNumber>,
pub(crate) messaging_info: HashMap<u64, BlockNumber>,
Copy link
Member

Choose a reason for hiding this comment

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

replace map with just struct

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep done.

@@ -216,6 +216,7 @@ pub struct GenesisJson {
pub accounts: HashMap<ContractAddress, GenesisAccountJson>,
#[serde(default)]
pub contracts: HashMap<ContractAddress, GenesisContractJson>,
pub gather_from_block: BlockNumber,
Copy link
Member

Choose a reason for hiding this comment

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

i think the genesis is determined by the smart contract in the underlying settlement layer, it also indicates the minimum starting point of when messages should be collected from. so it's more appropriate to rename this field into something like settlement_block_number which implicitly tells the messaging task to start fetching the messages starting from this block number of the L1.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sure

@@ -100,6 +100,8 @@ pub struct Genesis {
pub universal_deployer: Option<UniversalDeployerConfig>,
/// The genesis contract allocations.
pub allocations: BTreeMap<ContractAddress, GenesisAllocation>,
/// The block on settlement chain from where Katana will start fetching messages.
pub gather_from_block: BlockNumber,
Copy link
Member

Choose a reason for hiding this comment

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

refer to comment on the genesis json.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok


/// Stores the block number related to messaging service
MessagingInfo: (u64) => BlockNumber
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
MessagingInfo: (u64) => BlockNumber
MessagingCheckpoint: (MessagingCheckpointId) => BlockNumber

refer to comment below

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@ybensacq ybensacq force-pushed the feat-prevent-resending-message branch from 4f19ab6 to fe2c75b Compare September 19, 2024 17:47
Copy link
Collaborator

@glihm glihm left a comment

Choose a reason for hiding this comment

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

Thanks for the work here @ybensacq and sorry for the delay on my end.

Do you see a simple way to add some testing here? Testing messages are not sent twice with an anvil or a katana as base layer could be great.

You may actually check the e2e testing, where we could have Katana being stopped and restarted, verifying that no messages are actually processed?

Comment on lines 321 to 330
// get stored nonce from message hash
let message_hash_bytes = l1_tx.message_hash;
let message_hash_bytes: [u8; 32] = *message_hash_bytes;

let message_hash = Felt::from_bytes_be(&message_hash_bytes);
match provider.get_nonce_from_message_hash(message_hash) {
Ok(Some(nonce)) => provider.set_gather_message_nonce(nonce),
Ok(None) => Ok(()),
Err(_e) => Ok(()),
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's move that into a function taking the l1_tx as input. Maybe into the provider directly. Since we're calling provider several time, internalizing the process and having only one function here would make it simpler and easier to test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@glihm ok :-)

@@ -763,6 +763,78 @@ impl<Db: Database> BlockWriter for DbProvider<Db> {
}
}

impl MessagingCheckpointProvider for DbProvider {
fn set_send_from_block(&self, send_from_block: BlockNumber) -> ProviderResult<()> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wasn't those methods renamed from @kariy comments?

When I initially did the messaging, I guess the naming wasn't that good. May need a future rework.

In the meantime, for the function you add, we may attempt a better naming.
The gather is getting messaging from settlement layer and processing them.
The send is sending messaging from katana to the settlement layout.

Concept of inbound, outbound could match well. inbound is from settlement layer to current layer. And outbound is from current layer to settlement layer.

Or we could add the concept of settlement here too. Maybe easier:
set_settlement_block
set_sequencer_block <- this one referencing the katana one?

But maybe inbound and outbound would work nicely.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@glihm ok

@glihm glihm added katana This issue is related to Katana contributor labels Nov 7, 2024
@glihm glihm changed the title feat(messaging): prevent from resending messages to L1 feat(katana): prevent from resending messages to L1 Nov 14, 2024
@glihm glihm changed the title feat(katana): prevent from resending messages to L1 fix(katana): prevent from resending messages to L1 Nov 14, 2024
@glihm
Copy link
Collaborator

glihm commented Dec 9, 2024

@ybensacq gm sensei, if you don't have the bandwidth, don't hesitate to mention it and will take over. 🫡 Thanks for the work already done on that!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contributor katana This issue is related to Katana
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Previous Messages Resent to L1 on Katana Restart
3 participants