From ee27d7ec843bafed99092ee528a4c8cd20337bd9 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Tue, 11 Apr 2023 13:33:02 -0500 Subject: [PATCH 1/4] Update for latest sov sdk --- src/main.rs | 30 +++++++++++++++++++++++------- src/runtime.rs | 1 + src/tx_verifier_impl.rs | 2 +- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index 11922cf..0662973 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +use crate::runtime::GenesisConfig; use jsonrpsee::http_client::HeaderMap; use jupiter::{ da_app::{CelestiaApp, TmHash}, @@ -10,14 +11,15 @@ use sov_state::ProverStorage; use sovereign_db::{ ledger_db::{LedgerDB, SlotCommitBuilder}, schema::types::{ - BatchNumber, DbBytes, DbHash, EventNumber, Status, StoredBatch, StoredSlot, - StoredTransaction, TxNumber, + BatchNumber, DbBytes, EventNumber, Status, StoredBatch, StoredSlot, StoredTransaction, + TxNumber, }, }; use sovereign_sdk::{ da::BlobTransactionTrait, serial::Encode, services::da::{DaService, SlotData}, + spec::RollupSpec, }; use sovereign_sdk::{da::DaLayerTrait, stf::StateTransitionFunction}; use sovereign_sdk::{db::SlotStore, serial::Decode}; @@ -36,8 +38,20 @@ mod runtime; mod tx_hooks_impl; mod tx_verifier_impl; +#[derive(Debug, Clone)] +struct Spec; + +impl RollupSpec for Spec { + type SlotData = FilteredCelestiaBlock; + + type Stf = DemoApp; + + type Hasher = Sha256; +} + type C = MockContext; -type DemoApp = AppTemplate, Runtime, DemoAppTxHooks>; +type DemoApp = + AppTemplate, Runtime, DemoAppTxHooks, GenesisConfig>; const CELESTIA_NODE_AUTH_TOKEN: &'static str = ""; const START_HEIGHT: u64 = HEIGHT_OF_FIRST_TXS - 5; @@ -76,13 +90,14 @@ async fn main() -> Result<(), anyhow::Error> { .map_err(|_err| eprintln!("Unable to set global default subscriber")) .expect("Cannot fail to set subscriber"); let cel_service = default_celestia_service(); - let ledger_db = LedgerDB::::with_path(DATA_DIR_LOCATION).unwrap(); + let ledger_db = LedgerDB::::with_path(DATA_DIR_LOCATION).unwrap(); let storage = ProverStorage::with_path(DATA_DIR_LOCATION).unwrap(); let mut demo = DemoApp::new( storage.clone(), Runtime::new(), DemoAppTxVerifier::new(), DemoAppTxHooks::new(), + GenesisConfig::new(()), ); let da_app = CelestiaApp { db: ledger_db.clone(), @@ -132,7 +147,8 @@ async fn main() -> Result<(), anyhow::Error> { let tx_start = item_numbers.tx_number; let num_txs = batch.txs.len(); let mut batch_to_store = StoredBatch { - hash: DbBytes::new(batch_hash.to_vec()), + sender: raw_batch.sender.as_ref().to_vec(), + hash: batch_hash, extra_data: DbBytes::new(raw_batch.sender.as_ref().to_vec()), txs: TxNumber(tx_start)..TxNumber(tx_start + num_txs as u64), status: Status::Skipped, @@ -149,7 +165,7 @@ async fn main() -> Result<(), anyhow::Error> { let end_event_number = start_event_number + events.len() as u64; item_numbers.event_number = end_event_number; StoredTransaction { - hash: DbHash::new(sha2(&tx.data[..]).to_vec()), + hash: sha2(&tx.data[..]), events: EventNumber(start_event_number)..EventNumber(end_event_number), data: DbBytes::new(tx.data), status: Status::Applied, @@ -170,7 +186,7 @@ async fn main() -> Result<(), anyhow::Error> { demo.end_slot(); data_to_persist.slot_data = Some(StoredSlot { - hash: DbHash::new(slot_hash.to_vec()), + hash: slot_hash, extra_data: DbBytes::new(slot_extra_data), batches: BatchNumber(item_numbers.batch_number) ..BatchNumber(item_numbers.batch_number + num_batches as u64), diff --git a/src/runtime.rs b/src/runtime.rs index bff2309..5ff136d 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -38,6 +38,7 @@ use sov_modules_macros::{DispatchCall, DispatchQuery, Genesis, MessageCodec}; /// Similar mechanism works for queries with the difference that queries are submitted by users directly to the rollup node /// instead of going through the DA layer. #[derive(Genesis, DispatchCall, DispatchQuery, MessageCodec)] +#[serialization(borsh::BorshDeserialize, borsh::BorshSerialize)] pub(crate) struct Runtime { /// Definition of the first module in the rollup (must implement the sov_modules_api::Module trait). #[allow(unused)] diff --git a/src/tx_verifier_impl.rs b/src/tx_verifier_impl.rs index 4434df7..35b3439 100644 --- a/src/tx_verifier_impl.rs +++ b/src/tx_verifier_impl.rs @@ -14,7 +14,7 @@ pub(crate) struct Transaction { } impl Transaction { - pub fn new(msg: Vec, pub_key: C::PublicKey, signature: C::Signature, nonce: u64) -> Self { + pub fn _new(msg: Vec, pub_key: C::PublicKey, signature: C::Signature, nonce: u64) -> Self { Self { signature, runtime_msg: msg, From 0f452765275f422e0ee7046c7c5ff6617f39db96 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Thu, 20 Apr 2023 10:31:19 -0500 Subject: [PATCH 2/4] Implement bank/slot RPC --- Cargo.toml | 3 +- src/main.rs | 42 +++++++------- src/rpc.rs | 121 ++++++++++++++++++++++++++++++++++++++++ src/runtime.rs | 8 ++- src/tx_hooks_impl.rs | 29 +++++++++- src/tx_verifier_impl.rs | 2 +- 6 files changed, 180 insertions(+), 25 deletions(-) create mode 100644 src/rpc.rs diff --git a/Cargo.toml b/Cargo.toml index aa18d2b..f0df115 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ sha2 = "0.10.6" jupiter = { path ="../Jupiter"} sov-app-template = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } accounts = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } +bank = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } election = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } sovereign-sdk = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } sov-state = { git = "https://github.com/Sovereign-Labs/sovereign.git", features = ["temp"], rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } @@ -25,7 +26,7 @@ tracing = "0.1.37" tracing-subscriber = "0.3.16" anyhow = "1.0.62" -jsonrpsee = { version = "0.16.2", features = ["http-client"] } +jsonrpsee = { version = "0.16.2", features = ["http-client", "server"] } [patch.crates-io] # Patch borsh until "bytes" support is added diff --git a/src/main.rs b/src/main.rs index 0662973..7da0b79 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ use crate::runtime::GenesisConfig; +use bank::TokenConfig; use jsonrpsee::http_client::HeaderMap; use jupiter::{ da_app::{CelestiaApp, TmHash}, @@ -6,7 +7,7 @@ use jupiter::{ }; use sha2::{Digest, Sha256}; use sov_app_template::{AppTemplate, Batch}; -use sov_modules_api::mocks::MockContext; +use sov_modules_api::{mocks::MockContext, Address}; use sov_state::ProverStorage; use sovereign_db::{ ledger_db::{LedgerDB, SlotCommitBuilder}, @@ -27,13 +28,11 @@ use sovereign_sdk::{db::SlotStore, serial::Decode}; use tracing::Level; use tx_verifier_impl::DemoAppTxVerifier; -use crate::{ - data_generation::QueryGenerator, helpers::run_query, runtime::Runtime, - tx_hooks_impl::DemoAppTxHooks, -}; +use crate::{runtime::Runtime, tx_hooks_impl::DemoAppTxHooks}; mod data_generation; mod helpers; +mod rpc; mod runtime; mod tx_hooks_impl; mod tx_verifier_impl; @@ -83,8 +82,10 @@ const DATA_DIR_LOCATION: &'static str = "demo_data"; #[tokio::main] async fn main() -> Result<(), anyhow::Error> { + let sequencer_address: Address = [1u8; 32].into(); + let subscriber = tracing_subscriber::fmt() - .with_max_level(Level::INFO) + .with_max_level(Level::WARN) .finish(); tracing::subscriber::set_global_default(subscriber) .map_err(|_err| eprintln!("Unable to set global default subscriber")) @@ -97,11 +98,26 @@ async fn main() -> Result<(), anyhow::Error> { Runtime::new(), DemoAppTxVerifier::new(), DemoAppTxHooks::new(), - GenesisConfig::new(()), + GenesisConfig::new( + (), + bank::BankConfig { + tokens: vec![TokenConfig { + token_name: "sovereign".to_string(), + address_and_balances: vec![(sequencer_address, 1000)], + }], + }, + accounts::AccountConfig { pub_keys: vec![] }, + ), ); let da_app = CelestiaApp { db: ledger_db.clone(), }; + + let rpc_ledger = ledger_db.clone(); + let rpc_storage = storage.clone(); + + let _rpc_handle = rpc::RpcProvider::start(rpc_ledger, rpc_storage).await?; + let mut item_numbers = ledger_db.get_next_items_numbers(); if item_numbers.slot_number == 1 { print!("No history detected. Initializing chain..."); @@ -118,8 +134,6 @@ async fn main() -> Result<(), anyhow::Error> { if last_slot_processed_before_shutdown > i { println!("Slot at {} has already been processed! Skipping", height); continue; - } else { - println!("Processing slot at {}", height); } let filtered_block: FilteredCelestiaBlock = cel_service.get_finalized_at(height).await?; @@ -133,7 +147,6 @@ async fn main() -> Result<(), anyhow::Error> { demo.begin_slot(); let num_batches = batches.len(); - println!(" Found {} batches.", num_batches); for raw_batch in batches { let mut data = raw_batch.data(); let batch = match Batch::decode(&mut data) { @@ -193,15 +206,6 @@ async fn main() -> Result<(), anyhow::Error> { }); item_numbers.batch_number += num_batches as u64; ledger_db.commit_slot(data_to_persist.finalize()?)?; - - println!( - "Current state: {}", - run_query( - &mut demo.runtime, - QueryGenerator::generate_query_election_message(), - storage.clone(), - ) - ); } Ok(()) diff --git a/src/rpc.rs b/src/rpc.rs new file mode 100644 index 0000000..f5c4bb6 --- /dev/null +++ b/src/rpc.rs @@ -0,0 +1,121 @@ +use std::net::SocketAddr; + +use bank::{ + query::{BankRpcImpl, BankRpcServer}, + Bank, +}; +use jsonrpsee::server::ServerHandle; +use sov_modules_api::mocks::MockContext; +use sov_state::{mocks::MockStorageSpec, ProverStorage, WorkingSet}; +use sovereign_db::ledger_db::LedgerDB; +use sovereign_sdk::rpc::{LedgerRpcProvider, QueryMode, SlotIdentifier}; + +use crate::{runtime::Runtime, tx_verifier_impl::DemoAppTxVerifier, Spec}; + +#[derive(Clone)] +pub(crate) struct RpcProvider { + pub ledger_db: LedgerDB, + pub state_db: ProverStorage, + pub runtime: Runtime, + pub _tx_verifier: DemoAppTxVerifier, +} + +impl BankRpcImpl for RpcProvider { + fn get_backing_impl(&self) -> &Bank { + &self.runtime.bank + } + + fn get_working_set(&self) -> WorkingSet> { + WorkingSet::new(self.state_db.clone()) + } +} + +impl RpcProvider { + pub async fn start( + ledger_db: LedgerDB, + state_db: ProverStorage, + ) -> Result { + let address: SocketAddr = "127.0.0.1:12345".parse().unwrap(); + let server = jsonrpsee::server::ServerBuilder::default() + .build([address].as_ref()) + .await?; + + let runtime = Runtime::new(); + let tx_verifier = DemoAppTxVerifier::new(); + let bank_rpc = Self { + ledger_db, + state_db, + runtime, + _tx_verifier: tx_verifier, + }; + + let ledger_rpc = bank_rpc.clone(); + + let mut bank_rpc = bank_rpc.into_rpc(); + bank_rpc.register_method("chain_getSlots", move |params, _| { + let slot_ids: Vec; + let query_mode: QueryMode; + (slot_ids, query_mode) = params.parse()?; + ledger_rpc + .get_slots(&slot_ids, query_mode) + .map_err(|e| e.into()) + })?; + + server.start(bank_rpc) + } +} + +// TODO: Re-implement +// impl TransactionRpcProvider for RpcProvider { +// type Transaction = RawTx; + +// fn check_transaction(&self, tx: Self::Transaction) -> Result<(), anyhow::Error> { +// self.tx_verifier.verify_tx_stateless(tx).map(|_| ()) +// } + +// fn submit_transaction(&self, tx: Self::Transaction) -> Result<(), anyhow::Error> { +// todo!() +// } +// } + +/// Delegate all the Ledger RPC methods to the LedgerDB. +impl LedgerRpcProvider for RpcProvider { + type SlotResponse = as LedgerRpcProvider>::SlotResponse; + + type BatchResponse = as LedgerRpcProvider>::BatchResponse; + + type TxResponse = as LedgerRpcProvider>::TxResponse; + + type EventResponse = as LedgerRpcProvider>::EventResponse; + + fn get_slots( + &self, + slot_ids: &[sovereign_sdk::rpc::SlotIdentifier], + query_mode: sovereign_sdk::rpc::QueryMode, + ) -> Result>, anyhow::Error> { + self.ledger_db.get_slots(slot_ids, query_mode) + } + + fn get_batches( + &self, + batch_ids: &[sovereign_sdk::rpc::BatchIdentifier], + query_mode: sovereign_sdk::rpc::QueryMode, + ) -> Result>, anyhow::Error> { + self.ledger_db.get_batches(batch_ids, query_mode) + } + + fn get_transactions( + &self, + tx_ids: &[sovereign_sdk::rpc::TxIdentifier], + query_mode: sovereign_sdk::rpc::QueryMode, + ) -> Result>, anyhow::Error> { + self.ledger_db.get_transactions(tx_ids, query_mode) + } + + fn get_events( + &self, + event_ids: &[sovereign_sdk::rpc::EventIdentifier], + ) -> Result>, anyhow::Error> { + self.ledger_db.get_events(event_ids) + } +} diff --git a/src/runtime.rs b/src/runtime.rs index 5ff136d..5c97870 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -37,12 +37,16 @@ use sov_modules_macros::{DispatchCall, DispatchQuery, Genesis, MessageCodec}; /// /// Similar mechanism works for queries with the difference that queries are submitted by users directly to the rollup node /// instead of going through the DA layer. -#[derive(Genesis, DispatchCall, DispatchQuery, MessageCodec)] +#[derive(Genesis, DispatchCall, DispatchQuery, MessageCodec, Clone)] #[serialization(borsh::BorshDeserialize, borsh::BorshSerialize)] pub(crate) struct Runtime { /// Definition of the first module in the rollup (must implement the sov_modules_api::Module trait). #[allow(unused)] election: election::Election, + #[allow(unused)] + pub(crate) bank: bank::Bank, + #[allow(unused)] + accounts: accounts::Accounts, } // TODO add macro to generate the following code. @@ -50,6 +54,8 @@ impl Runtime { pub(crate) fn new() -> Self { Self { election: election::Election::new(), + bank: bank::Bank::new(), + accounts: accounts::Accounts::new(), } } } diff --git a/src/tx_hooks_impl.rs b/src/tx_hooks_impl.rs index 7839081..5176d35 100644 --- a/src/tx_hooks_impl.rs +++ b/src/tx_hooks_impl.rs @@ -40,7 +40,7 @@ impl TxHooks for DemoAppTxHooks { type VerifiedTx = AppVerifiedTx; fn pre_dispatch_tx_hook( - &mut self, + &self, tx: Transaction, working_set: &mut WorkingSet<::Storage>, ) -> anyhow::Result { @@ -54,7 +54,7 @@ impl TxHooks for DemoAppTxHooks { } fn post_dispatch_tx_hook( - &mut self, + &self, tx: Self::VerifiedTx, working_set: &mut WorkingSet<::Storage>, ) { @@ -64,11 +64,34 @@ impl TxHooks for DemoAppTxHooks { // therefore this panic should never happen, we add it for sanity check. .unwrap_or_else(|e| panic!("Inconsistent nonce {e}")); } + + fn enter_apply_batch( + &self, + _sequencer: &[u8], + _working_set: &mut WorkingSet<::Storage>, + ) -> anyhow::Result<()> { + Ok(()) + } + + fn post_revert_apply_batch( + &self, + _working_set: &mut WorkingSet<::Storage>, + ) -> anyhow::Result<()> { + Ok(()) + } + + fn exit_apply_batch( + &self, + _amount: u64, + _working_set: &mut WorkingSet<::Storage>, + ) -> anyhow::Result<()> { + Ok(()) + } } impl DemoAppTxHooks { fn check_nonce_for_address( - &mut self, + &self, tx_nonce: u64, tx_pub_key: C::PublicKey, working_set: &mut WorkingSet, diff --git a/src/tx_verifier_impl.rs b/src/tx_verifier_impl.rs index 35b3439..2aad70b 100644 --- a/src/tx_verifier_impl.rs +++ b/src/tx_verifier_impl.rs @@ -23,7 +23,7 @@ impl Transaction { } } } - +#[derive(Clone)] pub(crate) struct DemoAppTxVerifier { _phantom: PhantomData, } From adbbb71316e3517143b161176ea71317bfe23760 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Thu, 20 Apr 2023 13:38:31 -0500 Subject: [PATCH 3/4] Upgrade to rpc-enabled SDK --- Cargo.toml | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f0df115..ae905fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,21 +13,17 @@ serde = { version = "1", features = ["derive"] } serde_json = "1" sha2 = "0.10.6" jupiter = { path ="../Jupiter"} -sov-app-template = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } -accounts = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } -bank = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } -election = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } -sovereign-sdk = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } -sov-state = { git = "https://github.com/Sovereign-Labs/sovereign.git", features = ["temp"], rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } -sov-modules-api = { git = "https://github.com/Sovereign-Labs/sovereign.git", features = ["mocks"], rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } -sov-modules-macros = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } -sovereign-db = { git = "https://github.com/Sovereign-Labs/sovereign.git", features = ["temp"], rev = "bfdb58159ff9215a84aa60b9a4d3ce1f32136597" } +sov-app-template = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "abfe1485f9c30e2c4a41ee8c9a18d9d646013c9c" } +accounts = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "abfe1485f9c30e2c4a41ee8c9a18d9d646013c9c" } +bank = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "abfe1485f9c30e2c4a41ee8c9a18d9d646013c9c" } +election = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "abfe1485f9c30e2c4a41ee8c9a18d9d646013c9c" } +sovereign-sdk = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "abfe1485f9c30e2c4a41ee8c9a18d9d646013c9c" } +sov-state = { git = "https://github.com/Sovereign-Labs/sovereign.git", features = ["temp"], rev = "abfe1485f9c30e2c4a41ee8c9a18d9d646013c9c" } +sov-modules-api = { git = "https://github.com/Sovereign-Labs/sovereign.git", features = ["mocks"], rev = "abfe1485f9c30e2c4a41ee8c9a18d9d646013c9c" } +sov-modules-macros = { git = "https://github.com/Sovereign-Labs/sovereign.git", rev = "abfe1485f9c30e2c4a41ee8c9a18d9d646013c9c" } +sovereign-db = { git = "https://github.com/Sovereign-Labs/sovereign.git", features = ["temp"], rev = "abfe1485f9c30e2c4a41ee8c9a18d9d646013c9c" } tracing = "0.1.37" tracing-subscriber = "0.3.16" anyhow = "1.0.62" jsonrpsee = { version = "0.16.2", features = ["http-client", "server"] } - -[patch.crates-io] -# Patch borsh until "bytes" support is added -borsh = { git = "https://github.com/preston-evans98/borsh-rs.git", branch = "release-2" } From 50d0eb3786630cd4b39a2714cd4dd3159725c21b Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Tue, 25 Apr 2023 10:42:22 -0500 Subject: [PATCH 4/4] Add ledger RPC endpoint --- src/rpc.rs | 69 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/src/rpc.rs b/src/rpc.rs index f5c4bb6..f56d277 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -4,11 +4,13 @@ use bank::{ query::{BankRpcImpl, BankRpcServer}, Bank, }; -use jsonrpsee::server::ServerHandle; +use jsonrpsee::{server::ServerHandle, RpcModule}; use sov_modules_api::mocks::MockContext; use sov_state::{mocks::MockStorageSpec, ProverStorage, WorkingSet}; use sovereign_db::ledger_db::LedgerDB; -use sovereign_sdk::rpc::{LedgerRpcProvider, QueryMode, SlotIdentifier}; +use sovereign_sdk::rpc::{ + BatchIdentifier, EventIdentifier, LedgerRpcProvider, QueryMode, SlotIdentifier, TxIdentifier, +}; use crate::{runtime::Runtime, tx_verifier_impl::DemoAppTxVerifier, Spec}; @@ -49,34 +51,49 @@ impl RpcProvider { _tx_verifier: tx_verifier, }; - let ledger_rpc = bank_rpc.clone(); - let mut bank_rpc = bank_rpc.into_rpc(); - bank_rpc.register_method("chain_getSlots", move |params, _| { - let slot_ids: Vec; - let query_mode: QueryMode; - (slot_ids, query_mode) = params.parse()?; - ledger_rpc - .get_slots(&slot_ids, query_mode) - .map_err(|e| e.into()) - })?; + + register_ledger_rpc(&mut bank_rpc)?; server.start(bank_rpc) } } -// TODO: Re-implement -// impl TransactionRpcProvider for RpcProvider { -// type Transaction = RawTx; - -// fn check_transaction(&self, tx: Self::Transaction) -> Result<(), anyhow::Error> { -// self.tx_verifier.verify_tx_stateless(tx).map(|_| ()) -// } +fn register_ledger_rpc(rpc: &mut RpcModule) -> Result<(), jsonrpsee::core::Error> { + rpc.register_method("ledger_head", move |_, db| { + db.get_head().map_err(|e| e.into()) + })?; + + rpc.register_method("ledger_getSlots", move |params, db| { + let ids: Vec; + let query_mode: QueryMode; + (ids, query_mode) = params.parse()?; + db.get_slots(&ids, query_mode).map_err(|e| e.into()) + })?; + + rpc.register_method("ledger_getBatches", move |params, db| { + let ids: Vec; + let query_mode: QueryMode; + (ids, query_mode) = params.parse()?; + db.get_batches(&ids, query_mode).map_err(|e| e.into()) + })?; + + rpc.register_method("ledger_getTransactions", move |params, db| { + let ids: Vec; + let query_mode: QueryMode; + (ids, query_mode) = params.parse()?; + db.get_transactions(&ids, query_mode).map_err(|e| e.into()) + })?; + + rpc.register_method("ledger_getEvents", move |params, db| { + let ids: Vec = params.parse()?; + db.get_events(&ids).map_err(|e| e.into()) + })?; + + Ok(()) +} -// fn submit_transaction(&self, tx: Self::Transaction) -> Result<(), anyhow::Error> { -// todo!() -// } -// } +// TODO: implement TransactionRpcProvider and expose an endpoint for it /// Delegate all the Ledger RPC methods to the LedgerDB. impl LedgerRpcProvider for RpcProvider { @@ -88,6 +105,10 @@ impl LedgerRpcProvider for RpcProvider { type EventResponse = as LedgerRpcProvider>::EventResponse; + fn get_head(&self) -> Result, anyhow::Error> { + self.ledger_db.get_head() + } + fn get_slots( &self, slot_ids: &[sovereign_sdk::rpc::SlotIdentifier], @@ -115,7 +136,7 @@ impl LedgerRpcProvider for RpcProvider { fn get_events( &self, event_ids: &[sovereign_sdk::rpc::EventIdentifier], - ) -> Result>, anyhow::Error> { + ) -> Result>, anyhow::Error> { self.ledger_db.get_events(event_ids) } }