Skip to content

Commit

Permalink
Add RPC for chain-state module (#760)
Browse files Browse the repository at this point in the history
* Add RPC endpoint for chain state module, so it can be plugged into runtime

* Move tests to integration tests

* Fix native feature gating

* Fixed check features
  • Loading branch information
citizen-stig authored Aug 30, 2023
1 parent 461a749 commit 9bcd69c
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 59 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ sov-state = { path = "../../sov-state", version = "0.1" }
sov-rollup-interface = { path = "../../../rollup-interface", version = "0.1" }

[dev-dependencies]
tempfile = { workspace = true }
sov-bank = { path = "../sov-bank" }
sov-value-setter = { path = "../examples/sov-value-setter" }
sov-modules-stf-template = { path = "../../sov-modules-stf-template" }
sov-data-generators = { path = "../../utils/sov-data-generators" }
tempfile = { workspace = true }
sov-chain-state = { path = ".", features = ["native"] }


[features]
default = []
Expand Down
14 changes: 7 additions & 7 deletions module-system/module-implementations/sov-chain-state/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ use sov_state::WorkingSet;

use crate::{ChainState, StateTransitionId, TransitionHeight};

impl<
Ctx: sov_modules_api::Context,
Cond: ValidityCondition + BorshSerialize + BorshDeserialize,
> ChainState<Ctx, Cond>
impl<C, Cond> ChainState<C, Cond>
where
C: sov_modules_api::Context,
Cond: ValidityCondition + BorshSerialize + BorshDeserialize,
{
/// Increment the current slot height
pub fn increment_slot_height(&self, working_set: &mut WorkingSet<Ctx::Storage>) {
pub(crate) fn increment_slot_height(&self, working_set: &mut WorkingSet<C::Storage>) {
let current_height = self
.slot_height
.get(working_set)
Expand All @@ -20,11 +20,11 @@ impl<
}

/// Store the previous state transition
pub fn store_state_transition(
pub(crate) fn store_state_transition(
&self,
height: TransitionHeight,
transition: StateTransitionId<Cond>,
working_set: &mut WorkingSet<Ctx::Storage>,
working_set: &mut WorkingSet<C::Storage>,
) {
self.historical_transitions
.set(&height, &transition, working_set);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use sov_state::{Storage, WorkingSet};
use super::ChainState;
use crate::{StateTransitionId, TransitionInProgress};

impl<Ctx: Context, Cond: ValidityCondition> SlotHooks<Cond> for ChainState<Ctx, Cond> {
type Context = Ctx;
impl<C: Context, Cond: ValidityCondition> SlotHooks<Cond> for ChainState<C, Cond> {
type Context = C;

fn begin_slot_hook(
&self,
Expand Down
51 changes: 41 additions & 10 deletions module-system/module-implementations/sov-chain-state/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ pub mod genesis;
/// Hook implementation for the module
pub mod hooks;

#[cfg(test)]
pub mod tests;

/// The query interface with the module
#[cfg(feature = "native")]
pub mod query;

use borsh::{BorshDeserialize, BorshSerialize};
#[cfg(feature = "native")]
pub use query::{ChainStateRpcImpl, ChainStateRpcServer};
use sov_modules_api::Error;
use sov_modules_macros::ModuleInfo;
use sov_rollup_interface::zk::{ValidityCondition, ValidityConditionChecker};
Expand Down Expand Up @@ -102,10 +101,10 @@ impl<Cond> TransitionInProgress<Cond> {
/// - Must contain `[address]` field
/// - Can contain any number of ` #[state]` or `[module]` fields
#[derive(ModuleInfo)]
pub struct ChainState<Ctx: sov_modules_api::Context, Cond: ValidityCondition> {
pub struct ChainState<C: sov_modules_api::Context, Cond: ValidityCondition> {
/// Address of the module.
#[address]
pub address: Ctx::Address,
pub address: C::Address,

/// The current block height
#[state]
Expand Down Expand Up @@ -139,10 +138,42 @@ pub struct ChainStateConfig {
pub initial_slot_height: TransitionHeight,
}

impl<Ctx: sov_modules_api::Context, Cond: ValidityCondition> sov_modules_api::Module
for ChainState<Ctx, Cond>
impl<C: sov_modules_api::Context, Cond: ValidityCondition> ChainState<C, Cond> {
/// Returns transition height in the current slot
pub fn get_slot_height(&self, working_set: &mut WorkingSet<C::Storage>) -> TransitionHeight {
self.slot_height
.get(working_set)
.expect("Slot height should be set at initialization")
}

/// Return the genesis hash of the module.
pub fn get_genesis_hash(&self, working_set: &mut WorkingSet<C::Storage>) -> Option<[u8; 32]> {
self.genesis_hash.get(working_set)
}

/// Returns the transition in progress of the module.
pub fn get_in_progress_transition(
&self,
working_set: &mut WorkingSet<C::Storage>,
) -> Option<TransitionInProgress<Cond>> {
self.in_progress_transition.get(working_set)
}

/// Returns the completed transition associated with the provided `transition_num`.
pub fn get_historical_transitions(
&self,
transition_num: TransitionHeight,
working_set: &mut WorkingSet<C::Storage>,
) -> Option<StateTransitionId<Cond>> {
self.historical_transitions
.get(&transition_num, working_set)
}
}

impl<C: sov_modules_api::Context, Cond: ValidityCondition> sov_modules_api::Module
for ChainState<C, Cond>
{
type Context = Ctx;
type Context = C;

type Config = ChainStateConfig;

Expand All @@ -151,7 +182,7 @@ impl<Ctx: sov_modules_api::Context, Cond: ValidityCondition> sov_modules_api::Mo
fn genesis(
&self,
config: &Self::Config,
working_set: &mut WorkingSet<Ctx::Storage>,
working_set: &mut WorkingSet<C::Storage>,
) -> Result<(), Error> {
// The initialization logic
Ok(self.init_module(config, working_set)?)
Expand Down
41 changes: 8 additions & 33 deletions module-system/module-implementations/sov-chain-state/src/query.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,19 @@
use jsonrpsee::core::RpcResult;
use sov_modules_api::macros::rpc_gen;
use sov_rollup_interface::zk::ValidityCondition;
use sov_state::WorkingSet;

use super::ChainState;
use crate::{StateTransitionId, TransitionHeight, TransitionInProgress};

/// Structure returned by the query methods.
pub struct Response {
/// Value returned by the queries
pub value: u64,
}
use crate::{ChainState, TransitionHeight};

#[rpc_gen(client, server, namespace = "chainState")]
impl<C: sov_modules_api::Context, Cond: ValidityCondition> ChainState<C, Cond> {
/// Get the height of the current slot.
/// Panics if the slot height is not set
pub fn get_slot_height(&self, working_set: &mut WorkingSet<C::Storage>) -> TransitionHeight {
self.slot_height
.get(working_set)
.expect("Slot height should be set at initialization")
}

/// Return the genesis hash of the module.
pub fn get_genesis_hash(&self, working_set: &mut WorkingSet<C::Storage>) -> Option<[u8; 32]> {
self.genesis_hash.get(working_set)
}

/// Returns the transition in progress of the module.
pub fn get_in_progress_transition(
&self,
working_set: &mut WorkingSet<C::Storage>,
) -> Option<TransitionInProgress<Cond>> {
self.in_progress_transition.get(working_set)
}

/// Returns the completed transition associated with the provided `transition_num`.
pub fn get_historical_transitions(
#[rpc_method(name = "getSlotHeight")]
pub fn get_slot_height_rpc(
&self,
transition_num: TransitionHeight,
working_set: &mut WorkingSet<C::Storage>,
) -> Option<StateTransitionId<Cond>> {
self.historical_transitions
.get(&transition_num, working_set)
) -> RpcResult<TransitionHeight> {
Ok(self.get_slot_height(working_set))
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use sov_chain_state::{ChainState, ChainStateConfig, StateTransitionId, TransitionInProgress};
use sov_modules_api::default_context::DefaultContext;
use sov_modules_api::hooks::SlotHooks;
use sov_modules_api::Genesis;
use sov_rollup_interface::mocks::{MockBlock, MockBlockHeader, MockHash, MockValidityCond};
use sov_state::{ProverStorage, Storage, WorkingSet};

use crate::{ChainState, ChainStateConfig, StateTransitionId, TransitionInProgress};

/// This simply tests that the chain_state reacts properly with the invocation of the `begin_slot`
/// hook. For more complete integration tests, feel free to have a look at the integration tests folder.
#[test]
Expand Down Expand Up @@ -60,7 +59,7 @@ fn test_simple_chain_state() {

assert_eq!(stored_root, init_root_hash, "Genesis hashes don't match");

// Check that the slot height have been updated
// Check that the slot height has been updated
let new_height_storage = chain_state.get_slot_height(&mut working_set);

assert_eq!(
Expand Down Expand Up @@ -101,7 +100,7 @@ fn test_simple_chain_state() {

chain_state.begin_slot_hook(&new_slot_data, &mut working_set);

// Check that the slot height have been updated correctly
// Check that the slot height has been updated correctly
let new_height_storage = chain_state.get_slot_height(&mut working_set);
assert_eq!(
new_height_storage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ fn main() {
let actual_foo = <MyEnum as sov_modules_api::CliWalletArg>::CliStringRepr::try_parse_from(&[
"myenum", "foo", "1", "hello",
])
.expect("parsing must succed")
.expect("parsing must succeed")
.into();
assert_eq!(expected_foo, actual_foo);

let expected_bar = MyEnum::Bar(2);
let actual_bar = <MyEnum as sov_modules_api::CliWalletArg>::CliStringRepr::try_parse_from(&[
"myenum", "bar", "2",
])
.expect("parsing must succed")
.expect("parsing must succeed")
.into();

assert_eq!(expected_bar, actual_bar);
Expand Down

0 comments on commit 9bcd69c

Please sign in to comment.