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

feat(client): l1<>l2 messaging crate #220

Merged
merged 33 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
738511c
init
azurwastaken Aug 7, 2024
c1d1b04
added message cancellation
azurwastaken Aug 7, 2024
b134120
feat: add tx hash
EvolveArt Aug 7, 2024
477da0b
feat: mix messaging and state update tasks
EvolveArt Aug 7, 2024
83beb35
fix: remove comment
EvolveArt Aug 7, 2024
ff94b53
added first draft of test
azurwastaken Aug 8, 2024
4fc73f8
started anvil from code added all 3 E2E tests, also changed state upd…
azurwastaken Aug 8, 2024
6df593c
refactored tests
azurwastaken Aug 9, 2024
f30b391
moved L1-Messaging part to eth crate
azurwastaken Aug 9, 2024
bc45a58
Update CHANGELOG.md
azurwastaken Aug 9, 2024
8f042fd
prettier
azurwastaken Aug 9, 2024
f40899f
remove crate from sync
azurwastaken Aug 9, 2024
d233f48
lint
azurwastaken Aug 9, 2024
8c16b6e
lint
azurwastaken Aug 9, 2024
c822517
fix tests, added description
azurwastaken Aug 12, 2024
3896174
fix: refacto test with fixture
EvolveArt Aug 12, 2024
e7af6d0
fix: l1 to l2 msg hash
EvolveArt Aug 12, 2024
cc32fc6
Merge branch 'main' into pr/220
EvolveArt Aug 12, 2024
fe549b7
fix: linter
EvolveArt Aug 12, 2024
ef76ea4
moved a comment and adding rustdoc
azurwastaken Aug 13, 2024
e83e7c6
fix doc and rename variable to be more clear
azurwastaken Aug 13, 2024
95da77a
fix: add nonce in its own column
EvolveArt Aug 14, 2024
6fae6b0
Merge branch 'main' into pr/220
EvolveArt Aug 14, 2024
3a3029b
updated column name
azurwastaken Aug 15, 2024
90de846
moved get_l1_to_l2_message_cancellations to messaging related file
azurwastaken Aug 15, 2024
f9d7a66
renaming some fn
azurwastaken Aug 15, 2024
e485e8c
added nonce check in test
azurwastaken Aug 15, 2024
763c598
refactored contract in test
azurwastaken Aug 15, 2024
506745d
added nonce in db for cancelled message
azurwastaken Aug 16, 2024
420def5
take only finalized block in event filter
azurwastaken Aug 16, 2024
4d49899
Merge branch 'main' into pr/220
EvolveArt Aug 19, 2024
7323c7e
fix: linter
EvolveArt Aug 19, 2024
1c84517
fix: clippy
EvolveArt Aug 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Next release

- feat: Added l1->l2 messaging
- tests: add tests for the rpcs endpoints
- fix: pending contract storage not stored properly
- test: add tests crate `db`
Expand Down
100 changes: 96 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

127 changes: 127 additions & 0 deletions crates/client/db/src/l1_db.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
use rocksdb::WriteOptions;
use serde::{Deserialize, Serialize};
use starknet_api::core::Nonce;

use crate::error::DbError;
use crate::{Column, DatabaseExt, DeoxysBackend, DeoxysStorageError};

type Result<T, E = DeoxysStorageError> = std::result::Result<T, E>;

pub const LAST_SYNCED_L1_EVENT_BLOCK: &[u8] = b"LAST_SYNCED_L1_EVENT_BLOCK";

/// Struct to store block number and event_index where L1->L2 Message occured
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct LastSyncedEventBlock {
pub block_number: u64,
pub event_index: u64,
}

impl LastSyncedEventBlock {
/// Create a new LastSyncedBlock with block number and event index
pub fn new(block_number: u64, event_index: u64) -> Self {
LastSyncedEventBlock { block_number, event_index }
}
}

/// We add method in DeoxysBackend to be able to handle L1->L2 messaging related data
impl DeoxysBackend {
/// Retrieves the last stored L1 block data that contains a message from the database.
///
/// This function attempts to fetch the data of the last messaging-related block from the database.
/// If a block is found, it is retrieved, deserialized, and returned.
/// Otherwise, a `LastSyncedEventBlock` instance with the `block_number` and `event_index` set to 0 is returned.
///
/// # Returns
///
/// - `Ok(Some(LastSyncedEventBlock))` - If the last synced L1 block with a messaging event is found
/// and successfully deserialized.
/// - `Ok(Some(LastSyncedEventBlock::new(0, 0)))` - If no such block exists in the database.
/// - `Err(e)` - If there is an error accessing the database or deserializing the block.
///
/// # Errors
///
/// This function returns an error if:
/// - There is a failure in interacting with the database.
/// - The block's deserialization fails.
///
/// # Example
///
/// let last_synced_event_block = match backend.messaging_last_synced_l1_block_with_event() {
/// Ok(Some(blk)) => blk,
/// Ok(None) => unreachable!("Should never be None"),
/// Err(e) => {
/// tracing::error!("⟠ Madara Messaging DB unavailable: {:?}", e);
/// return Err(e.into());
/// }
/// };
///
/// # Panics
///
/// This function does not panic.
pub fn messaging_last_synced_l1_block_with_event(&self) -> Result<Option<LastSyncedEventBlock>> {
let messaging_column = self.db.get_column(Column::L1Messaging);
let Some(res) = self.db.get_cf(&messaging_column, LAST_SYNCED_L1_EVENT_BLOCK)? else {
return Ok(Some(LastSyncedEventBlock::new(0, 0)));
};
let res = bincode::deserialize(&res)?;
Ok(Some(res))
}

/// This function inserts a new block into the messaging column.
///
/// This function retrieves the messaging column and inserts a `LastSyncedEventBlock`
/// into it.
///
/// # Arguments
///
/// - `last_synced_event_block`: The `LastSyncedEventBlock` instance representing the most recent
/// synced L1 block with a messaging event.
///
/// # Returns
///
/// - `Ok(())` if the data is correctly inserted into the database.
/// - `Err(e)` if there is an error accessing the database or serializing the data.
///
/// # Errors
///
/// This function returns an error if:
/// - There is a failure in interacting with the database.
/// - The block's serialization fails.
///
/// # Example
///
/// let block_sent = LastSyncedEventBlock::new(l1_block_number.unwrap(), event_index.unwrap());
/// backend.messaging_update_last_synced_l1_block_with_event(block_sent)?;
///
/// # Panics
///
/// This function does not panic.
pub fn messaging_update_last_synced_l1_block_with_event(
&self,
last_synced_event_block: LastSyncedEventBlock,
) -> Result<(), DbError> {
let messaging_column = self.db.get_column(Column::L1Messaging);
let mut writeopts = WriteOptions::default(); // todo move that in db
writeopts.disable_wal(true);
EvolveArt marked this conversation as resolved.
Show resolved Hide resolved
self.db.put_cf_opt(
&messaging_column,
LAST_SYNCED_L1_EVENT_BLOCK,
bincode::serialize(&last_synced_event_block)?,
&writeopts,
)?;
Ok(())
}

pub fn has_l1_messaging_nonce(&self, nonce: Nonce) -> Result<bool> {
let nonce_column = self.db.get_column(Column::L1MessagingNonce);
Ok(self.db.get_pinned_cf(&nonce_column, bincode::serialize(&nonce)?)?.is_some())
}

pub fn set_l1_messaging_nonce(&self, nonce: Nonce) -> Result<(), DbError> {
let nonce_column = self.db.get_column(Column::L1MessagingNonce);
let mut writeopts = WriteOptions::default();
writeopts.disable_wal(true);
self.db.put_cf_opt(&nonce_column, bincode::serialize(&nonce)?, /* empty value */ &[], &writeopts)?;
Ok(())
}
}
8 changes: 8 additions & 0 deletions crates/client/db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub mod class_db;
pub mod contract_db;
pub mod db_block_id;
pub mod db_metrics;
pub mod l1_db;
pub mod storage_updates;

pub use error::{DeoxysStorageError, TrieType};
Expand Down Expand Up @@ -164,6 +165,9 @@ pub enum Column {
BonsaiClassesTrie,
BonsaiClassesFlat,
BonsaiClassesLog,

L1Messaging,
L1MessagingNonce,
}

impl fmt::Debug for Column {
Expand Down Expand Up @@ -207,6 +211,8 @@ impl Column {
BonsaiClassesTrie,
BonsaiClassesFlat,
BonsaiClassesLog,
L1Messaging,
L1MessagingNonce,
PendingContractToClassHashes,
PendingContractToNonces,
PendingContractStorage,
Expand Down Expand Up @@ -242,6 +248,8 @@ impl Column {
ContractToNonces => "contract_to_nonces",
ContractClassHashes => "contract_class_hashes",
ContractStorage => "contract_storage",
L1Messaging => "l1_messaging",
L1MessagingNonce => "l1_messaging_nonce",
PendingContractToClassHashes => "pending_contract_to_class_hashes",
PendingContractToNonces => "pending_contract_to_nonces",
PendingContractStorage => "pending_contract_storage",
Expand Down
4 changes: 4 additions & 0 deletions crates/client/eth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ starknet_api = { workspace = true }
alloy = { workspace = true, features = ["node-bindings"] }
anyhow = "1.0.75"
bitvec = { workspace = true }
blockifier = { workspace = true }
bytes = "1.6.0"
futures = { workspace = true, default-features = true }
log = { workspace = true }
serde = { workspace = true, default-features = true }
Expand All @@ -41,6 +43,7 @@ tokio = { workspace = true, features = [
"test-util",
"signal",
] }
tracing = "0.1.40"
url = { workspace = true }

[dev-dependencies]
Expand All @@ -49,3 +52,4 @@ once_cell = { workspace = true }
tempfile = { workspace = true }
dotenv = { workspace = true }
prometheus = { workspace = true }
tracing-test = "0.2.5"
Loading