Skip to content

Commit

Permalink
runtime/consensus: Add support for querying round roots
Browse files Browse the repository at this point in the history
  • Loading branch information
ptrus committed Nov 21, 2023
1 parent 1c49e4c commit a6b0094
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 8 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions runtime-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ license = "Apache-2.0"

[dependencies]
cbor = { version = "0.5.1", package = "oasis-cbor" }
oasis-core-runtime = { git = "https://github.com/oasisprotocol/oasis-core", tag = "v23.0.4" }
oasis-core-keymanager = { git = "https://github.com/oasisprotocol/oasis-core", tag = "v23.0.4" }
oasis-core-runtime = { git = "https://github.com/oasisprotocol/oasis-core", branch = "stable/23.0.x" }
oasis-core-keymanager = { git = "https://github.com/oasisprotocol/oasis-core", branch = "stable/23.0.x" }
oasis-runtime-sdk-macros = { path = "../runtime-sdk-macros", optional = true }

# Third party.
Expand Down
64 changes: 60 additions & 4 deletions runtime-sdk/src/modules/consensus/mod.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
//! Consensus module.
//!
//! Consensus module.
//! Low level consensus module for communicating with the consensus layer.
use std::{convert::TryInto, num::NonZeroUsize, str::FromStr, sync::Mutex};

use oasis_runtime_sdk_macros::handler;
use once_cell::sync::Lazy;
use thiserror::Error;

use oasis_core_runtime::{
common::versioned::Versioned,
common::{namespace::Namespace, versioned::Versioned},
consensus::{
beacon::EpochTime,
roothash::{Message, StakingMessage},
roothash::{Error as RoothashError, Message, RoundRoots, StakingMessage},
staking,
staking::{Account as ConsensusAccount, Delegation as ConsensusDelegation},
state::{
beacon::ImmutableState as BeaconImmutableState,
roothash::ImmutableState as RoothashImmutableState,
staking::ImmutableState as StakingImmutableState, StateError,
},
HEIGHT_LATEST,
Expand All @@ -23,26 +25,40 @@ use oasis_core_runtime::{

use crate::{
context::{Context, TxContext},
core::common::crypto::hash::Hash,
history, migration, module,
module::{Module as _, Parameters as _},
modules, sdk_derive,
modules,
modules::core::API as _,
sdk_derive,
types::{
address::{Address, SignatureAddressSpec},
message::MessageEventHookInvocation,
token,
transaction::AddressSpec,
},
Runtime,
};

#[cfg(test)]
mod test;
pub mod types;

/// Unique module name.
const MODULE_NAME: &str = "consensus";

/// Gas costs.
#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
pub struct GasCosts {
/// Cost of the internal round_roots call.
pub round_roots: u64,
}

/// Parameters for the consensus module.
#[derive(Clone, Debug, PartialEq, Eq, cbor::Encode, cbor::Decode)]
pub struct Parameters {
pub gas_costs: GasCosts,

pub consensus_denomination: token::Denomination,
pub consensus_scaling_factor: u64,

Expand All @@ -56,6 +72,7 @@ pub struct Parameters {
impl Default for Parameters {
fn default() -> Self {
Self {
gas_costs: Default::default(),
consensus_denomination: token::Denomination::from_str("TEST").unwrap(),
consensus_scaling_factor: 1,
min_delegate_amount: 0,
Expand Down Expand Up @@ -194,6 +211,13 @@ pub trait API {
/// Determine consensus height corresponding to the given epoch transition. This query may be
/// expensive in case the epoch is far back.
fn height_for_epoch<C: Context>(ctx: &C, epoch: EpochTime) -> Result<u64, Error>;

/// Round roots return the round roots for the given runtime ID and round.
fn round_roots<C: Context>(
ctx: &C,
runtime_id: Namespace,
round: u64,
) -> Result<Option<RoundRoots>, Error>;
}

pub struct Module;
Expand Down Expand Up @@ -231,6 +255,27 @@ impl Module {
// Set genesis parameters.
Self::set_params(genesis.parameters);
}

#[handler(call = "consensus.RoundRoot", internal)]
fn internal_round_root<C: TxContext>(
ctx: &mut C,
body: types::RoundRootBody,
) -> Result<Option<Hash>, Error> {
let params = Self::params();
<C::Runtime as Runtime>::Core::use_tx_gas(ctx, params.gas_costs.round_roots)?;

if !body.kind.is_valid() {
return Err(Error::InvalidArgument);
}

Ok(
Self::round_roots(ctx, body.runtime_id, body.round)?.map(|rr| match body.kind {
types::RootKind::IO => rr.io_root,
types::RootKind::State => rr.state_root,
_ => panic!("invalid root kind"), // Covered by the is_valid check above.
}),
)
}
}

impl API for Module {
Expand Down Expand Up @@ -418,6 +463,17 @@ impl API for Module {
height -= 1;
}
}

fn round_roots<C: Context>(
ctx: &C,
runtime_id: Namespace,
round: u64,
) -> Result<Option<RoundRoots>, Error> {
let roothash = RoothashImmutableState::new(ctx.consensus_state());
roothash
.round_roots(runtime_id, round)
.map_err(Error::InternalStateError)
}
}

impl module::TransactionHandler for Module {}
Expand Down
27 changes: 27 additions & 0 deletions runtime-sdk/src/modules/consensus/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use oasis_core_runtime::common::namespace::Namespace;

/// Kind of root.
#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
#[cfg_attr(test, derive(PartialEq, Eq))]
#[repr(u8)]
pub enum RootKind {
#[default]
Invalid = 0,
State = 1,
IO = 2,
}

impl RootKind {
/// Whether the root kind is valid.
pub fn is_valid(&self) -> bool {
!matches!(self, Self::Invalid)
}
}

/// Internal round root call body.
#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
pub struct RoundRootBody {
pub runtime_id: Namespace,
pub round: u64,
pub kind: RootKind,
}
1 change: 1 addition & 0 deletions tests/runtimes/benchmarking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ impl sdk::Runtime for Runtime {
},
modules::consensus::Genesis {
parameters: modules::consensus::Parameters {
gas_costs: Default::default(),
// Consensus layer denomination is the native denomination of this runtime.
consensus_denomination: Denomination::NATIVE,
// Scale to 18 decimal places as this is what is expected in the EVM ecosystem.
Expand Down
1 change: 1 addition & 0 deletions tests/runtimes/simple-consensus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ impl sdk::Runtime for Runtime {
},
modules::consensus::Genesis {
parameters: modules::consensus::Parameters {
gas_costs: Default::default(),
consensus_denomination: "TEST".parse().unwrap(),
// Test scaling consensus base units when transferring them into the runtime.
consensus_scaling_factor: 1000,
Expand Down
1 change: 1 addition & 0 deletions tests/runtimes/simple-evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ impl sdk::Runtime for Runtime {
},
modules::consensus::Genesis {
parameters: modules::consensus::Parameters {
gas_costs: Default::default(),
consensus_denomination: Denomination::NATIVE,
// Test scaling consensus base units when transferring them into the runtime.
consensus_scaling_factor: 1000,
Expand Down

0 comments on commit a6b0094

Please sign in to comment.