From ed2f1a886c0f25d7099fc3b6ff4cf28ce8f11f7c Mon Sep 17 00:00:00 2001 From: Stephen Chen <20940639+stephenctw@users.noreply.github.com> Date: Thu, 5 Sep 2024 20:50:13 +0800 Subject: [PATCH] feat: [WIP] adopt `DaveConsensus` contract --- cartesi-rollups/node/Cargo.toml | 2 + .../node/blockchain-reader/src/lib.rs | 133 +++++++++--------- cartesi-rollups/node/dave-rollups/Cargo.toml | 2 + cartesi-rollups/node/dave-rollups/src/lib.rs | 28 ++++ cartesi-rollups/node/dave-rollups/src/main.rs | 6 +- cartesi-rollups/node/dave-runner/Cargo.toml | 14 ++ cartesi-rollups/node/dave-runner/src/lib.rs | 66 +++++++++ cartesi-rollups/node/epoch-manager/src/lib.rs | 26 ++-- .../node/machine-runner/Cargo.toml | 2 - .../node/machine-runner/src/lib.rs | 12 +- cartesi-rollups/node/state-manager/src/lib.rs | 5 +- .../src/persistent_state_access.rs | 13 +- .../state-manager/src/sql/consensus_data.rs | 61 ++++++-- .../node/state-manager/src/sql/migrations.sql | 3 +- prt/prt-rs/core/src/arena/sender.rs | 2 +- 15 files changed, 269 insertions(+), 106 deletions(-) create mode 100644 cartesi-rollups/node/dave-runner/Cargo.toml create mode 100644 cartesi-rollups/node/dave-runner/src/lib.rs diff --git a/cartesi-rollups/node/Cargo.toml b/cartesi-rollups/node/Cargo.toml index f6b82b9b..4e62ea41 100644 --- a/cartesi-rollups/node/Cargo.toml +++ b/cartesi-rollups/node/Cargo.toml @@ -24,6 +24,7 @@ repository = "https://github.com/cartesi/dave" [workspace.dependencies] rollups-blockchain-reader = { version = "0.1", path = "blockchain-reader" } +rollups-dave-runner = { version = "0.1", path = "dave-runner" } rollups-epoch-manager = { version = "0.1", path = "epoch-manager" } rollups-machine-runner = { version = "0.1", path = "machine-runner" } rollups-state-manager = { version = "0.1", path = "state-manager" } @@ -33,6 +34,7 @@ cartesi-dave-arithmetic = { path = "../../common-rs/arithmetic" } cartesi-dave-contracts = { path = "../contract-bindings" } cartesi-dave-merkle = { path = "../../common-rs/merkle" } cartesi-prt-core = { path = "../../prt/prt-rs/core" } +cartesi-prt-compute = { path = "../../prt/prt-rs/compute" } alloy = { version = "0.3.1", features = ["sol-types", "contract", "network", "reqwest", "signers", "signer-local"] } anyhow = "1.0" diff --git a/cartesi-rollups/node/blockchain-reader/src/lib.rs b/cartesi-rollups/node/blockchain-reader/src/lib.rs index f2437226..87279156 100644 --- a/cartesi-rollups/node/blockchain-reader/src/lib.rs +++ b/cartesi-rollups/node/blockchain-reader/src/lib.rs @@ -17,6 +17,7 @@ use alloy_rpc_types_eth::Topic; use async_recursion::async_recursion; use clap::Parser; use error::BlockchainReaderError; +use num_traits::cast::ToPrimitive; use std::{ marker::{Send, Sync}, str::FromStr, @@ -24,19 +25,10 @@ use std::{ time::Duration, }; +use cartesi_dave_contracts::daveconsensus::DaveConsensus::EpochSealed; use cartesi_rollups_contracts::inputbox::InputBox::InputAdded; use rollups_state_manager::{Epoch, Input, InputId, StateManager}; -/// this is a placeholder for the non-existing epoch event -// #[derive(EthEvent)] -// #[ethevent(name = "EpochSealed", abi = "EpochSealed(uint256,uint256)")] -// pub struct EpochSealedFilter { -// #[ethevent(indexed)] -// pub epoch_index: ::ethers::core::types::U256, -// #[ethevent(indexed)] -// pub input_count: ::ethers::core::types::U256, -// } - #[derive(Debug, Clone, Parser)] #[command(name = "cartesi_rollups_config")] #[command(about = "Addresses of Cartesi Rollups")] @@ -58,7 +50,7 @@ pub struct BlockchainReader { prev_block: u64, provider: PartitionProvider, input_reader: EventReader, - epoch_reader: EventReader, + epoch_reader: EventReader, sleep_duration: Duration, } @@ -85,7 +77,7 @@ where prev_block, provider: partition_provider, input_reader: EventReader::::new(), - epoch_reader: EventReader::::new(), + epoch_reader: EventReader::::new(), sleep_duration: Duration::from_secs(sleep_duration), }) } @@ -119,32 +111,21 @@ where prev_block: u64, current_block: u64, ) -> Result<(Vec, Vec), SM> { - let prev_sealed_epoch = self - .state_manager - .epoch_count() - .map_err(|e| BlockchainReaderError::StateManagerError(e))?; - - // read epochs from blockchain - let epochs: Vec = self + // read sealed epochs from blockchain + let sealed_epochs: Vec = self .collect_sealed_epochs(prev_block, current_block) .await?; - let latest_sealed_epoch = match epochs.last() { - Some(e) => e.epoch_number, - None => prev_sealed_epoch, - }; - // read inputs from blockchain let inputs = self .collect_inputs( prev_block, current_block, - prev_sealed_epoch, - latest_sealed_epoch, + sealed_epochs.iter().collect::>().into_iter(), ) .await?; - Ok((inputs, epochs)) + Ok((inputs, sealed_epochs)) } async fn collect_sealed_epochs( @@ -164,10 +145,17 @@ where .await? .iter() .map(|e| Epoch { - epoch_number: 0, - input_count: 0, - // epoch_number: e.epoch_index.as_u64(), - // input_count: e.input_count.as_u64(), + epoch_number: e + .0 + .epochNumber + .to_u64() + .expect("fail to convert epoch number"), + epoch_boundary: e + .0 + .blockNumberUpperBound + .to_u64() + .expect("fail to convert epoch boundary"), + root_tournament: e.0.tournament.to_string(), }) .collect()) } @@ -176,11 +164,9 @@ where &self, prev_block: u64, current_block: u64, - prev_sealed_epoch: u64, - latest_sealed_epoch: u64, + sealed_epochs_iter: impl Iterator, ) -> Result, SM> { // read new inputs from blockchain - // collected inputs should belong to `prev_sealed_epoch` + 1 and/or later epochs let input_events = self .input_reader .next( @@ -192,45 +178,43 @@ where ) .await?; + let last_input = self + .state_manager + .last_input() + .map_err(|e| BlockchainReaderError::StateManagerError(e))?; + + let (mut next_input_index_in_epoch, mut last_epoch_number) = { + match last_input { + // continue inserting inputs from where last were left + Some(input) => (input.input_index_in_epoch + 1, input.epoch_number), + // first ever input for the application + None => (0, 0), + } + }; + let mut inputs = vec![]; - let input_events_len = input_events.len(); - let mut input_events_iter = input_events.into_iter(); - - // all inputs from `prev_sealed_epoch` should be in database already because it's sealed in previous tick - for epoch_number in prev_sealed_epoch + 1..latest_sealed_epoch + 1 { - // iterate through newly sealed epochs - // get total input count submitted to the sealed epoch - let total_input_count_of_epoch = self - .state_manager - .epoch(epoch_number) - .map_err(|e| BlockchainReaderError::StateManagerError(e))? - .unwrap() - .input_count; - // get input count of epoch that currently exist in database - let current_input_count_of_epoch = self - .state_manager - .input_count(epoch_number) - .map_err(|e| BlockchainReaderError::StateManagerError(e))?; - - // fill in the inputs of the sealed epoch + let mut input_events_iter = input_events.iter(); + for epoch in sealed_epochs_iter { + // iterate through newly sealed epochs, fill in the inputs accordingly let inputs_of_epoch = self .construct_input_ids( - epoch_number, - current_input_count_of_epoch, - total_input_count_of_epoch, + epoch.epoch_number, + epoch.epoch_boundary, + &mut next_input_index_in_epoch, &mut input_events_iter, ) .await; inputs.extend(inputs_of_epoch); + last_epoch_number = epoch.epoch_number + 1; } // all remaining inputs belong to an epoch that's not sealed yet let inputs_of_epoch = self .construct_input_ids( - latest_sealed_epoch + 1, - 0, - (input_events_len - inputs.len()).try_into().unwrap(), + last_epoch_number, + u64::MAX, + &mut next_input_index_in_epoch, &mut input_events_iter, ) .await; @@ -243,23 +227,32 @@ where async fn construct_input_ids( &self, epoch_number: u64, - input_index_in_epoch_start: u64, - input_index_in_epoch_end: u64, - input_events_iter: &mut impl Iterator, + epoch_boundary: u64, + next_input_index_in_epoch: &mut u64, + input_events_iter: &mut impl Iterator, ) -> Vec { let mut inputs = vec![]; - for input_index_in_epoch in input_index_in_epoch_start..input_index_in_epoch_end { + while input_events_iter + .peekable() + .peek() + .expect("fail to get peek next input") + .1 + < epoch_boundary + { let input = Input { id: InputId { epoch_number, - input_index_in_epoch, + input_index_in_epoch: *next_input_index_in_epoch, }, - data: input_events_iter.next().unwrap().input.to_vec(), + data: input_events_iter.next().unwrap().0.input.to_vec(), }; + *next_input_index_in_epoch += 1; inputs.push(input); } + // input index in epoch should be reset when a new epoch starts + *next_input_index_in_epoch = 0; inputs } @@ -283,7 +276,7 @@ impl EventReader { prev_finalized: u64, current_finalized: u64, provider: &PartitionProvider, - ) -> std::result::Result, ProviderErrors> { + ) -> std::result::Result)>, ProviderErrors> { assert!(current_finalized > prev_finalized); let logs = provider @@ -320,7 +313,7 @@ impl PartitionProvider { read_from: &Address, start_block: u64, end_block: u64, - ) -> std::result::Result, Vec> { + ) -> std::result::Result)>, Vec> { self.get_events_rec(topic1, read_from, start_block, end_block) .await } @@ -332,7 +325,7 @@ impl PartitionProvider { read_from: &Address, start_block: u64, end_block: u64, - ) -> std::result::Result, Vec> { + ) -> std::result::Result)>, Vec> { // TODO: partition log queries if range too large let event = { let mut e = Event::new_sol(&self.inner, read_from) @@ -349,7 +342,7 @@ impl PartitionProvider { match event.query().await { Ok(l) => { - let logs = l.into_iter().map(|x| x.0).collect(); + let logs = l.into_iter().map(|x| (x.0, x.1.block_number)).collect(); Ok(logs) } diff --git a/cartesi-rollups/node/dave-rollups/Cargo.toml b/cartesi-rollups/node/dave-rollups/Cargo.toml index 5b405da7..df140e94 100644 --- a/cartesi-rollups/node/dave-rollups/Cargo.toml +++ b/cartesi-rollups/node/dave-rollups/Cargo.toml @@ -12,12 +12,14 @@ repository = { workspace = true } [dependencies] rollups-blockchain-reader = { workspace = true } +rollups-dave-runner = { workspace = true } rollups-epoch-manager = { workspace = true } rollups-machine-runner = { workspace = true } rollups-state-manager = { workspace = true } cartesi-rollups-contracts = { workspace = true } cartesi-prt-core = { workspace = true } +cartesi-prt-compute = { workspace = true } alloy = { workspace = true } anyhow = { workspace = true } diff --git a/cartesi-rollups/node/dave-rollups/src/lib.rs b/cartesi-rollups/node/dave-rollups/src/lib.rs index 746f0894..5ec344c6 100644 --- a/cartesi-rollups/node/dave-rollups/src/lib.rs +++ b/cartesi-rollups/node/dave-rollups/src/lib.rs @@ -1,10 +1,15 @@ +use alloy::primitives::Address; use cartesi_prt_core::arena::BlockchainConfig; + use clap::Parser; +use dave_runner::DaveRunner; use log::error; use rollups_blockchain_reader::{AddressBook, BlockchainReader}; +use rollups_dave_runner::DaveRunner; use rollups_epoch_manager::EpochManager; use rollups_machine_runner::MachineRunner; use rollups_state_manager::persistent_state_access::PersistentStateAccess; +use rusqlite::config; use std::sync::Arc; use tokio::task::JoinHandle; use tokio::task::{spawn, spawn_blocking}; @@ -54,6 +59,29 @@ pub fn create_blockchain_reader_task( }) } +pub fn create_dave_runner_task( + state_manager: Arc, + parameters: &DaveParameters, +) -> JoinHandle<()> { + let params = parameters.clone(); + + spawn_blocking(move || { + let mut dave_runner = DaveRunner::new( + ¶meters.blockchain_config, + state_manager, + params.sleep_duration, + ) + .inspect_err(|e| error!("{e}")) + .unwrap(); + + dave_runner + .start() + .await + .inspect_err(|e| error!("{e}")) + .unwrap(); + }) +} + pub fn create_epoch_manager_task( state_manager: Arc, parameters: &DaveParameters, diff --git a/cartesi-rollups/node/dave-rollups/src/main.rs b/cartesi-rollups/node/dave-rollups/src/main.rs index 40538017..5c394708 100644 --- a/cartesi-rollups/node/dave-rollups/src/main.rs +++ b/cartesi-rollups/node/dave-rollups/src/main.rs @@ -23,11 +23,13 @@ async fn main() -> Result<()> { let blockchain_reader_task = create_blockchain_reader_task(state_manager.clone(), ¶meters); let epoch_manager_task = create_epoch_manager_task(state_manager.clone(), ¶meters); let machine_runner_task = create_machine_runner_task(state_manager.clone(), ¶meters); + let dave_runner_task = create_dave_runner_task(state_manager.clone(), ¶meters); - let (_blockchain_reader_res, _epoch_manager_res, _machine_runner_res) = futures::join!( + let (_blockchain_reader_res, _epoch_manager_res, _machine_runner_res, _dave_runner_res) = futures::join!( blockchain_reader_task, epoch_manager_task, - machine_runner_task + machine_runner_task, + dave_runner_task ); Ok(()) diff --git a/cartesi-rollups/node/dave-runner/Cargo.toml b/cartesi-rollups/node/dave-runner/Cargo.toml new file mode 100644 index 00000000..ff0263a2 --- /dev/null +++ b/cartesi-rollups/node/dave-runner/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "rollups-dave-runner" +version.workspace = true +authors.workspace = true +description.workspace = true +edition.workspace = true +homepage.workspace = true +license-file.workspace = true +readme.workspace = true +repository.workspace = true + +[dependencies] +cartesi-prt-core = { workspace = true } +rollups-state-manager = { workspace = true } diff --git a/cartesi-rollups/node/dave-runner/src/lib.rs b/cartesi-rollups/node/dave-runner/src/lib.rs new file mode 100644 index 00000000..4c3d1f7b --- /dev/null +++ b/cartesi-rollups/node/dave-runner/src/lib.rs @@ -0,0 +1,66 @@ +use std::result::Result; +use std::{sync::Arc, time::Duration}; + +use cartesi_prt_core::arena::BlockchainConfig; +use rollups_state_manager::{Epoch, StateManager}; + +pub struct DaveRunner { + config: BlockchainConfig, + last_processed_epoch: Epoch, + sleep_duration: Duration, + state_manager: Arc, +} + +impl DaveRunner +where + ::Error: Send + Sync + 'static, +{ + pub fn new( + config: &BlockchainConfig, + state_manager: Arc, + sleep_duration: u64, + ) -> Result::Error> { + let last_sealed_epoch = state_manager.last_epoch()?; + let last_processed_epoch = { + match last_sealed_epoch { + Some(e) => { + spawn_dave_process(config, &e); + e + } + None => Epoch { + epoch_number: 0, + epoch_boundary: 0, + root_tournament: String::new(), + }, + } + }; + + Ok(Self { + config: config.clone(), + last_processed_epoch, + sleep_duration: Duration::from_secs(sleep_duration), + state_manager, + }) + } + + pub fn start(&mut self) -> Result<(), ::Error> { + loop { + let last_sealed_epoch = self.state_manager.last_epoch()?; + if let Some(e) = last_sealed_epoch { + if e.epoch_number != self.last_processed_epoch.epoch_number + || e.epoch_boundary != self.last_processed_epoch.epoch_boundary + || e.root_tournament != self.last_processed_epoch.root_tournament + { + spawn_dave_process(&self.config, &e); + self.last_processed_epoch = e; + } + } + + std::thread::sleep(self.sleep_duration); + } + } +} + +fn spawn_dave_process(config: &BlockchainConfig, epoch: &Epoch) { + // TODO: spawn a dave process +} diff --git a/cartesi-rollups/node/epoch-manager/src/lib.rs b/cartesi-rollups/node/epoch-manager/src/lib.rs index 680b74dc..74e7b305 100644 --- a/cartesi-rollups/node/epoch-manager/src/lib.rs +++ b/cartesi-rollups/node/epoch-manager/src/lib.rs @@ -1,6 +1,6 @@ use alloy::{ - network::{Ethereum, EthereumWallet, NetworkWallet}, - providers::ProviderBuilder, + network::EthereumWallet, + providers::{fillers::NonceFiller, ProviderBuilder}, signers::local::PrivateKeySigner, sol_types::private::Address, }; @@ -11,7 +11,6 @@ use cartesi_dave_contracts::daveconsensus; use cartesi_prt_core::arena::{BlockchainConfig, SenderFiller}; use rollups_state_manager::StateManager; -// TODO: setup constants for commitment builder pub struct EpochManager { consensus: Address, sleep_duration: Duration, @@ -35,7 +34,7 @@ where let url = config.web3_rpc_url.parse().expect("fail to parse url"); let provider = ProviderBuilder::new() - .with_nonce_management() + .filler(NonceFiller::default()) .wallet(wallet) .with_chain( config @@ -54,20 +53,21 @@ where } } - pub async fn start(&mut self) -> Result<()> { + pub async fn start(&self) -> Result<()> { let dave_consensus = daveconsensus::DaveConsensus::new(self.consensus, &self.client); loop { - let can_settle = dave_consensus.canSettle().call().await?._0; + let can_settle = dave_consensus.canSettle().call().await?; - if can_settle { + if can_settle.isFinished { match self.state_manager.computation_hash(0)? { Some(computation_hash) => { - dave_consensus.settle().send().await?.watch().await?; - // match claim - //  + None -> claim - //  + Some({x, false}) if x is same as comp_hash -> return; - //  + Some({x, false}) if x is not same comp_hash -> claim; - // + Some({_, true}) -> instantiate/join dave; + dave_consensus + .settle(can_settle.epochNumber) + .send() + .await? + .watch() + .await?; + // TODO: if claim doesn't match, that can be a serious problem, send out alert } None => { // wait for the `machine-runner` to insert the value diff --git a/cartesi-rollups/node/machine-runner/Cargo.toml b/cartesi-rollups/node/machine-runner/Cargo.toml index 2bb1b6a9..9a7fec55 100644 --- a/cartesi-rollups/node/machine-runner/Cargo.toml +++ b/cartesi-rollups/node/machine-runner/Cargo.toml @@ -18,9 +18,7 @@ cartesi-machine = { workspace = true } rollups-state-manager = { workspace = true } thiserror = { workspace = true } -tokio = { workspace = true } [dev-dependencies] cartesi-rollups-contracts = { workspace = true } hex = "0.4.3" -serde = "1" diff --git a/cartesi-rollups/node/machine-runner/src/lib.rs b/cartesi-rollups/node/machine-runner/src/lib.rs index 02e974f7..e1177c74 100644 --- a/cartesi-rollups/node/machine-runner/src/lib.rs +++ b/cartesi-rollups/node/machine-runner/src/lib.rs @@ -266,6 +266,10 @@ mod tests { Ok(self.inputs.len() as u64) } + fn last_epoch(&self) -> Result> { + panic!("last_epoch not implemented in mock version"); + } + fn input(&self, id: &InputId) -> Result> { let (epoch_number, input_index_in_epoch) = (id.epoch_number as usize, id.input_index_in_epoch as usize); @@ -283,6 +287,10 @@ mod tests { })) } + fn last_input(&self) -> Result> { + panic!("last_input not implemented in mock version"); + } + fn input_count(&self, epoch_number: u64) -> Result { let input_count = self.inputs[epoch_number as usize].len(); Ok(input_count as u64) @@ -447,8 +455,8 @@ mod tests { inputs } - #[tokio::test] - async fn test_input_advance() -> std::result::Result<(), Box> { + #[test] + fn test_input_advance() -> std::result::Result<(), Box> { // TODO: update machine state hashes with new emulator version let (machine_state_hashes, commitment) = load_machine_state_hashes(); let inputs = load_inputs(); diff --git a/cartesi-rollups/node/state-manager/src/lib.rs b/cartesi-rollups/node/state-manager/src/lib.rs index 3380a963..bdef641c 100644 --- a/cartesi-rollups/node/state-manager/src/lib.rs +++ b/cartesi-rollups/node/state-manager/src/lib.rs @@ -70,7 +70,8 @@ pub struct Input { #[derive(Clone, Debug)] pub struct Epoch { pub epoch_number: u64, - pub input_count: u64, + pub epoch_boundary: u64, + pub root_tournament: String, } pub trait StateManager { @@ -82,8 +83,10 @@ pub trait StateManager { fn epoch(&self, epoch_number: u64) -> Result, Self::Error>; fn epoch_count(&self) -> Result; + fn last_epoch(&self) -> Result, Self::Error>; fn input(&self, id: &InputId) -> Result, Self::Error>; fn input_count(&self, epoch_number: u64) -> Result; + fn last_input(&self) -> Result, Self::Error>; fn insert_consensus_data<'a>( &self, last_processed_block: u64, diff --git a/cartesi-rollups/node/state-manager/src/persistent_state_access.rs b/cartesi-rollups/node/state-manager/src/persistent_state_access.rs index f315bee1..6d277f4a 100644 --- a/cartesi-rollups/node/state-manager/src/persistent_state_access.rs +++ b/cartesi-rollups/node/state-manager/src/persistent_state_access.rs @@ -37,6 +37,11 @@ impl StateManager for PersistentStateAccess { consensus_data::epoch_count(&conn) } + fn last_epoch(&self) -> Result> { + let conn = self.connection.lock().unwrap(); + consensus_data::last_epoch(&conn) + } + fn input(&self, id: &InputId) -> Result> { let conn = self.connection.lock().unwrap(); consensus_data::input(&conn, id) @@ -47,6 +52,11 @@ impl StateManager for PersistentStateAccess { consensus_data::input_count(&conn, epoch_number) } + fn last_input(&self) -> Result> { + let conn = self.connection.lock().unwrap(); + consensus_data::last_input(&conn) + } + fn latest_processed_block(&self) -> Result { let conn = self.connection.lock().unwrap(); consensus_data::last_processed_block(&conn) @@ -336,7 +346,8 @@ mod tests { .into_iter(), [&Epoch { epoch_number: 0, - input_count: 12, + epoch_boundary: 12, + root_tournament: String::new(), }] .into_iter(), )?; diff --git a/cartesi-rollups/node/state-manager/src/sql/consensus_data.rs b/cartesi-rollups/node/state-manager/src/sql/consensus_data.rs index 3ba45368..2d25b6b5 100644 --- a/cartesi-rollups/node/state-manager/src/sql/consensus_data.rs +++ b/cartesi-rollups/node/state-manager/src/sql/consensus_data.rs @@ -164,7 +164,11 @@ pub fn insert_epochs<'a>( }); } - stmt.execute(params![epoch.epoch_number, epoch.input_count])?; + stmt.execute(params![ + epoch.epoch_number, + epoch.epoch_boundary, + epoch.root_tournament + ])?; next_epoch += 1; } Ok(()) @@ -173,15 +177,35 @@ pub fn insert_epochs<'a>( fn insert_epoch_statement<'a>(conn: &'a rusqlite::Connection) -> Result> { Ok(conn.prepare( "\ - INSERT INTO epochs (epoch_number, input_count) VALUES (?1, ?2) + INSERT INTO epochs (epoch_number, epoch_boundary, root_tournament) VALUES (?1, ?2, ?3) ", )?) } +pub fn last_epoch(conn: &rusqlite::Connection) -> Result> { + let mut stmt = conn.prepare( + "\ + SELECT epoch_number, epoch_boundary, root_tournament FROM epochs + ORDER BY epoch_number DESC + LIMIT 1 + ", + )?; + + Ok(stmt + .query_row([], |row| { + Ok(Epoch { + epoch_number: row.get(0)?, + epoch_boundary: row.get(1)?, + root_tournament: row.get(2)?, + }) + }) + .optional()?) +} + pub fn epoch(conn: &rusqlite::Connection, epoch_number: u64) -> Result> { let mut stmt = conn.prepare( "\ - SELECT input_count FROM epochs + SELECT epoch_boundary, root_tournament FROM epochs WHERE epoch_number = ?1 ", )?; @@ -190,7 +214,8 @@ pub fn epoch(conn: &rusqlite::Connection, epoch_number: u64) -> Result = (1..128) .map(|i| Epoch { epoch_number: i, - input_count: 0, + epoch_boundary: 0, + root_tournament: String::new(), }) .collect(); assert!(matches!(insert_epochs(&conn, x.iter()), Ok(()))); @@ -549,15 +578,18 @@ mod epochs_tests { [ &Epoch { epoch_number: 128, - input_count: 0, + epoch_boundary: 0, + root_tournament: String::new(), }, &Epoch { epoch_number: 129, - input_count: 0, + epoch_boundary: 0, + root_tournament: String::new(), }, &Epoch { epoch_number: 131, - input_count: 0, + epoch_boundary: 0, + root_tournament: String::new(), } ] .into_iter(), @@ -569,13 +601,15 @@ mod epochs_tests { )); assert!(matches!(epoch_count(&conn), Ok(130))); + let tournament_address = "0x8dA443F84fEA710266C8eB6bC34B71702d033EF2".to_string(); assert!(matches!(epoch(&conn, 130), Ok(None))); assert!(matches!( insert_epochs( &conn, [&Epoch { epoch_number: 130, - input_count: 99, + epoch_boundary: 99, + root_tournament: tournament_address, }] .into_iter(), ), @@ -585,7 +619,8 @@ mod epochs_tests { epoch(&conn, 130), Ok(Some(Epoch { epoch_number: 130, - input_count: 99, + epoch_boundary: 99, + root_tournament: tournament_address, })) )); } diff --git a/cartesi-rollups/node/state-manager/src/sql/migrations.sql b/cartesi-rollups/node/state-manager/src/sql/migrations.sql index 7c774f94..ca527382 100644 --- a/cartesi-rollups/node/state-manager/src/sql/migrations.sql +++ b/cartesi-rollups/node/state-manager/src/sql/migrations.sql @@ -5,7 +5,8 @@ CREATE TABLE computation_hashes ( CREATE TABLE epochs ( epoch_number INTEGER NOT NULL PRIMARY KEY, - input_count INTEGER NOT NULL + epoch_boundary INTEGER NOT NULL, + root_tournament TEXT NOT NULL ); CREATE TABLE inputs ( diff --git a/prt/prt-rs/core/src/arena/sender.rs b/prt/prt-rs/core/src/arena/sender.rs index 46d3d787..903e7314 100644 --- a/prt/prt-rs/core/src/arena/sender.rs +++ b/prt/prt-rs/core/src/arena/sender.rs @@ -49,7 +49,7 @@ impl EthArenaSender { let url = config.web3_rpc_url.parse()?; let provider = ProviderBuilder::new() - .with_nonce_management() + .filler(NonceFiller::default()) .wallet(wallet) .with_chain( config