From 08bc052873b751942ab7b22a534f247d192434b2 Mon Sep 17 00:00:00 2001 From: Mario Cao Date: Fri, 7 Jun 2024 11:44:48 +0200 Subject: [PATCH 01/14] feat(common): add staking query --- Cargo.toml | 2 ++ common/Cargo.toml | 14 +++++++++++++ common/src/lib.rs | 2 ++ common/src/msgs/mod.rs | 1 + common/src/msgs/staking/mod.rs | 4 ++++ common/src/msgs/staking/query.rs | 26 ++++++++++++++++++++++++ common/src/msgs/staking/types.rs | 34 ++++++++++++++++++++++++++++++++ common/src/types.rs | 1 + 8 files changed, 84 insertions(+) create mode 100644 common/Cargo.toml create mode 100644 common/src/lib.rs create mode 100644 common/src/msgs/mod.rs create mode 100644 common/src/msgs/staking/mod.rs create mode 100644 common/src/msgs/staking/query.rs create mode 100644 common/src/msgs/staking/types.rs create mode 100644 common/src/types.rs diff --git a/Cargo.toml b/Cargo.toml index 6f904d9b..872b78c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" members = [ + "common", "contract", # "fuzz", "xtask", @@ -40,4 +41,5 @@ semver = { version = "1.0", features = ["serde"] } vrf-rs = "0.0.0" xshell = "0.2" +seda-contract-common = { path = "./common"} seda-contract = { path = "./contract" } diff --git a/common/Cargo.toml b/common/Cargo.toml new file mode 100644 index 00000000..19b9b0e5 --- /dev/null +++ b/common/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "seda-contract-common" +version = "0.1.0" +edition = "2021" + +[features] +cosmwasm = ["cosmwasm-schema", "cosmwasm-std"] + +[dependencies] +cosmwasm-schema = { workspace = true, optional = true} +cosmwasm-std = { workspace = true, optional = true} +serde = { workspace = true } +schemars = { workspace = true } + diff --git a/common/src/lib.rs b/common/src/lib.rs new file mode 100644 index 00000000..a6643b5c --- /dev/null +++ b/common/src/lib.rs @@ -0,0 +1,2 @@ +pub mod msgs; +pub mod types; diff --git a/common/src/msgs/mod.rs b/common/src/msgs/mod.rs new file mode 100644 index 00000000..ba07cfb7 --- /dev/null +++ b/common/src/msgs/mod.rs @@ -0,0 +1 @@ +pub mod staking; diff --git a/common/src/msgs/staking/mod.rs b/common/src/msgs/staking/mod.rs new file mode 100644 index 00000000..3ac85b9f --- /dev/null +++ b/common/src/msgs/staking/mod.rs @@ -0,0 +1,4 @@ +pub mod query; + +mod types; +pub use types::*; diff --git a/common/src/msgs/staking/query.rs b/common/src/msgs/staking/query.rs new file mode 100644 index 00000000..16b14b1d --- /dev/null +++ b/common/src/msgs/staking/query.rs @@ -0,0 +1,26 @@ +#[cfg(feature = "cosmwasm")] +use cosmwasm_schema::{cw_serde, QueryResponses}; +#[cfg(feature = "cosmwasm")] +use cosmwasm_std::Uint128; +#[cfg(not(feature = "cosmwasm"))] +use serde::Serialize; + +#[cfg(feature = "cosmwasm")] +use super::{Staker, StakerAndSeq, StakingConfig}; +use crate::types::PublicKey; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(feature = "cosmwasm", derive(QueryResponses))] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +pub enum QueryMsg { + #[cfg_attr(feature = "cosmwasm", returns(Option))] + GetStaker { public_key: PublicKey }, + #[cfg_attr(feature = "cosmwasm", returns(Uint128))] + GetAccountSeq { public_key: PublicKey }, + #[cfg_attr(feature = "cosmwasm", returns(StakerAndSeq))] + GetStakerAndSeq { public_key: PublicKey }, + #[cfg_attr(feature = "cosmwasm", returns(bool))] + IsExecutorEligible { public_key: PublicKey }, + #[cfg_attr(feature = "cosmwasm", returns(StakingConfig))] + GetStakingConfig {}, +} diff --git a/common/src/msgs/staking/types.rs b/common/src/msgs/staking/types.rs new file mode 100644 index 00000000..36dd8f14 --- /dev/null +++ b/common/src/msgs/staking/types.rs @@ -0,0 +1,34 @@ +#[cfg(feature = "cosmwasm")] +use cosmwasm_std::Uint128; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[cfg(feature = "cosmwasm")] +type U128 = Uint128; +#[cfg(not(feature = "cosmwasm"))] +type U128 = String; + +/// A data request executor with staking info and optional p2p multi address +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, JsonSchema)] +pub struct Staker { + pub memo: Option, + pub tokens_staked: U128, + pub tokens_pending_withdrawal: U128, +} + +/// Governance-controlled configuration parameters +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, JsonSchema)] +pub struct StakingConfig { + /// Minimum amount of SEDA tokens required to register as a data request executor + pub minimum_stake_to_register: U128, + /// Minimum amount of SEDA tokens required to be eligible for committee inclusion + pub minimum_stake_for_committee_eligibility: U128, + /// Whether the allowlist is enabled + pub allowlist_enabled: bool, +} + +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, JsonSchema)] +pub struct StakerAndSeq { + pub staker: Option, + pub seq: U128, +} diff --git a/common/src/types.rs b/common/src/types.rs new file mode 100644 index 00000000..4b69ada9 --- /dev/null +++ b/common/src/types.rs @@ -0,0 +1 @@ +pub type PublicKey = Vec; From 107a5e8508e736f92c3e28b6431ff023a6e4ebe1 Mon Sep 17 00:00:00 2001 From: Mario Cao Date: Fri, 7 Jun 2024 12:08:23 +0200 Subject: [PATCH 02/14] refactor(contract): use staking query from common --- contract/Cargo.toml | 17 ++++---- contract/src/msgs/data_requests/query.rs | 1 - contract/src/msgs/mod.rs | 6 ++- .../staking/execute/register_and_stake.rs | 3 +- contract/src/msgs/staking/mod.rs | 10 +---- contract/src/msgs/staking/query.rs | 43 ++++++------------- contract/src/msgs/staking/state.rs | 2 + contract/src/msgs/staking/test_helpers.rs | 8 ++-- contract/src/msgs/staking/tests.rs | 2 + contract/src/msgs/staking/utils.rs | 2 + 10 files changed, 41 insertions(+), 53 deletions(-) diff --git a/contract/Cargo.toml b/contract/Cargo.toml index 29cd0854..ff05397c 100644 --- a/contract/Cargo.toml +++ b/contract/Cargo.toml @@ -4,9 +4,9 @@ version = "0.1.0" edition = "2021" exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. - "contract.wasm", - "hash.txt", + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", ] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -35,14 +35,15 @@ cw-utils = { workspace = true } cw2 = { workspace = true } hex = { workspace = true } schemars = { workspace = true } +seda-contract-common ={ workspace = true, features = ["cosmwasm"]} semver = { workspace = true } serde = { workspace = true } -serde-big-array.workspace = true -sha3.workspace = true +serde-big-array = { workspace = true } +sha3 = { workspace = true } thiserror = { workspace = true } -vrf-rs.workspace = true +vrf-rs = { workspace = true } [dev-dependencies] +cw-multi-test = { workspace = true } k256 = { workspace = true } -cw-multi-test.workspace = true -serde_json.workspace = true +serde_json = { workspace = true } diff --git a/contract/src/msgs/data_requests/query.rs b/contract/src/msgs/data_requests/query.rs index 73653622..211d13d4 100644 --- a/contract/src/msgs/data_requests/query.rs +++ b/contract/src/msgs/data_requests/query.rs @@ -2,7 +2,6 @@ use super::*; #[cw_serde] #[derive(QueryResponses)] - pub enum QueryMsg { #[returns(DataRequest)] GetDataRequest { dr_id: Hash }, diff --git a/contract/src/msgs/mod.rs b/contract/src/msgs/mod.rs index 8aeefabf..92c7651e 100644 --- a/contract/src/msgs/mod.rs +++ b/contract/src/msgs/mod.rs @@ -15,6 +15,10 @@ pub mod data_requests; pub mod owner; pub mod staking; +pub trait QueryHandler { + fn query(msg: Self, deps: Deps, _env: Env) -> StdResult; +} + #[cw_serde] #[serde(untagged)] pub enum ExecuteMsg { @@ -48,7 +52,7 @@ impl QueryMsg { pub fn query(self, deps: Deps, env: Env) -> StdResult { match self { QueryMsg::DataRequest(msg) => msg.query(deps, env), - QueryMsg::Staking(msg) => msg.query(deps, env), + QueryMsg::Staking(msg) => QueryHandler::query(msg, deps, env), QueryMsg::Owner(msg) => msg.query(deps, env), } } diff --git a/contract/src/msgs/staking/execute/register_and_stake.rs b/contract/src/msgs/staking/execute/register_and_stake.rs index b2ce1507..d379142d 100644 --- a/contract/src/msgs/staking/execute/register_and_stake.rs +++ b/contract/src/msgs/staking/execute/register_and_stake.rs @@ -1,8 +1,9 @@ +use seda_contract_common::msgs::staking::Staker; + use self::staking::owner::utils::is_staker_allowed; use super::*; use crate::{ crypto::{hash, verify_proof}, - msgs::staking::Staker, state::{inc_get_seq, CHAIN_ID, TOKEN}, types::{Hasher, PublicKey}, utils::get_attached_funds, diff --git a/contract/src/msgs/staking/mod.rs b/contract/src/msgs/staking/mod.rs index 94f9e351..c0b3ca33 100644 --- a/contract/src/msgs/staking/mod.rs +++ b/contract/src/msgs/staking/mod.rs @@ -2,6 +2,8 @@ use super::*; pub mod execute; pub mod query; +pub use seda_contract_common::msgs::staking::query::QueryMsg; + pub mod state; pub mod utils; @@ -11,14 +13,6 @@ mod tests; #[cfg(test)] pub mod test_helpers; -/// A data request executor with staking info and optional p2p multi address -#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, JsonSchema)] -pub struct Staker { - pub memo: Option, - pub tokens_staked: Uint128, - pub tokens_pending_withdrawal: Uint128, -} - /// Governance-controlled configuration parameters #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, JsonSchema)] pub struct StakingConfig { diff --git a/contract/src/msgs/staking/query.rs b/contract/src/msgs/staking/query.rs index 40324383..bd6b1ccd 100644 --- a/contract/src/msgs/staking/query.rs +++ b/contract/src/msgs/staking/query.rs @@ -1,31 +1,12 @@ +pub use seda_contract_common::msgs::staking::query::QueryMsg; +use seda_contract_common::msgs::staking::StakerAndSeq; + use super::*; use crate::state::get_seq; -#[cw_serde] -pub struct StakerAndSeq { - pub staker: Option, - pub seq: Uint128, -} - -#[cw_serde] -#[derive(QueryResponses)] - -pub enum QueryMsg { - #[returns(Option)] - GetStaker { public_key: PublicKey }, - #[returns(Uint128)] - GetAccountSeq { public_key: PublicKey }, - #[returns(StakerAndSeq)] - GetStakerAndSeq { public_key: PublicKey }, - #[returns(bool)] - IsExecutorEligible { public_key: PublicKey }, - #[returns(super::StakingConfig)] - GetStakingConfig {}, -} - -impl QueryMsg { - pub fn query(self, deps: Deps, _env: Env) -> StdResult { - match self { +impl QueryHandler for QueryMsg { + fn query(msg: QueryMsg, deps: Deps, _env: Env) -> StdResult { + match msg { QueryMsg::GetStaker { public_key: executor } => to_json_binary(&utils::get_staker(deps, &executor)?), QueryMsg::GetAccountSeq { public_key } => { let seq: Uint128 = get_seq(deps.storage, &public_key)?.into(); @@ -44,9 +25,9 @@ impl QueryMsg { } } -#[cfg(test)] -impl From for super::QueryMsg { - fn from(value: QueryMsg) -> Self { - Self::Staking(value) - } -} +// #[cfg(test)] +// impl From for super::QueryMsg { +// fn from(value: QueryMsg) -> Self { +// Self::Staking(value) +// } +// } diff --git a/contract/src/msgs/staking/state.rs b/contract/src/msgs/staking/state.rs index f77dea01..a79a8c87 100644 --- a/contract/src/msgs/staking/state.rs +++ b/contract/src/msgs/staking/state.rs @@ -1,3 +1,5 @@ +use seda_contract_common::msgs::staking::Staker; + use super::*; /// Governance-controlled configuration parameters. diff --git a/contract/src/msgs/staking/test_helpers.rs b/contract/src/msgs/staking/test_helpers.rs index 7916f515..41ca93bb 100644 --- a/contract/src/msgs/staking/test_helpers.rs +++ b/contract/src/msgs/staking/test_helpers.rs @@ -1,3 +1,5 @@ +use seda_contract_common::msgs::staking::{query::QueryMsg, Staker}; + use super::{execute::*, *}; use crate::{ crypto::hash, @@ -59,7 +61,7 @@ impl TestInfo { #[track_caller] pub fn get_staker(&self, executor: PublicKey) -> Option { - self.query(query::QueryMsg::GetStaker { public_key: executor }).unwrap() + self.query(QueryMsg::GetStaker { public_key: executor }).unwrap() } #[track_caller] @@ -142,12 +144,12 @@ impl TestInfo { #[track_caller] pub fn is_executor_eligible(&self, executor: PublicKey) -> bool { - self.query(query::QueryMsg::IsExecutorEligible { public_key: executor }) + self.query(QueryMsg::IsExecutorEligible { public_key: executor }) .unwrap() } #[track_caller] pub fn get_account_sequence(&self, public_key: PublicKey) -> Uint128 { - self.query(query::QueryMsg::GetAccountSeq { public_key }).unwrap() + self.query(QueryMsg::GetAccountSeq { public_key }).unwrap() } } diff --git a/contract/src/msgs/staking/tests.rs b/contract/src/msgs/staking/tests.rs index 9fff01d7..c78aeb55 100644 --- a/contract/src/msgs/staking/tests.rs +++ b/contract/src/msgs/staking/tests.rs @@ -1,3 +1,5 @@ +use seda_contract_common::msgs::staking::Staker; + use super::*; use crate::TestInfo; diff --git a/contract/src/msgs/staking/utils.rs b/contract/src/msgs/staking/utils.rs index 8d377c58..a7174d17 100644 --- a/contract/src/msgs/staking/utils.rs +++ b/contract/src/msgs/staking/utils.rs @@ -1,3 +1,5 @@ +use seda_contract_common::msgs::staking::Staker; + use super::{ state::{CONFIG, STAKERS}, *, From 326d65ebb67e576fa64c587dc32a2cbdb6b71843 Mon Sep 17 00:00:00 2001 From: Mario Cao Date: Fri, 7 Jun 2024 18:13:32 +0200 Subject: [PATCH 03/14] feat(common): add test of staking functions --- common/Cargo.toml | 1 - common/src/msgs/mod.rs | 11 ++++++++ common/src/msgs/staking/execute/mod.rs | 26 +++++++++++++++++++ common/src/msgs/staking/execute/set_config.rs | 11 ++++++++ common/src/msgs/staking/execute/stake.rs | 20 ++++++++++++++ common/src/msgs/staking/execute/unstake.rs | 14 ++++++++++ common/src/msgs/staking/execute/withdraw.rs | 14 ++++++++++ common/src/msgs/staking/mod.rs | 4 +++ common/src/msgs/staking/query.rs | 1 + common/src/msgs/staking/types.rs | 7 +---- common/src/types.rs | 8 ++++++ 11 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 common/src/msgs/staking/execute/mod.rs create mode 100644 common/src/msgs/staking/execute/set_config.rs create mode 100644 common/src/msgs/staking/execute/stake.rs create mode 100644 common/src/msgs/staking/execute/unstake.rs create mode 100644 common/src/msgs/staking/execute/withdraw.rs diff --git a/common/Cargo.toml b/common/Cargo.toml index 19b9b0e5..785cba93 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -11,4 +11,3 @@ cosmwasm-schema = { workspace = true, optional = true} cosmwasm-std = { workspace = true, optional = true} serde = { workspace = true } schemars = { workspace = true } - diff --git a/common/src/msgs/mod.rs b/common/src/msgs/mod.rs index ba07cfb7..3dafd831 100644 --- a/common/src/msgs/mod.rs +++ b/common/src/msgs/mod.rs @@ -1 +1,12 @@ +#[cfg(feature = "cosmwasm")] +use cosmwasm_schema::cw_serde; + pub mod staking; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(feature = "cosmwasm", serde(untagged))] +pub enum ExecuteMsg { + // DataRequest(Box), + Staking(staking::execute::ExecuteMsg), + // Owner(owner::execute::ExecuteMsg), +} diff --git a/common/src/msgs/staking/execute/mod.rs b/common/src/msgs/staking/execute/mod.rs new file mode 100644 index 00000000..4181b778 --- /dev/null +++ b/common/src/msgs/staking/execute/mod.rs @@ -0,0 +1,26 @@ +#[cfg(feature = "cosmwasm")] +use cosmwasm_schema::cw_serde; +#[cfg(not(feature = "cosmwasm"))] +use serde::Serialize; + +use super::*; + +pub mod stake; +pub mod unstake; +pub mod withdraw; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub enum ExecuteMsg { + Stake(stake::Execute), + Unstake(unstake::Execute), + Withdraw(withdraw::Execute), + SetStakingConfig(StakingConfig), +} + +impl From for super::ExecuteMsg { + fn from(value: ExecuteMsg) -> Self { + Self::Staking(value) + } +} diff --git a/common/src/msgs/staking/execute/set_config.rs b/common/src/msgs/staking/execute/set_config.rs new file mode 100644 index 00000000..61ba700d --- /dev/null +++ b/common/src/msgs/staking/execute/set_config.rs @@ -0,0 +1,11 @@ +#[cfg(feature = "cosmwasm")] +use cosmwasm_schema::cw_serde; +#[cfg(not(feature = "cosmwasm"))] +use serde::Serialize; + +use crate::msgs::staking::StakingConfig; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +pub struct Execute { + pub config: StakingConfig, +} diff --git a/common/src/msgs/staking/execute/stake.rs b/common/src/msgs/staking/execute/stake.rs new file mode 100644 index 00000000..8007c2a1 --- /dev/null +++ b/common/src/msgs/staking/execute/stake.rs @@ -0,0 +1,20 @@ +#[cfg(feature = "cosmwasm")] +use cosmwasm_schema::cw_serde; +#[cfg(not(feature = "cosmwasm"))] +use serde::Serialize; + +use crate::types::PublicKey; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +pub struct Execute { + pub public_key: PublicKey, + pub proof: Vec, + pub memo: Option, +} + +impl From for super::ExecuteMsg { + fn from(value: Execute) -> Self { + super::ExecuteMsg::Stake(value) + } +} diff --git a/common/src/msgs/staking/execute/unstake.rs b/common/src/msgs/staking/execute/unstake.rs new file mode 100644 index 00000000..a512c5af --- /dev/null +++ b/common/src/msgs/staking/execute/unstake.rs @@ -0,0 +1,14 @@ +#[cfg(feature = "cosmwasm")] +use cosmwasm_schema::cw_serde; +#[cfg(not(feature = "cosmwasm"))] +use serde::Serialize; + +use crate::types::{PublicKey, U128}; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +pub struct Execute { + pub public_key: PublicKey, + pub proof: Vec, + pub amount: U128, +} diff --git a/common/src/msgs/staking/execute/withdraw.rs b/common/src/msgs/staking/execute/withdraw.rs new file mode 100644 index 00000000..a512c5af --- /dev/null +++ b/common/src/msgs/staking/execute/withdraw.rs @@ -0,0 +1,14 @@ +#[cfg(feature = "cosmwasm")] +use cosmwasm_schema::cw_serde; +#[cfg(not(feature = "cosmwasm"))] +use serde::Serialize; + +use crate::types::{PublicKey, U128}; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +pub struct Execute { + pub public_key: PublicKey, + pub proof: Vec, + pub amount: U128, +} diff --git a/common/src/msgs/staking/mod.rs b/common/src/msgs/staking/mod.rs index 3ac85b9f..acce3b88 100644 --- a/common/src/msgs/staking/mod.rs +++ b/common/src/msgs/staking/mod.rs @@ -1,4 +1,8 @@ +pub mod execute; + pub mod query; mod types; pub use types::*; + +use super::*; diff --git a/common/src/msgs/staking/query.rs b/common/src/msgs/staking/query.rs index 16b14b1d..a675a1d6 100644 --- a/common/src/msgs/staking/query.rs +++ b/common/src/msgs/staking/query.rs @@ -12,6 +12,7 @@ use crate::types::PublicKey; #[cfg_attr(feature = "cosmwasm", cw_serde)] #[cfg_attr(feature = "cosmwasm", derive(QueryResponses))] #[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] pub enum QueryMsg { #[cfg_attr(feature = "cosmwasm", returns(Option))] GetStaker { public_key: PublicKey }, diff --git a/common/src/msgs/staking/types.rs b/common/src/msgs/staking/types.rs index 36dd8f14..609251f6 100644 --- a/common/src/msgs/staking/types.rs +++ b/common/src/msgs/staking/types.rs @@ -1,12 +1,7 @@ -#[cfg(feature = "cosmwasm")] -use cosmwasm_std::Uint128; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -#[cfg(feature = "cosmwasm")] -type U128 = Uint128; -#[cfg(not(feature = "cosmwasm"))] -type U128 = String; +use crate::types::U128; /// A data request executor with staking info and optional p2p multi address #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, JsonSchema)] diff --git a/common/src/types.rs b/common/src/types.rs index 4b69ada9..543e9630 100644 --- a/common/src/types.rs +++ b/common/src/types.rs @@ -1 +1,9 @@ +#[cfg(feature = "cosmwasm")] +use cosmwasm_std::Uint128; + pub type PublicKey = Vec; + +#[cfg(feature = "cosmwasm")] +pub(crate) type U128 = Uint128; +#[cfg(not(feature = "cosmwasm"))] +pub(crate) type U128 = String; From 142b05d0fc1619e52d90eea9ccb2b97704be32ad Mon Sep 17 00:00:00 2001 From: Mario Cao Date: Fri, 7 Jun 2024 18:16:35 +0200 Subject: [PATCH 04/14] feat(contract): simplify staking functions and use common --- contract/src/contract.rs | 4 +- contract/src/msgs/mod.rs | 17 ++-- .../msgs/staking/execute/increase_stake.rs | 71 ----------------- contract/src/msgs/staking/execute/mod.rs | 40 +++------- .../staking/execute/register_and_stake.rs | 77 ------------------ .../staking/execute/set_staking_config.rs | 15 ++-- contract/src/msgs/staking/execute/stake.rs | 78 +++++++++++++++++++ .../src/msgs/staking/execute/unregister.rs | 50 ------------ contract/src/msgs/staking/execute/unstake.rs | 20 +---- contract/src/msgs/staking/execute/withdraw.rs | 28 +++---- contract/src/msgs/staking/mod.rs | 12 --- contract/src/msgs/staking/query.rs | 11 +-- contract/src/msgs/staking/state.rs | 2 +- 13 files changed, 124 insertions(+), 301 deletions(-) delete mode 100644 contract/src/msgs/staking/execute/increase_stake.rs delete mode 100644 contract/src/msgs/staking/execute/register_and_stake.rs create mode 100644 contract/src/msgs/staking/execute/stake.rs delete mode 100644 contract/src/msgs/staking/execute/unregister.rs diff --git a/contract/src/contract.rs b/contract/src/contract.rs index 5de9c276..109f9cb8 100644 --- a/contract/src/contract.rs +++ b/contract/src/contract.rs @@ -2,13 +2,15 @@ use cosmwasm_std::{entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Response}; use cosmwasm_std::{StdResult, Uint128}; use cw2::set_contract_version; +use seda_contract_common::msgs::staking::StakingConfig; use crate::{ consts::{INITIAL_MINIMUM_STAKE_FOR_COMMITTEE_ELIGIBILITY, INITIAL_MINIMUM_STAKE_TO_REGISTER}, error::ContractError, msgs::{ owner::state::{OWNER, PENDING_OWNER}, - staking::{state::CONFIG, StakingConfig}, + staking::state::CONFIG, + ExecuteHandler, ExecuteMsg, InstantiateMsg, QueryMsg, diff --git a/contract/src/msgs/mod.rs b/contract/src/msgs/mod.rs index 92c7651e..46673e7b 100644 --- a/contract/src/msgs/mod.rs +++ b/contract/src/msgs/mod.rs @@ -1,8 +1,6 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::*; use cw_storage_plus::{Item, Map}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use crate::{ contract::CONTRACT_VERSION, @@ -16,9 +14,15 @@ pub mod owner; pub mod staking; pub trait QueryHandler { - fn query(msg: Self, deps: Deps, _env: Env) -> StdResult; + fn query(self, deps: Deps, _env: Env) -> StdResult; } +pub trait ExecuteHandler { + fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result; +} + +// TODO: replace by ExecuteMsg from seda-contract-common +// (Not yet replace because data request and owner still not there) #[cw_serde] #[serde(untagged)] pub enum ExecuteMsg { @@ -27,8 +31,9 @@ pub enum ExecuteMsg { Owner(owner::execute::ExecuteMsg), } -impl ExecuteMsg { - pub fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { +// impl ExecuteMsg { +impl ExecuteHandler for ExecuteMsg { + fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { match self { ExecuteMsg::DataRequest(msg) => msg.execute(deps, env, info), ExecuteMsg::Staking(msg) => msg.execute(deps, env, info), @@ -52,7 +57,7 @@ impl QueryMsg { pub fn query(self, deps: Deps, env: Env) -> StdResult { match self { QueryMsg::DataRequest(msg) => msg.query(deps, env), - QueryMsg::Staking(msg) => QueryHandler::query(msg, deps, env), + QueryMsg::Staking(msg) => msg.query(deps, env), QueryMsg::Owner(msg) => msg.query(deps, env), } } diff --git a/contract/src/msgs/staking/execute/increase_stake.rs b/contract/src/msgs/staking/execute/increase_stake.rs deleted file mode 100644 index b0a159b0..00000000 --- a/contract/src/msgs/staking/execute/increase_stake.rs +++ /dev/null @@ -1,71 +0,0 @@ -use self::staking::owner::utils::is_staker_allowed; -use super::*; -use crate::{ - crypto::{hash, verify_proof}, - state::{inc_get_seq, CHAIN_ID, TOKEN}, - utils::get_attached_funds, -}; - -#[cw_serde] -pub struct Execute { - pub(in crate::msgs::staking) public_key: PublicKey, - pub(in crate::msgs::staking) proof: Vec, -} - -impl Execute { - /// Deposits and stakes tokens for an already existing staker. - pub fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { - let token = TOKEN.load(deps.storage)?; - let amount = get_attached_funds(&info.funds, &token)?; - let chain_id = CHAIN_ID.load(deps.storage)?; - - // compute message hash - let message_hash = hash([ - "increase_stake".as_bytes(), - chain_id.as_bytes(), - env.contract.address.as_str().as_bytes(), - &inc_get_seq(deps.storage, &self.public_key)?.to_be_bytes(), - ]); - - // verify the proof - verify_proof(&self.public_key, &self.proof, message_hash)?; - - // if allowlist is on, check if the signer is in the allowlist - is_staker_allowed(&deps, &self.public_key)?; - - // update staked tokens for executor - let mut executor = state::STAKERS.load(deps.storage, &self.public_key)?; - executor.tokens_staked += amount; - state::STAKERS.save(deps.storage, &self.public_key, &executor)?; - - let mut event = Event::new("seda-data-request-executor").add_attributes([ - ("version", CONTRACT_VERSION.to_string()), - ("executor", hex::encode(&self.public_key)), - ("tokens_staked", executor.tokens_staked.to_string()), - ( - "tokens_pending_withdrawal", - executor.tokens_pending_withdrawal.to_string(), - ), - ]); - // https://github.com/CosmWasm/cosmwasm/issues/2163 - if let Some(memo) = executor.memo { - event = event.add_attribute("memo", memo); - } - - Ok(Response::new().add_attribute("action", "increase-stake").add_events([ - event, - Event::new("seda-data-request-executor-increase-stake").add_attributes([ - ("version", CONTRACT_VERSION.to_string()), - ("executor", hex::encode(self.public_key)), - ("amount_deposited", amount.to_string()), - ]), - ])) - } -} - -#[cfg(test)] -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::IncreaseStake(value).into() - } -} diff --git a/contract/src/msgs/staking/execute/mod.rs b/contract/src/msgs/staking/execute/mod.rs index cdc79ff0..88e7f6c9 100644 --- a/contract/src/msgs/staking/execute/mod.rs +++ b/contract/src/msgs/staking/execute/mod.rs @@ -1,40 +1,20 @@ +pub use seda_contract_common::msgs::staking::execute::ExecuteMsg; + use super::*; -pub(in crate::msgs::staking) mod increase_stake; -pub(in crate::msgs::staking) mod register_and_stake; pub(in crate::msgs::staking) mod set_staking_config; -pub(in crate::msgs::staking) mod unregister; +pub(in crate::msgs::staking) mod stake; pub(in crate::msgs::staking) mod unstake; pub(in crate::msgs::staking) mod withdraw; -#[cw_serde] -pub enum ExecuteMsg { - RegisterAndStake(register_and_stake::Execute), - Unregister(unregister::Execute), - IncreaseStake(increase_stake::Execute), - Unstake(unstake::Execute), - Withdraw(withdraw::Execute), - SetStakingConfig(StakingConfig), -} - -impl ExecuteMsg { - pub fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { - use self::*; - +impl ExecuteHandler for ExecuteMsg { + fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { match self { - ExecuteMsg::RegisterAndStake(msg) => msg.execute(deps, env, info), - ExecuteMsg::IncreaseStake(msg) => msg.execute(deps, env, info), - ExecuteMsg::Unstake(msg) => msg.execute(deps, env, info), - ExecuteMsg::Withdraw(msg) => msg.execute(deps, env, info), - ExecuteMsg::Unregister(msg) => msg.execute(deps, env, info), - ExecuteMsg::SetStakingConfig(msg) => msg.execute(deps, env, info), + ExecuteMsg::Stake(msg) => ExecuteHandler::execute(msg, deps, env, info), + // ExecuteMsg::IncreaseStake(msg) => ExecuteHandler::execute(msg, deps, env, info), + ExecuteMsg::Unstake(msg) => ExecuteHandler::execute(msg, deps, env, info), + ExecuteMsg::Withdraw(msg) => ExecuteHandler::execute(msg, deps, env, info), + ExecuteMsg::SetStakingConfig(msg) => ExecuteHandler::execute(msg, deps, env, info), } } } - -#[cfg(test)] -impl From for super::ExecuteMsg { - fn from(value: ExecuteMsg) -> Self { - Self::Staking(value) - } -} diff --git a/contract/src/msgs/staking/execute/register_and_stake.rs b/contract/src/msgs/staking/execute/register_and_stake.rs deleted file mode 100644 index d379142d..00000000 --- a/contract/src/msgs/staking/execute/register_and_stake.rs +++ /dev/null @@ -1,77 +0,0 @@ -use seda_contract_common::msgs::staking::Staker; - -use self::staking::owner::utils::is_staker_allowed; -use super::*; -use crate::{ - crypto::{hash, verify_proof}, - state::{inc_get_seq, CHAIN_ID, TOKEN}, - types::{Hasher, PublicKey}, - utils::get_attached_funds, -}; - -#[cw_serde] -pub struct Execute { - pub(in crate::msgs::staking) public_key: PublicKey, - pub(in crate::msgs::staking) proof: Vec, - pub(in crate::msgs::staking) memo: Option, -} - -impl Execute { - /// Registers a staker with an optional p2p multi address, requiring a token deposit. - pub fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { - let chain_id = CHAIN_ID.load(deps.storage)?; - // compute message hash - let message_hash = hash([ - "register_and_stake".as_bytes(), - &self.memo.hash(), - chain_id.as_bytes(), - env.contract.address.as_str().as_bytes(), - &inc_get_seq(deps.storage, &self.public_key)?.to_be_bytes(), - ]); - - // verify the proof - verify_proof(&self.public_key, &self.proof, message_hash)?; - - // if allowlist is on, check if the signer is in the allowlist - is_staker_allowed(&deps, &self.public_key)?; - - // require token deposit - let token = TOKEN.load(deps.storage)?; - let amount = get_attached_funds(&info.funds, &token)?; - - let minimum_stake_to_register = state::CONFIG.load(deps.storage)?.minimum_stake_to_register; - if amount < minimum_stake_to_register { - return Err(ContractError::InsufficientFunds(minimum_stake_to_register, amount)); - } - - let executor = Staker { - memo: self.memo.clone(), - tokens_staked: amount, - tokens_pending_withdrawal: Uint128::zero(), - }; - state::STAKERS.save(deps.storage, &self.public_key, &executor)?; - - let mut event = Event::new("seda-register-and-stake").add_attributes([ - ("version", CONTRACT_VERSION.to_string()), - ("executor", hex::encode(self.public_key)), - ("sender", info.sender.to_string()), - ("tokens_staked", amount.to_string()), - ("tokens_pending_withdrawal", "0".to_string()), - ]); - // https://github.com/CosmWasm/cosmwasm/issues/2163 - if let Some(memo) = self.memo { - event = event.add_attribute("memo", memo); - } - - Ok(Response::new() - .add_attribute("action", "register-and-stake") - .add_event(event)) - } -} - -#[cfg(test)] -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::RegisterAndStake(value).into() - } -} diff --git a/contract/src/msgs/staking/execute/set_staking_config.rs b/contract/src/msgs/staking/execute/set_staking_config.rs index f4d120f5..773ecbca 100644 --- a/contract/src/msgs/staking/execute/set_staking_config.rs +++ b/contract/src/msgs/staking/execute/set_staking_config.rs @@ -1,9 +1,11 @@ +use seda_contract_common::msgs::staking::StakingConfig; + use self::staking::owner::state::OWNER; -use super::{state::CONFIG, StakingConfig, *}; +use super::{state::CONFIG, *}; -impl StakingConfig { +impl ExecuteHandler for StakingConfig { /// Set staking config - pub fn execute(self, deps: DepsMut, _env: Env, info: MessageInfo) -> Result { + fn execute(self, deps: DepsMut, _env: Env, info: MessageInfo) -> Result { if info.sender != OWNER.load(deps.storage)? { return Err(ContractError::NotOwner); } @@ -22,10 +24,3 @@ impl StakingConfig { ])])) } } - -#[cfg(test)] -impl From for crate::msgs::ExecuteMsg { - fn from(config: StakingConfig) -> Self { - super::ExecuteMsg::SetStakingConfig(config).into() - } -} diff --git a/contract/src/msgs/staking/execute/stake.rs b/contract/src/msgs/staking/execute/stake.rs new file mode 100644 index 00000000..755de609 --- /dev/null +++ b/contract/src/msgs/staking/execute/stake.rs @@ -0,0 +1,78 @@ +pub use seda_contract_common::msgs::staking::execute::stake::Execute; +use seda_contract_common::msgs::staking::Staker; + +use self::staking::owner::utils::is_staker_allowed; +use super::*; +use crate::{ + crypto::{hash, verify_proof}, + state::{inc_get_seq, CHAIN_ID, TOKEN}, + types::Hasher, + utils::get_attached_funds, +}; + +impl ExecuteHandler for Execute { + /// Stakes with an optional memo field, requiring a token deposit. + fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { + let chain_id = CHAIN_ID.load(deps.storage)?; + // compute message hash + let message_hash = hash([ + "stake".as_bytes(), + &self.memo.hash(), + chain_id.as_bytes(), + env.contract.address.as_str().as_bytes(), + &inc_get_seq(deps.storage, &self.public_key)?.to_be_bytes(), + ]); + + // verify the proof + verify_proof(&self.public_key, &self.proof, message_hash)?; + + // if allowlist is on, check if the signer is in the allowlist + is_staker_allowed(&deps, &self.public_key)?; + + // require token deposit + let token = TOKEN.load(deps.storage)?; + let amount = get_attached_funds(&info.funds, &token)?; + + // fetch executor from state + let executor = match state::STAKERS.may_load(deps.storage, &self.public_key)? { + // new executor + None => { + let minimum_stake_to_register = state::CONFIG.load(deps.storage)?.minimum_stake_to_register; + if amount < minimum_stake_to_register { + return Err(ContractError::InsufficientFunds(minimum_stake_to_register, amount)); + } + + Staker { + memo: self.memo.clone(), + tokens_staked: amount, + tokens_pending_withdrawal: Uint128::zero(), + } + } + // already existing executor + Some(mut executor) => { + let minimum_stake_to_register = state::CONFIG.load(deps.storage)?.minimum_stake_to_register; + if amount + executor.tokens_staked < minimum_stake_to_register { + return Err(ContractError::InsufficientFunds(minimum_stake_to_register, amount)); + } + executor.tokens_staked += amount; + + executor + } + }; + state::STAKERS.save(deps.storage, &self.public_key, &executor)?; + + let mut event = Event::new("seda-register-and-stake").add_attributes([ + ("version", CONTRACT_VERSION.to_string()), + ("executor", hex::encode(self.public_key)), + ("sender", info.sender.to_string()), + ("tokens_staked", amount.to_string()), + ("tokens_pending_withdrawal", "0".to_string()), + ]); + // https://github.com/CosmWasm/cosmwasm/issues/2163 + if let Some(memo) = self.memo { + event = event.add_attribute("memo", memo); + } + + Ok(Response::new().add_attribute("action", "stake").add_event(event)) + } +} diff --git a/contract/src/msgs/staking/execute/unregister.rs b/contract/src/msgs/staking/execute/unregister.rs deleted file mode 100644 index 2dc842a0..00000000 --- a/contract/src/msgs/staking/execute/unregister.rs +++ /dev/null @@ -1,50 +0,0 @@ -use super::*; -use crate::{ - crypto::{hash, verify_proof}, - state::{inc_get_seq, CHAIN_ID}, -}; - -#[cw_serde] -pub struct Execute { - pub(in crate::msgs::staking) public_key: PublicKey, - pub(in crate::msgs::staking) proof: Vec, -} - -impl Execute { - /// Unregisters a staker, with the requirement that no tokens are staked or pending withdrawal. - pub fn execute(self, deps: DepsMut, env: Env, _info: MessageInfo) -> Result { - let chain_id = CHAIN_ID.load(deps.storage)?; - // compute message hash - let message_hash = hash([ - "unregister".as_bytes(), - chain_id.as_bytes(), - env.contract.address.as_str().as_bytes(), - &inc_get_seq(deps.storage, &self.public_key)?.to_be_bytes(), - ]); - - // verify the proof - verify_proof(&self.public_key, &self.proof, message_hash)?; - - // require that the executor has no staked or tokens pending withdrawal - let executor = state::STAKERS.load(deps.storage, &self.public_key)?; - if executor.tokens_staked > Uint128::zero() || executor.tokens_pending_withdrawal > Uint128::zero() { - return Err(ContractError::ExecutorHasTokens); - } - - state::STAKERS.remove(deps.storage, &self.public_key); - - Ok(Response::new().add_attribute("action", "unregister").add_event( - Event::new("seda-unregister").add_attributes([ - ("version", CONTRACT_VERSION.to_string()), - ("executor", hex::encode(self.public_key)), - ]), - )) - } -} - -#[cfg(test)] -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::Unregister(value).into() - } -} diff --git a/contract/src/msgs/staking/execute/unstake.rs b/contract/src/msgs/staking/execute/unstake.rs index 2f1cf14b..73e2bf3f 100644 --- a/contract/src/msgs/staking/execute/unstake.rs +++ b/contract/src/msgs/staking/execute/unstake.rs @@ -1,19 +1,14 @@ +use seda_contract_common::msgs::staking::execute::unstake::Execute; + use super::*; use crate::{ crypto::{hash, verify_proof}, state::{inc_get_seq, CHAIN_ID}, }; -#[cw_serde] -pub struct Execute { - pub(in crate::msgs::staking) public_key: PublicKey, - pub(in crate::msgs::staking) proof: Vec, - pub(in crate::msgs::staking) amount: Uint128, -} - -impl Execute { +impl ExecuteHandler for Execute { /// Unstakes tokens from a given staker, to be withdrawn after a delay. - pub fn execute(self, deps: DepsMut, env: Env, _info: MessageInfo) -> Result { + fn execute(self, deps: DepsMut, env: Env, _info: MessageInfo) -> Result { let chain_id = CHAIN_ID.load(deps.storage)?; // compute message hash let message_hash = hash([ @@ -65,10 +60,3 @@ impl Execute { ])) } } - -#[cfg(test)] -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::Unstake(value).into() - } -} diff --git a/contract/src/msgs/staking/execute/withdraw.rs b/contract/src/msgs/staking/execute/withdraw.rs index 0469af98..a58d186d 100644 --- a/contract/src/msgs/staking/execute/withdraw.rs +++ b/contract/src/msgs/staking/execute/withdraw.rs @@ -1,4 +1,5 @@ use cosmwasm_std::{coins, BankMsg}; +pub(crate) use seda_contract_common::msgs::staking::execute::withdraw::Execute; use super::*; use crate::{ @@ -6,16 +7,9 @@ use crate::{ state::{inc_get_seq, CHAIN_ID, TOKEN}, }; -#[cw_serde] -pub struct Execute { - pub(in crate::msgs::staking) public_key: PublicKey, - pub(in crate::msgs::staking) proof: Vec, - pub(in crate::msgs::staking) amount: Uint128, -} - -impl Execute { +impl ExecuteHandler for Execute { /// Sends tokens back to the sender that are marked as pending withdrawal. - pub fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { + fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { let chain_id = CHAIN_ID.load(deps.storage)?; // compute message hash let message_hash = hash([ @@ -41,9 +35,13 @@ impl Execute { )); } - // update the executor + // update the executor (remove if balances are zero) executor.tokens_pending_withdrawal -= self.amount; - state::STAKERS.save(deps.storage, &self.public_key, &executor)?; + if executor.tokens_pending_withdrawal.is_zero() && executor.tokens_staked.is_zero() { + state::STAKERS.remove(deps.storage, &self.public_key); + } else { + state::STAKERS.save(deps.storage, &self.public_key, &executor)?; + } // send the tokens back to the executor let bank_msg = BankMsg::Send { @@ -65,6 +63,7 @@ impl Execute { if let Some(memo) = executor.memo { event = event.add_attribute("memo", memo); } + Ok(Response::new() .add_message(bank_msg) .add_attribute("action", "withdraw") @@ -78,10 +77,3 @@ impl Execute { ])) } } - -#[cfg(test)] -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::Withdraw(value).into() - } -} diff --git a/contract/src/msgs/staking/mod.rs b/contract/src/msgs/staking/mod.rs index c0b3ca33..a1dcb9dd 100644 --- a/contract/src/msgs/staking/mod.rs +++ b/contract/src/msgs/staking/mod.rs @@ -2,7 +2,6 @@ use super::*; pub mod execute; pub mod query; -pub use seda_contract_common::msgs::staking::query::QueryMsg; pub mod state; pub mod utils; @@ -12,14 +11,3 @@ mod tests; #[cfg(test)] pub mod test_helpers; - -/// Governance-controlled configuration parameters -#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, JsonSchema)] -pub struct StakingConfig { - /// Minimum amount of SEDA tokens required to register as a data request executor - pub minimum_stake_to_register: Uint128, - /// Minimum amount of SEDA tokens required to be eligible for committee inclusion - pub minimum_stake_for_committee_eligibility: Uint128, - /// Whether the allowlist is enabled - pub allowlist_enabled: bool, -} diff --git a/contract/src/msgs/staking/query.rs b/contract/src/msgs/staking/query.rs index bd6b1ccd..fe92e512 100644 --- a/contract/src/msgs/staking/query.rs +++ b/contract/src/msgs/staking/query.rs @@ -5,8 +5,8 @@ use super::*; use crate::state::get_seq; impl QueryHandler for QueryMsg { - fn query(msg: QueryMsg, deps: Deps, _env: Env) -> StdResult { - match msg { + fn query(self, deps: Deps, _env: Env) -> StdResult { + match self { QueryMsg::GetStaker { public_key: executor } => to_json_binary(&utils::get_staker(deps, &executor)?), QueryMsg::GetAccountSeq { public_key } => { let seq: Uint128 = get_seq(deps.storage, &public_key)?.into(); @@ -24,10 +24,3 @@ impl QueryHandler for QueryMsg { } } } - -// #[cfg(test)] -// impl From for super::QueryMsg { -// fn from(value: QueryMsg) -> Self { -// Self::Staking(value) -// } -// } diff --git a/contract/src/msgs/staking/state.rs b/contract/src/msgs/staking/state.rs index a79a8c87..46b9c42a 100644 --- a/contract/src/msgs/staking/state.rs +++ b/contract/src/msgs/staking/state.rs @@ -1,4 +1,4 @@ -use seda_contract_common::msgs::staking::Staker; +use seda_contract_common::msgs::staking::{Staker, StakingConfig}; use super::*; From c7888901a0e9dc6b26667435e127db1b37952006 Mon Sep 17 00:00:00 2001 From: Mario Cao Date: Fri, 7 Jun 2024 18:17:36 +0200 Subject: [PATCH 05/14] test(contract): update staking tests and use common --- contract/src/msgs/owner/tests.rs | 13 ++- contract/src/msgs/staking/test_helpers.rs | 131 +++++++++++++--------- contract/src/msgs/staking/tests.rs | 39 ++----- 3 files changed, 97 insertions(+), 86 deletions(-) diff --git a/contract/src/msgs/owner/tests.rs b/contract/src/msgs/owner/tests.rs index f55c9e6e..32aefc0f 100644 --- a/contract/src/msgs/owner/tests.rs +++ b/contract/src/msgs/owner/tests.rs @@ -1,4 +1,5 @@ -use super::staking::StakingConfig; +use seda_contract_common::msgs::staking::StakingConfig; + use crate::{error::ContractError, TestInfo}; #[test] @@ -91,7 +92,7 @@ pub fn allowlist_works() { // alice tries to register a data request executor, but she's not on the allowlist let mut alice = test_info.new_executor("alice", Some(100)); - let res = test_info.reg_and_stake(&mut alice, None, 10); + let res = test_info.stake(&mut alice, None, 10); assert!(res.is_err_and(|x| x == ContractError::NotOnAllowlist)); // add alice to the allowlist @@ -100,12 +101,12 @@ pub fn allowlist_works() { .unwrap(); // now alice can register a data request executor - test_info.reg_and_stake(&mut alice, None, 10).unwrap(); + test_info.stake(&mut alice, None, 10).unwrap(); // alice unstakes, withdraws, then unregisters herself test_info.unstake(&alice, 10).unwrap(); test_info.withdraw(&mut alice, 10).unwrap(); - test_info.unregister(&alice).unwrap(); + // test_info.unregister(&alice).unwrap(); // remove alice from the allowlist test_info @@ -113,7 +114,7 @@ pub fn allowlist_works() { .unwrap(); // now alice can't register a data request executor - let res = test_info.reg_and_stake(&mut alice, None, 2); + let res = test_info.stake(&mut alice, None, 2); assert!(res.is_err_and(|x| x == ContractError::NotOnAllowlist)); // update the config to disable the allowlist @@ -125,5 +126,5 @@ pub fn allowlist_works() { test_info.set_staking_config(&test_info.creator(), new_config).unwrap(); // now alice can register a data request executor - test_info.reg_and_stake(&mut alice, None, 100).unwrap(); + test_info.stake(&mut alice, None, 100).unwrap(); } diff --git a/contract/src/msgs/staking/test_helpers.rs b/contract/src/msgs/staking/test_helpers.rs index 41ca93bb..fa956d11 100644 --- a/contract/src/msgs/staking/test_helpers.rs +++ b/contract/src/msgs/staking/test_helpers.rs @@ -1,4 +1,7 @@ -use seda_contract_common::msgs::staking::{query::QueryMsg, Staker}; +use seda_contract_common::msgs::{ + self, + staking::{query::QueryMsg, Staker, StakingConfig}, +}; use super::{execute::*, *}; use crate::{ @@ -11,12 +14,14 @@ use crate::{ impl TestInfo { #[track_caller] pub fn set_staking_config(&mut self, sender: &TestExecutor, config: StakingConfig) -> Result<(), ContractError> { - let msg = config.into(); + let msg = crate::msgs::ExecuteMsg::Staking( + seda_contract_common::msgs::staking::execute::ExecuteMsg::SetStakingConfig(config), + ); self.execute(sender, &msg) } #[track_caller] - pub fn reg_and_stake( + pub fn stake( &mut self, sender: &mut TestExecutor, memo: Option, @@ -24,78 +29,92 @@ impl TestInfo { ) -> Result<(), ContractError> { let seq = self.get_account_sequence(sender.pub_key()); let msg_hash = hash([ - "register_and_stake".as_bytes(), + "stake".as_bytes(), &memo.hash(), self.chain_id(), self.contract_addr_bytes(), &seq.to_be_bytes(), ]); - let msg = register_and_stake::Execute { + let msg = msgs::staking::execute::stake::Execute { public_key: sender.pub_key(), proof: sender.prove(&msg_hash), memo, - } - .into(); + }; + // TODO: impl `From` trait + let msg = + crate::msgs::ExecuteMsg::Staking(seda_contract_common::msgs::staking::execute::ExecuteMsg::Stake(msg)); self.execute_with_funds(sender, &msg, amount) } - #[track_caller] - pub fn unregister(&mut self, sender: &TestExecutor) -> Result<(), ContractError> { - let seq = self.get_account_sequence(sender.pub_key()); - let msg_hash = hash([ - "unregister".as_bytes(), - self.chain_id(), - self.contract_addr_bytes(), - &seq.to_be_bytes(), - ]); - let msg = unregister::Execute { - public_key: sender.pub_key(), - proof: sender.prove(&msg_hash), - } - .into(); - - self.execute(sender, &msg) - } + // #[track_caller] + // pub fn unregister(&mut self, sender: &TestExecutor) -> Result<(), ContractError> { + // let seq = self.get_account_sequence(sender.pub_key()); + // let msg_hash = hash([ + // "unregister".as_bytes(), + // self.chain_id(), + // self.contract_addr_bytes(), + // &seq.to_be_bytes(), + // ]); + // let msg = unregister::Execute { + // public_key: sender.pub_key(), + // proof: sender.prove(&msg_hash), + // }; + // let msg = + // crate::msgs::ExecuteMsg::Staking(seda_contract_common::msgs::staking::execute::ExecuteMsg::Stake(msg)); + + // self.execute(sender, &msg) + // } #[track_caller] pub fn get_staker(&self, executor: PublicKey) -> Option { self.query(QueryMsg::GetStaker { public_key: executor }).unwrap() } - #[track_caller] - pub fn increase_stake(&mut self, sender: &mut TestExecutor, amount: u128) -> Result<(), ContractError> { - let seq = self.get_account_sequence(sender.pub_key()); - let msg_hash = hash([ - "increase_stake".as_bytes(), - self.chain_id(), - self.contract_addr_bytes(), - &seq.to_be_bytes(), - ]); - let msg = increase_stake::Execute { - public_key: sender.pub_key(), - proof: sender.prove(&msg_hash), - } - .into(); - - self.execute_with_funds(sender, &msg, amount) - } + // #[track_caller] + // pub fn increase_stake(&mut self, sender: &mut TestExecutor, amount: u128) -> Result<(), ContractError> { + // let seq = self.get_account_sequence(sender.pub_key()); + // let msg_hash = hash([ + // "increase_stake".as_bytes(), + // self.chain_id(), + // self.contract_addr_bytes(), + // &seq.to_be_bytes(), + // ]); + // let msg = stake::Execute { + // public_key: sender.pub_key(), + // proof: sender.prove(&msg_hash), + // memo: None, + // }; + // let msg = + // crate::msgs::ExecuteMsg::Staking(seda_contract_common::msgs::staking::execute::ExecuteMsg::Stake(msg)); + + // self.execute_with_funds(sender, &msg, amount) + // } #[track_caller] - pub fn increase_stake_no_funds(&mut self, sender: &mut TestExecutor) -> Result<(), ContractError> { + pub fn stake_with_no_funds( + &mut self, + sender: &mut TestExecutor, + memo: Option, + ) -> Result<(), ContractError> { let seq = self.get_account_sequence(sender.pub_key()); let msg_hash = hash([ - "increase_stake".as_bytes(), + "stake".as_bytes(), + &memo.hash(), self.chain_id(), self.contract_addr_bytes(), &seq.to_be_bytes(), ]); - let msg = increase_stake::Execute { + let msg = stake::Execute { public_key: sender.pub_key(), - proof: sender.prove(&msg_hash), - } - .into(); + proof: sender.prove(&msg_hash), + memo, + }; + + // TODO: impl `From` trait + let msg = + crate::msgs::ExecuteMsg::Staking(seda_contract_common::msgs::staking::execute::ExecuteMsg::Stake(msg)); self.execute(sender, &msg) } @@ -110,12 +129,15 @@ impl TestInfo { self.contract_addr_bytes(), &seq.to_be_bytes(), ]); - let msg = unstake::Execute { + let msg = msgs::staking::execute::unstake::Execute { public_key: sender.pub_key(), proof: sender.prove(&msg_hash), amount: amount.into(), - } - .into(); + }; + + // TODO: impl `From` trait + let msg = + crate::msgs::ExecuteMsg::Staking(seda_contract_common::msgs::staking::execute::ExecuteMsg::Unstake(msg)); self.execute(sender, &msg) } @@ -130,12 +152,15 @@ impl TestInfo { self.contract_addr_bytes(), &seq.to_be_bytes(), ]); - let msg = withdraw::Execute { + let msg = msgs::staking::execute::withdraw::Execute { public_key: sender.pub_key(), proof: sender.prove(&msg_hash), amount: amount.into(), - } - .into(); + }; + + // TODO: impl `From` trait + let msg = + crate::msgs::ExecuteMsg::Staking(seda_contract_common::msgs::staking::execute::ExecuteMsg::Withdraw(msg)); let res = self.execute(sender, &msg); sender.add_seda(10); diff --git a/contract/src/msgs/staking/tests.rs b/contract/src/msgs/staking/tests.rs index c78aeb55..4f465e88 100644 --- a/contract/src/msgs/staking/tests.rs +++ b/contract/src/msgs/staking/tests.rs @@ -1,4 +1,4 @@ -use seda_contract_common::msgs::staking::Staker; +use seda_contract_common::msgs::staking::{Staker, StakingConfig}; use super::*; use crate::TestInfo; @@ -42,9 +42,7 @@ fn deposit_stake_withdraw() { let mut anyone = test_info.new_executor("anyone", Some(3)); // register a data request executor - test_info - .reg_and_stake(&mut anyone, Some("address".to_string()), 1) - .unwrap(); + test_info.stake(&mut anyone, Some("address".to_string()), 1).unwrap(); let executor_is_eligible = test_info.is_executor_eligible(anyone.pub_key()); assert!(executor_is_eligible); @@ -53,7 +51,7 @@ fn deposit_stake_withdraw() { assert_eq!(value.map(|x| x.tokens_staked), Some(1u8.into()),); // the data request executor stakes 2 more tokens - test_info.increase_stake(&mut anyone, 2).unwrap(); + test_info.stake(&mut anyone, Some("address".to_string()), 2).unwrap(); let executor_is_eligible = test_info.is_executor_eligible(anyone.pub_key()); assert!(executor_is_eligible); // data request executor's stake should be 3 @@ -105,7 +103,9 @@ fn no_funds_provided() { let mut test_info = TestInfo::init(); let mut anyone = test_info.new_executor("anyone", None); - test_info.increase_stake_no_funds(&mut anyone).unwrap(); + test_info + .stake_with_no_funds(&mut anyone, Some("address".to_string())) + .unwrap(); } #[test] @@ -115,7 +115,7 @@ fn insufficient_funds() { // register a data request executor let mut alice = test_info.new_executor("alice", Some(1000)); - test_info.reg_and_stake(&mut alice, None, 1).unwrap(); + test_info.stake(&mut alice, None, 1).unwrap(); // try unstaking more than staked test_info.unstake(&alice, 2).unwrap(); @@ -131,9 +131,7 @@ fn register_data_request_executor() { assert_eq!(value, None); // someone registers a data request executor - test_info - .reg_and_stake(&mut anyone, Some("memo".to_string()), 1) - .unwrap(); + test_info.stake(&mut anyone, Some("memo".to_string()), 1).unwrap(); // should be able to fetch the data request executor let value = test_info.get_staker(anyone.pub_key()); @@ -153,9 +151,7 @@ fn unregister_data_request_executor() { // someone registers a data request executor let mut anyone = test_info.new_executor("anyone", Some(2)); - test_info - .reg_and_stake(&mut anyone, Some("memo".to_string()), 2) - .unwrap(); + test_info.stake(&mut anyone, Some("memo".to_string()), 2).unwrap(); // should be able to fetch the data request executor let value: Option = test_info.get_staker(anyone.pub_key()); @@ -169,8 +165,8 @@ fn unregister_data_request_executor() { ); // can't unregister the data request executor if it has staked tokens - let res = test_info.unregister(&anyone); - assert!(res.is_err_and(|x| x == ContractError::ExecutorHasTokens)); + // let res = test_info.unregister(&anyone); + // assert!(res.is_err_and(|x| x == ContractError::ExecutorHasTokens)); // unstake and withdraw all tokens test_info.unstake(&anyone, 2).unwrap(); @@ -184,19 +180,8 @@ fn unregister_data_request_executor() { }), ); + // unregister the data request executor by withdrawing all funds test_info.withdraw(&mut anyone, 2).unwrap(); - let value: Option = test_info.get_staker(anyone.pub_key()); - assert_eq!( - value, - Some(Staker { - memo: Some("memo".to_string()), - tokens_staked: 0u8.into(), - tokens_pending_withdrawal: 0u8.into(), - }), - ); - - // unregister the data request executor - test_info.unregister(&anyone).unwrap(); // fetching data request executor after unregistering should return None let value: Option = test_info.get_staker(anyone.pub_key()); From 48a7381a45d75dc32125425a11f4170eaf72fab6 Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Fri, 7 Jun 2024 12:53:31 -0600 Subject: [PATCH 06/14] refactor: migrate staking and owner to common --- Cargo.lock | 13 ++ common/Cargo.toml | 10 +- common/src/msgs/mod.rs | 33 +++- .../msgs/owner/execute/accept_ownership.rs | 12 ++ .../msgs/owner/execute/add_to_allowlist.rs | 15 ++ common/src/msgs/owner/execute/mod.rs | 24 +++ .../owner/execute/remove_from_allowlist.rs | 15 ++ .../msgs/owner/execute/transfer_ownership.rs | 14 ++ common/src/msgs/owner/mod.rs | 4 + common/src/msgs/owner/query.rs | 18 +++ common/src/msgs/staking/execute/mod.rs | 5 - common/src/msgs/staking/execute/set_config.rs | 11 -- common/src/msgs/staking/execute/stake.rs | 12 +- common/src/msgs/staking/execute/unstake.rs | 14 +- common/src/msgs/staking/execute/withdraw.rs | 14 +- common/src/msgs/staking/mod.rs | 1 - common/src/msgs/staking/query.rs | 13 +- common/src/msgs/staking/types.rs | 23 ++- common/src/types.rs | 69 ++++++++- contract/src/bin/schema.rs | 2 +- contract/src/contract.rs | 7 +- contract/src/lib.rs | 3 +- contract/src/msgs/mod.rs | 56 ++----- .../msgs/owner/execute/accept_ownership.rs | 14 +- .../msgs/owner/execute/add_to_allowlist.rs | 17 +-- contract/src/msgs/owner/execute/mod.rs | 31 +--- .../owner/execute/remove_from_allowlist.rs | 17 +-- .../msgs/owner/execute/transfer_ownership.rs | 16 +- contract/src/msgs/owner/query.rs | 21 +-- contract/src/msgs/owner/test_helpers.rs | 5 +- contract/src/msgs/staking/execute/mod.rs | 7 +- .../staking/execute/set_staking_config.rs | 3 +- contract/src/msgs/staking/execute/stake.rs | 13 +- contract/src/msgs/staking/execute/unstake.rs | 6 +- contract/src/msgs/staking/execute/withdraw.rs | 10 +- contract/src/msgs/staking/test_helpers.rs | 107 +++++-------- contract/src/test_utils.rs | 2 +- contract/src/types.rs | 66 -------- xtask/src/main.rs | 144 +++++++++--------- 39 files changed, 421 insertions(+), 446 deletions(-) create mode 100644 common/src/msgs/owner/execute/accept_ownership.rs create mode 100644 common/src/msgs/owner/execute/add_to_allowlist.rs create mode 100644 common/src/msgs/owner/execute/mod.rs create mode 100644 common/src/msgs/owner/execute/remove_from_allowlist.rs create mode 100644 common/src/msgs/owner/execute/transfer_ownership.rs create mode 100644 common/src/msgs/owner/mod.rs create mode 100644 common/src/msgs/owner/query.rs delete mode 100644 common/src/msgs/staking/execute/set_config.rs delete mode 100644 contract/src/types.rs diff --git a/Cargo.lock b/Cargo.lock index 410ed7a0..6bdf56b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -682,6 +682,7 @@ dependencies = [ "hex", "k256", "schemars", + "seda-contract-common", "semver", "serde", "serde-big-array", @@ -691,6 +692,18 @@ dependencies = [ "vrf-rs", ] +[[package]] +name = "seda-contract-common" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "hex", + "semver", + "serde", + "sha3", +] + [[package]] name = "semver" version = "1.0.23" diff --git a/common/Cargo.toml b/common/Cargo.toml index 785cba93..fa0f4c46 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -7,7 +7,9 @@ edition = "2021" cosmwasm = ["cosmwasm-schema", "cosmwasm-std"] [dependencies] -cosmwasm-schema = { workspace = true, optional = true} -cosmwasm-std = { workspace = true, optional = true} -serde = { workspace = true } -schemars = { workspace = true } +cosmwasm-schema = { workspace = true, optional = true } +cosmwasm-std = { workspace = true, optional = true } +hex.workspace = true +sha3.workspace = true +semver.workspace = true +serde = { workspace = true, optional = true } diff --git a/common/src/msgs/mod.rs b/common/src/msgs/mod.rs index 3dafd831..ecaec474 100644 --- a/common/src/msgs/mod.rs +++ b/common/src/msgs/mod.rs @@ -1,12 +1,39 @@ #[cfg(feature = "cosmwasm")] -use cosmwasm_schema::cw_serde; +use cosmwasm_schema::{cw_serde, QueryResponses}; +#[cfg(not(feature = "cosmwasm"))] +use serde::{Deserialize, Serialize}; +use crate::types::*; + +pub mod owner; pub mod staking; #[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(feature = "cosmwasm", serde(untagged))] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +#[serde(untagged)] pub enum ExecuteMsg { // DataRequest(Box), Staking(staking::execute::ExecuteMsg), - // Owner(owner::execute::ExecuteMsg), + Owner(owner::execute::ExecuteMsg), +} + +// https://github.com/CosmWasm/cosmwasm/issues/2030 +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(feature = "cosmwasm", derive(QueryResponses))] +#[cfg_attr(feature = "cosmwasm", query_responses(nested))] +#[cfg_attr(not(feature = "cosmwasm"), derive(serde::Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +#[serde(untagged)] +pub enum QueryMsg { + // DataRequest(data_requests::query::QueryMsg), + Staking(staking::query::QueryMsg), + Owner(owner::query::QueryMsg), +} + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +pub struct InstantiateMsg { + pub token: String, + pub owner: String, + pub chain_id: String, } diff --git a/common/src/msgs/owner/execute/accept_ownership.rs b/common/src/msgs/owner/execute/accept_ownership.rs new file mode 100644 index 00000000..2c65d342 --- /dev/null +++ b/common/src/msgs/owner/execute/accept_ownership.rs @@ -0,0 +1,12 @@ +use super::*; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub struct Execute {} + +impl From for crate::msgs::ExecuteMsg { + fn from(value: Execute) -> Self { + super::ExecuteMsg::AcceptOwnership(value).into() + } +} diff --git a/common/src/msgs/owner/execute/add_to_allowlist.rs b/common/src/msgs/owner/execute/add_to_allowlist.rs new file mode 100644 index 00000000..07c0b95c --- /dev/null +++ b/common/src/msgs/owner/execute/add_to_allowlist.rs @@ -0,0 +1,15 @@ +use super::*; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub struct Execute { + /// The public key of the person. + pub public_key: PublicKey, +} + +impl From for crate::msgs::ExecuteMsg { + fn from(value: Execute) -> Self { + super::ExecuteMsg::AddToAllowlist(value).into() + } +} diff --git a/common/src/msgs/owner/execute/mod.rs b/common/src/msgs/owner/execute/mod.rs new file mode 100644 index 00000000..5b27c791 --- /dev/null +++ b/common/src/msgs/owner/execute/mod.rs @@ -0,0 +1,24 @@ +use super::*; + +pub mod accept_ownership; +pub mod add_to_allowlist; +pub mod remove_from_allowlist; +pub mod transfer_ownership; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub enum ExecuteMsg { + TransferOwnership(transfer_ownership::Execute), + AcceptOwnership(accept_ownership::Execute), + /// Add a user to the allowlist. + AddToAllowlist(add_to_allowlist::Execute), + /// Remove a user from the allowlist. + RemoveFromAllowlist(remove_from_allowlist::Execute), +} + +impl From for super::ExecuteMsg { + fn from(value: ExecuteMsg) -> Self { + Self::Owner(value) + } +} diff --git a/common/src/msgs/owner/execute/remove_from_allowlist.rs b/common/src/msgs/owner/execute/remove_from_allowlist.rs new file mode 100644 index 00000000..ff7fed06 --- /dev/null +++ b/common/src/msgs/owner/execute/remove_from_allowlist.rs @@ -0,0 +1,15 @@ +use super::*; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub struct Execute { + /// The public key of the person. + pub public_key: PublicKey, +} + +impl From for crate::msgs::ExecuteMsg { + fn from(value: Execute) -> Self { + super::ExecuteMsg::RemoveFromAllowlist(value).into() + } +} diff --git a/common/src/msgs/owner/execute/transfer_ownership.rs b/common/src/msgs/owner/execute/transfer_ownership.rs new file mode 100644 index 00000000..a15d33ac --- /dev/null +++ b/common/src/msgs/owner/execute/transfer_ownership.rs @@ -0,0 +1,14 @@ +use super::*; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub struct Execute { + pub new_owner: String, +} + +impl From for crate::msgs::ExecuteMsg { + fn from(value: Execute) -> Self { + super::ExecuteMsg::TransferOwnership(value).into() + } +} diff --git a/common/src/msgs/owner/mod.rs b/common/src/msgs/owner/mod.rs new file mode 100644 index 00000000..cddbfbd2 --- /dev/null +++ b/common/src/msgs/owner/mod.rs @@ -0,0 +1,4 @@ +pub mod execute; +pub mod query; + +use super::*; diff --git a/common/src/msgs/owner/query.rs b/common/src/msgs/owner/query.rs new file mode 100644 index 00000000..6106e6de --- /dev/null +++ b/common/src/msgs/owner/query.rs @@ -0,0 +1,18 @@ +use super::*; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(feature = "cosmwasm", derive(QueryResponses))] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub enum QueryMsg { + #[cfg_attr(feature = "cosmwasm", returns(cosmwasm_std::Addr))] + GetOwner {}, + #[cfg_attr(feature = "cosmwasm", returns(Option))] + GetPendingOwner {}, +} + +impl From for super::QueryMsg { + fn from(value: QueryMsg) -> Self { + Self::Owner(value) + } +} diff --git a/common/src/msgs/staking/execute/mod.rs b/common/src/msgs/staking/execute/mod.rs index 4181b778..3ea0edd8 100644 --- a/common/src/msgs/staking/execute/mod.rs +++ b/common/src/msgs/staking/execute/mod.rs @@ -1,8 +1,3 @@ -#[cfg(feature = "cosmwasm")] -use cosmwasm_schema::cw_serde; -#[cfg(not(feature = "cosmwasm"))] -use serde::Serialize; - use super::*; pub mod stake; diff --git a/common/src/msgs/staking/execute/set_config.rs b/common/src/msgs/staking/execute/set_config.rs deleted file mode 100644 index 61ba700d..00000000 --- a/common/src/msgs/staking/execute/set_config.rs +++ /dev/null @@ -1,11 +0,0 @@ -#[cfg(feature = "cosmwasm")] -use cosmwasm_schema::cw_serde; -#[cfg(not(feature = "cosmwasm"))] -use serde::Serialize; - -use crate::msgs::staking::StakingConfig; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -pub struct Execute { - pub config: StakingConfig, -} diff --git a/common/src/msgs/staking/execute/stake.rs b/common/src/msgs/staking/execute/stake.rs index 8007c2a1..c283123d 100644 --- a/common/src/msgs/staking/execute/stake.rs +++ b/common/src/msgs/staking/execute/stake.rs @@ -1,20 +1,16 @@ -#[cfg(feature = "cosmwasm")] -use cosmwasm_schema::cw_serde; -#[cfg(not(feature = "cosmwasm"))] -use serde::Serialize; - -use crate::types::PublicKey; +use super::*; #[cfg_attr(feature = "cosmwasm", cw_serde)] #[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] pub struct Execute { pub public_key: PublicKey, pub proof: Vec, pub memo: Option, } -impl From for super::ExecuteMsg { +impl From for crate::msgs::ExecuteMsg { fn from(value: Execute) -> Self { - super::ExecuteMsg::Stake(value) + super::ExecuteMsg::Stake(value).into() } } diff --git a/common/src/msgs/staking/execute/unstake.rs b/common/src/msgs/staking/execute/unstake.rs index a512c5af..ac9a7b93 100644 --- a/common/src/msgs/staking/execute/unstake.rs +++ b/common/src/msgs/staking/execute/unstake.rs @@ -1,14 +1,16 @@ -#[cfg(feature = "cosmwasm")] -use cosmwasm_schema::cw_serde; -#[cfg(not(feature = "cosmwasm"))] -use serde::Serialize; - -use crate::types::{PublicKey, U128}; +use super::*; #[cfg_attr(feature = "cosmwasm", cw_serde)] #[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] pub struct Execute { pub public_key: PublicKey, pub proof: Vec, pub amount: U128, } + +impl From for crate::msgs::ExecuteMsg { + fn from(value: Execute) -> Self { + super::ExecuteMsg::Unstake(value).into() + } +} diff --git a/common/src/msgs/staking/execute/withdraw.rs b/common/src/msgs/staking/execute/withdraw.rs index a512c5af..aae1dfae 100644 --- a/common/src/msgs/staking/execute/withdraw.rs +++ b/common/src/msgs/staking/execute/withdraw.rs @@ -1,14 +1,16 @@ -#[cfg(feature = "cosmwasm")] -use cosmwasm_schema::cw_serde; -#[cfg(not(feature = "cosmwasm"))] -use serde::Serialize; - -use crate::types::{PublicKey, U128}; +use super::*; #[cfg_attr(feature = "cosmwasm", cw_serde)] #[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] pub struct Execute { pub public_key: PublicKey, pub proof: Vec, pub amount: U128, } + +impl From for crate::msgs::ExecuteMsg { + fn from(value: Execute) -> Self { + super::ExecuteMsg::Withdraw(value).into() + } +} diff --git a/common/src/msgs/staking/mod.rs b/common/src/msgs/staking/mod.rs index acce3b88..58872e42 100644 --- a/common/src/msgs/staking/mod.rs +++ b/common/src/msgs/staking/mod.rs @@ -1,5 +1,4 @@ pub mod execute; - pub mod query; mod types; diff --git a/common/src/msgs/staking/query.rs b/common/src/msgs/staking/query.rs index a675a1d6..43d3a0fe 100644 --- a/common/src/msgs/staking/query.rs +++ b/common/src/msgs/staking/query.rs @@ -1,13 +1,4 @@ -#[cfg(feature = "cosmwasm")] -use cosmwasm_schema::{cw_serde, QueryResponses}; -#[cfg(feature = "cosmwasm")] -use cosmwasm_std::Uint128; -#[cfg(not(feature = "cosmwasm"))] -use serde::Serialize; - -#[cfg(feature = "cosmwasm")] -use super::{Staker, StakerAndSeq, StakingConfig}; -use crate::types::PublicKey; +use super::*; #[cfg_attr(feature = "cosmwasm", cw_serde)] #[cfg_attr(feature = "cosmwasm", derive(QueryResponses))] @@ -16,7 +7,7 @@ use crate::types::PublicKey; pub enum QueryMsg { #[cfg_attr(feature = "cosmwasm", returns(Option))] GetStaker { public_key: PublicKey }, - #[cfg_attr(feature = "cosmwasm", returns(Uint128))] + #[cfg_attr(feature = "cosmwasm", returns(U128))] GetAccountSeq { public_key: PublicKey }, #[cfg_attr(feature = "cosmwasm", returns(StakerAndSeq))] GetStakerAndSeq { public_key: PublicKey }, diff --git a/common/src/msgs/staking/types.rs b/common/src/msgs/staking/types.rs index 609251f6..25e7d6a2 100644 --- a/common/src/msgs/staking/types.rs +++ b/common/src/msgs/staking/types.rs @@ -1,10 +1,9 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use crate::types::U128; +use super::*; /// A data request executor with staking info and optional p2p multi address -#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, JsonSchema)] +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] pub struct Staker { pub memo: Option, pub tokens_staked: U128, @@ -12,7 +11,9 @@ pub struct Staker { } /// Governance-controlled configuration parameters -#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, JsonSchema)] +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] pub struct StakingConfig { /// Minimum amount of SEDA tokens required to register as a data request executor pub minimum_stake_to_register: U128, @@ -22,7 +23,15 @@ pub struct StakingConfig { pub allowlist_enabled: bool, } -#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, JsonSchema)] +impl From for crate::msgs::ExecuteMsg { + fn from(config: StakingConfig) -> Self { + super::execute::ExecuteMsg::SetStakingConfig(config).into() + } +} + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] pub struct StakerAndSeq { pub staker: Option, pub seq: U128, diff --git a/common/src/types.rs b/common/src/types.rs index 543e9630..84cb8099 100644 --- a/common/src/types.rs +++ b/common/src/types.rs @@ -1,9 +1,74 @@ #[cfg(feature = "cosmwasm")] use cosmwasm_std::Uint128; -pub type PublicKey = Vec; - #[cfg(feature = "cosmwasm")] pub(crate) type U128 = Uint128; #[cfg(not(feature = "cosmwasm"))] pub(crate) type U128 = String; + +use semver::Version; +use sha3::{Digest, Keccak256}; + +pub type Bytes = Vec; +// pub type Commitment = Hash; +pub type Memo = Vec; +pub type Hash = [u8; 32]; +pub type PublicKey = Vec; + +pub trait Hex: AsRef<[u8]> { + fn to_hex(&self) -> String { + hex::encode(self) + } +} + +impl Hex for Hash { + fn to_hex(&self) -> String { + hex::encode(self) + } +} + +pub trait Hasher { + fn hash(&self) -> Hash; +} + +impl Hasher for &str { + fn hash(&self) -> Hash { + let mut hasher = Keccak256::new(); + hasher.update(self.as_bytes()); + hasher.finalize().into() + } +} + +impl Hasher for String { + fn hash(&self) -> Hash { + let refer: &str = self.as_ref(); + refer.hash() + } +} + +impl Hasher for Version { + fn hash(&self) -> Hash { + self.to_string().hash() + } +} + +impl Hasher for Vec { + fn hash(&self) -> Hash { + let mut hasher = Keccak256::new(); + hasher.update(self); + hasher.finalize().into() + } +} + +impl Hasher for Option +where + T: AsRef<[u8]>, +{ + fn hash(&self) -> Hash { + let mut hasher = Keccak256::new(); + if let Some(inner) = self { + hasher.update(inner); + } + hasher.finalize().into() + } +} diff --git a/contract/src/bin/schema.rs b/contract/src/bin/schema.rs index 34b1297f..f85b3939 100644 --- a/contract/src/bin/schema.rs +++ b/contract/src/bin/schema.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::write_api; -use seda_contract::msgs::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use seda_contract_common::msgs::*; fn main() { write_api! { diff --git a/contract/src/contract.rs b/contract/src/contract.rs index 109f9cb8..db68e43a 100644 --- a/contract/src/contract.rs +++ b/contract/src/contract.rs @@ -2,7 +2,8 @@ use cosmwasm_std::{entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Response}; use cosmwasm_std::{StdResult, Uint128}; use cw2::set_contract_version; -use seda_contract_common::msgs::staking::StakingConfig; +use seda_contract_common::msgs::*; +use staking::StakingConfig; use crate::{ consts::{INITIAL_MINIMUM_STAKE_FOR_COMMITTEE_ELIGIBILITY, INITIAL_MINIMUM_STAKE_TO_REGISTER}, @@ -11,9 +12,7 @@ use crate::{ owner::state::{OWNER, PENDING_OWNER}, staking::state::CONFIG, ExecuteHandler, - ExecuteMsg, - InstantiateMsg, - QueryMsg, + QueryHandler, }, state::{CHAIN_ID, TOKEN}, }; diff --git a/contract/src/lib.rs b/contract/src/lib.rs index 03177c27..af7de396 100644 --- a/contract/src/lib.rs +++ b/contract/src/lib.rs @@ -4,9 +4,10 @@ mod crypto; mod error; pub mod msgs; pub mod state; -mod types; mod utils; +use seda_contract_common::types; + #[cfg(test)] mod test_utils; #[cfg(test)] diff --git a/contract/src/msgs/mod.rs b/contract/src/msgs/mod.rs index 46673e7b..3c5b3a4d 100644 --- a/contract/src/msgs/mod.rs +++ b/contract/src/msgs/mod.rs @@ -1,6 +1,9 @@ -use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::*; use cw_storage_plus::{Item, Map}; +use seda_contract_common::msgs::{ + self, + staking::{Staker, StakingConfig}, +}; use crate::{ contract::CONTRACT_VERSION, @@ -9,63 +12,34 @@ use crate::{ types::*, }; -pub mod data_requests; +// pub mod data_requests; pub mod owner; pub mod staking; pub trait QueryHandler { - fn query(self, deps: Deps, _env: Env) -> StdResult; + fn query(self, deps: Deps, env: Env) -> StdResult; } pub trait ExecuteHandler { fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result; } -// TODO: replace by ExecuteMsg from seda-contract-common -// (Not yet replace because data request and owner still not there) -#[cw_serde] -#[serde(untagged)] -pub enum ExecuteMsg { - DataRequest(Box), - Staking(staking::execute::ExecuteMsg), - Owner(owner::execute::ExecuteMsg), -} - -// impl ExecuteMsg { -impl ExecuteHandler for ExecuteMsg { +impl ExecuteHandler for msgs::ExecuteMsg { fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { match self { - ExecuteMsg::DataRequest(msg) => msg.execute(deps, env, info), - ExecuteMsg::Staking(msg) => msg.execute(deps, env, info), - ExecuteMsg::Owner(msg) => msg.execute(deps, env, info), + // msgs::ExecuteMsg::DataRequest(msg) => msg.execute(deps, env, info), + msgs::ExecuteMsg::Staking(msg) => msg.execute(deps, env, info), + msgs::ExecuteMsg::Owner(msg) => msg.execute(deps, env, info), } } } -// https://github.com/CosmWasm/cosmwasm/issues/2030 -#[cw_serde] -#[serde(untagged)] -#[derive(QueryResponses)] -#[query_responses(nested)] -pub enum QueryMsg { - DataRequest(data_requests::query::QueryMsg), - Staking(staking::query::QueryMsg), - Owner(owner::query::QueryMsg), -} - -impl QueryMsg { - pub fn query(self, deps: Deps, env: Env) -> StdResult { +impl QueryHandler for msgs::QueryMsg { + fn query(self, deps: Deps, env: Env) -> StdResult { match self { - QueryMsg::DataRequest(msg) => msg.query(deps, env), - QueryMsg::Staking(msg) => msg.query(deps, env), - QueryMsg::Owner(msg) => msg.query(deps, env), + // msgs::QueryMsg::DataRequest(msg) => msg.query(deps, env), + msgs::QueryMsg::Staking(msg) => msg.query(deps, env), + msgs::QueryMsg::Owner(msg) => msg.query(deps, env), } } } - -#[cw_serde] -pub struct InstantiateMsg { - pub token: String, - pub owner: String, - pub chain_id: String, -} diff --git a/contract/src/msgs/owner/execute/accept_ownership.rs b/contract/src/msgs/owner/execute/accept_ownership.rs index d7be547b..1f4f7b11 100644 --- a/contract/src/msgs/owner/execute/accept_ownership.rs +++ b/contract/src/msgs/owner/execute/accept_ownership.rs @@ -1,11 +1,8 @@ use super::*; -#[cw_serde] -pub struct Execute {} - -impl Execute { +impl ExecuteHandler for execute::accept_ownership::Execute { /// Accept transfer contract ownership (previously triggered by owner) - pub fn execute(self, deps: DepsMut, _env: Env, info: MessageInfo) -> Result { + fn execute(self, deps: DepsMut, _env: Env, info: MessageInfo) -> Result { let pending_owner = PENDING_OWNER.load(deps.storage)?; if pending_owner.is_none() { return Err(ContractError::NoPendingOwnerFound); @@ -22,10 +19,3 @@ impl Execute { .add_attributes([("version", CONTRACT_VERSION), ("new_owner", info.sender.as_ref())])])) } } - -#[cfg(test)] -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::AcceptOwnership(value).into() - } -} diff --git a/contract/src/msgs/owner/execute/add_to_allowlist.rs b/contract/src/msgs/owner/execute/add_to_allowlist.rs index 41d538f5..dc8653a7 100644 --- a/contract/src/msgs/owner/execute/add_to_allowlist.rs +++ b/contract/src/msgs/owner/execute/add_to_allowlist.rs @@ -1,14 +1,8 @@ use super::*; -#[cw_serde] -pub struct Execute { - /// The public key of the person. - pub(in crate::msgs::owner) public_key: PublicKey, -} - -impl Execute { +impl ExecuteHandler for execute::add_to_allowlist::Execute { /// Add a `Secp256k1PublicKey` to the allow list - pub fn execute(self, deps: DepsMut, info: MessageInfo) -> Result { + fn execute(self, deps: DepsMut, _env: Env, info: MessageInfo) -> Result { // require the sender to be the OWNER let owner = OWNER.load(deps.storage)?; if info.sender != owner { @@ -26,10 +20,3 @@ impl Execute { )) } } - -#[cfg(test)] -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::AddToAllowlist(value).into() - } -} diff --git a/contract/src/msgs/owner/execute/mod.rs b/contract/src/msgs/owner/execute/mod.rs index a74876cc..e341fe8f 100644 --- a/contract/src/msgs/owner/execute/mod.rs +++ b/contract/src/msgs/owner/execute/mod.rs @@ -1,37 +1,22 @@ -use cosmwasm_std::Event; use state::{ALLOWLIST, OWNER, PENDING_OWNER}; -use super::*; +use super::{ + msgs::owner::execute::{self, ExecuteMsg}, + *, +}; pub(in crate::msgs::owner) mod accept_ownership; pub(in crate::msgs::owner) mod add_to_allowlist; pub(in crate::msgs::owner) mod remove_from_allowlist; pub(in crate::msgs::owner) mod transfer_ownership; -#[cw_serde] -pub enum ExecuteMsg { - TransferOwnership(transfer_ownership::Execute), - AcceptOwnership(accept_ownership::Execute), - /// Add a user to the allowlist. - AddToAllowlist(add_to_allowlist::Execute), - /// Remove a user from the allowlist. - RemoveFromAllowlist(remove_from_allowlist::Execute), -} - -impl ExecuteMsg { - pub fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { +impl ExecuteHandler for ExecuteMsg { + fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { match self { ExecuteMsg::TransferOwnership(msg) => msg.execute(deps, env, info), ExecuteMsg::AcceptOwnership(msg) => msg.execute(deps, env, info), - ExecuteMsg::AddToAllowlist(msg) => msg.execute(deps, info), - ExecuteMsg::RemoveFromAllowlist(msg) => msg.execute(deps, info), + ExecuteMsg::AddToAllowlist(msg) => msg.execute(deps, env, info), + ExecuteMsg::RemoveFromAllowlist(msg) => msg.execute(deps, env, info), } } } - -#[cfg(test)] -impl From for super::ExecuteMsg { - fn from(value: ExecuteMsg) -> Self { - Self::Owner(value) - } -} diff --git a/contract/src/msgs/owner/execute/remove_from_allowlist.rs b/contract/src/msgs/owner/execute/remove_from_allowlist.rs index c2fea874..9189239e 100644 --- a/contract/src/msgs/owner/execute/remove_from_allowlist.rs +++ b/contract/src/msgs/owner/execute/remove_from_allowlist.rs @@ -1,14 +1,8 @@ use super::*; -#[cw_serde] -pub struct Execute { - /// The public key of the person. - pub(in crate::msgs::owner) public_key: PublicKey, -} - -impl Execute { +impl ExecuteHandler for execute::remove_from_allowlist::Execute { /// Remove a `Secp256k1PublicKey` to the allow list - pub fn execute(self, deps: DepsMut, info: MessageInfo) -> Result { + fn execute(self, deps: DepsMut, _env: Env, info: MessageInfo) -> Result { // require the sender to be the OWNER let owner = OWNER.load(deps.storage)?; if info.sender != owner { @@ -26,10 +20,3 @@ impl Execute { ]))) } } - -#[cfg(test)] -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::RemoveFromAllowlist(value).into() - } -} diff --git a/contract/src/msgs/owner/execute/transfer_ownership.rs b/contract/src/msgs/owner/execute/transfer_ownership.rs index 9e9a0eb9..e09305d3 100644 --- a/contract/src/msgs/owner/execute/transfer_ownership.rs +++ b/contract/src/msgs/owner/execute/transfer_ownership.rs @@ -1,13 +1,8 @@ use super::*; -#[cw_serde] -pub struct Execute { - pub(in crate::msgs::owner) new_owner: String, -} - -impl Execute { +impl ExecuteHandler for execute::transfer_ownership::Execute { /// Start 2-step process for transfer contract ownership to a new address - pub fn execute(self, deps: DepsMut, _env: Env, info: MessageInfo) -> Result { + fn execute(self, deps: DepsMut, _env: Env, info: MessageInfo) -> Result { if info.sender != OWNER.load(deps.storage)? { return Err(ContractError::NotOwner); } @@ -22,10 +17,3 @@ impl Execute { ])])) } } - -#[cfg(test)] -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::TransferOwnership(value).into() - } -} diff --git a/contract/src/msgs/owner/query.rs b/contract/src/msgs/owner/query.rs index 96bab77e..8d4c3f10 100644 --- a/contract/src/msgs/owner/query.rs +++ b/contract/src/msgs/owner/query.rs @@ -1,29 +1,14 @@ use super::{ + msgs::owner::query::QueryMsg, state::{OWNER, PENDING_OWNER}, *, }; -#[cw_serde] -#[derive(QueryResponses)] -pub enum QueryMsg { - #[returns(cosmwasm_std::Addr)] - GetOwner {}, - #[returns(Option)] - GetPendingOwner {}, -} - -impl QueryMsg { - pub fn query(self, deps: Deps, _env: Env) -> StdResult { +impl QueryHandler for QueryMsg { + fn query(self, deps: Deps, _env: Env) -> StdResult { match self { QueryMsg::GetOwner {} => to_json_binary(&OWNER.load(deps.storage)?), QueryMsg::GetPendingOwner {} => to_json_binary(&PENDING_OWNER.load(deps.storage)?), } } } - -#[cfg(test)] -impl From for super::QueryMsg { - fn from(value: QueryMsg) -> Self { - Self::Owner(value) - } -} diff --git a/contract/src/msgs/owner/test_helpers.rs b/contract/src/msgs/owner/test_helpers.rs index c3fe105c..a55536d0 100644 --- a/contract/src/msgs/owner/test_helpers.rs +++ b/contract/src/msgs/owner/test_helpers.rs @@ -1,4 +1,7 @@ -use super::*; +use super::{ + msgs::owner::{execute, query}, + *, +}; use crate::{TestExecutor, TestInfo}; impl TestInfo { diff --git a/contract/src/msgs/staking/execute/mod.rs b/contract/src/msgs/staking/execute/mod.rs index 88e7f6c9..ac39e4bf 100644 --- a/contract/src/msgs/staking/execute/mod.rs +++ b/contract/src/msgs/staking/execute/mod.rs @@ -1,6 +1,7 @@ -pub use seda_contract_common::msgs::staking::execute::ExecuteMsg; - -use super::*; +use super::{ + msgs::staking::execute::{self, ExecuteMsg}, + *, +}; pub(in crate::msgs::staking) mod set_staking_config; pub(in crate::msgs::staking) mod stake; diff --git a/contract/src/msgs/staking/execute/set_staking_config.rs b/contract/src/msgs/staking/execute/set_staking_config.rs index 773ecbca..8a0dee1d 100644 --- a/contract/src/msgs/staking/execute/set_staking_config.rs +++ b/contract/src/msgs/staking/execute/set_staking_config.rs @@ -1,6 +1,5 @@ -use seda_contract_common::msgs::staking::StakingConfig; +use owner::state::OWNER; -use self::staking::owner::state::OWNER; use super::{state::CONFIG, *}; impl ExecuteHandler for StakingConfig { diff --git a/contract/src/msgs/staking/execute/stake.rs b/contract/src/msgs/staking/execute/stake.rs index 755de609..89e2bb8b 100644 --- a/contract/src/msgs/staking/execute/stake.rs +++ b/contract/src/msgs/staking/execute/stake.rs @@ -1,16 +1,9 @@ -pub use seda_contract_common::msgs::staking::execute::stake::Execute; -use seda_contract_common::msgs::staking::Staker; +use owner::utils::is_staker_allowed; -use self::staking::owner::utils::is_staker_allowed; use super::*; -use crate::{ - crypto::{hash, verify_proof}, - state::{inc_get_seq, CHAIN_ID, TOKEN}, - types::Hasher, - utils::get_attached_funds, -}; +use crate::{state::*, utils::get_attached_funds}; -impl ExecuteHandler for Execute { +impl ExecuteHandler for execute::stake::Execute { /// Stakes with an optional memo field, requiring a token deposit. fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { let chain_id = CHAIN_ID.load(deps.storage)?; diff --git a/contract/src/msgs/staking/execute/unstake.rs b/contract/src/msgs/staking/execute/unstake.rs index 73e2bf3f..20d8c261 100644 --- a/contract/src/msgs/staking/execute/unstake.rs +++ b/contract/src/msgs/staking/execute/unstake.rs @@ -1,12 +1,10 @@ -use seda_contract_common::msgs::staking::execute::unstake::Execute; - use super::*; use crate::{ crypto::{hash, verify_proof}, - state::{inc_get_seq, CHAIN_ID}, + state::*, }; -impl ExecuteHandler for Execute { +impl ExecuteHandler for execute::unstake::Execute { /// Unstakes tokens from a given staker, to be withdrawn after a delay. fn execute(self, deps: DepsMut, env: Env, _info: MessageInfo) -> Result { let chain_id = CHAIN_ID.load(deps.storage)?; diff --git a/contract/src/msgs/staking/execute/withdraw.rs b/contract/src/msgs/staking/execute/withdraw.rs index a58d186d..d61f93b2 100644 --- a/contract/src/msgs/staking/execute/withdraw.rs +++ b/contract/src/msgs/staking/execute/withdraw.rs @@ -1,13 +1,7 @@ -use cosmwasm_std::{coins, BankMsg}; -pub(crate) use seda_contract_common::msgs::staking::execute::withdraw::Execute; - use super::*; -use crate::{ - crypto::{hash, verify_proof}, - state::{inc_get_seq, CHAIN_ID, TOKEN}, -}; +use crate::state::*; -impl ExecuteHandler for Execute { +impl ExecuteHandler for execute::withdraw::Execute { /// Sends tokens back to the sender that are marked as pending withdrawal. fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { let chain_id = CHAIN_ID.load(deps.storage)?; diff --git a/contract/src/msgs/staking/test_helpers.rs b/contract/src/msgs/staking/test_helpers.rs index fa956d11..9b26e315 100644 --- a/contract/src/msgs/staking/test_helpers.rs +++ b/contract/src/msgs/staking/test_helpers.rs @@ -1,9 +1,7 @@ -use seda_contract_common::msgs::{ - self, - staking::{query::QueryMsg, Staker, StakingConfig}, +use super::{ + msgs::staking::{execute, query}, + *, }; - -use super::{execute::*, *}; use crate::{ crypto::hash, types::{Hasher, PublicKey}, @@ -14,9 +12,7 @@ use crate::{ impl TestInfo { #[track_caller] pub fn set_staking_config(&mut self, sender: &TestExecutor, config: StakingConfig) -> Result<(), ContractError> { - let msg = crate::msgs::ExecuteMsg::Staking( - seda_contract_common::msgs::staking::execute::ExecuteMsg::SetStakingConfig(config), - ); + let msg = config.into(); self.execute(sender, &msg) } @@ -36,61 +32,39 @@ impl TestInfo { &seq.to_be_bytes(), ]); - let msg = msgs::staking::execute::stake::Execute { + let msg = execute::stake::Execute { public_key: sender.pub_key(), proof: sender.prove(&msg_hash), memo, - }; - // TODO: impl `From` trait - let msg = - crate::msgs::ExecuteMsg::Staking(seda_contract_common::msgs::staking::execute::ExecuteMsg::Stake(msg)); + } + .into(); self.execute_with_funds(sender, &msg, amount) } - // #[track_caller] - // pub fn unregister(&mut self, sender: &TestExecutor) -> Result<(), ContractError> { - // let seq = self.get_account_sequence(sender.pub_key()); - // let msg_hash = hash([ - // "unregister".as_bytes(), - // self.chain_id(), - // self.contract_addr_bytes(), - // &seq.to_be_bytes(), - // ]); - // let msg = unregister::Execute { - // public_key: sender.pub_key(), - // proof: sender.prove(&msg_hash), - // }; - // let msg = - // crate::msgs::ExecuteMsg::Staking(seda_contract_common::msgs::staking::execute::ExecuteMsg::Stake(msg)); - - // self.execute(sender, &msg) - // } - #[track_caller] pub fn get_staker(&self, executor: PublicKey) -> Option { - self.query(QueryMsg::GetStaker { public_key: executor }).unwrap() + self.query(query::QueryMsg::GetStaker { public_key: executor }).unwrap() } - // #[track_caller] - // pub fn increase_stake(&mut self, sender: &mut TestExecutor, amount: u128) -> Result<(), ContractError> { - // let seq = self.get_account_sequence(sender.pub_key()); - // let msg_hash = hash([ - // "increase_stake".as_bytes(), - // self.chain_id(), - // self.contract_addr_bytes(), - // &seq.to_be_bytes(), - // ]); - // let msg = stake::Execute { - // public_key: sender.pub_key(), - // proof: sender.prove(&msg_hash), - // memo: None, - // }; - // let msg = - // crate::msgs::ExecuteMsg::Staking(seda_contract_common::msgs::staking::execute::ExecuteMsg::Stake(msg)); + #[track_caller] + pub fn increase_stake(&mut self, sender: &mut TestExecutor, amount: u128) -> Result<(), ContractError> { + let seq = self.get_account_sequence(sender.pub_key()); + let msg_hash = hash([ + "increase_stake".as_bytes(), + self.chain_id(), + self.contract_addr_bytes(), + &seq.to_be_bytes(), + ]); + let msg = execute::stake::Execute { + public_key: sender.pub_key(), + proof: sender.prove(&msg_hash), + memo: None, + } + .into(); - // self.execute_with_funds(sender, &msg, amount) - // } + self.execute_with_funds(sender, &msg, amount) + } #[track_caller] pub fn stake_with_no_funds( @@ -106,15 +80,12 @@ impl TestInfo { self.contract_addr_bytes(), &seq.to_be_bytes(), ]); - let msg = stake::Execute { + let msg = execute::stake::Execute { public_key: sender.pub_key(), proof: sender.prove(&msg_hash), memo, - }; - - // TODO: impl `From` trait - let msg = - crate::msgs::ExecuteMsg::Staking(seda_contract_common::msgs::staking::execute::ExecuteMsg::Stake(msg)); + } + .into(); self.execute(sender, &msg) } @@ -129,15 +100,12 @@ impl TestInfo { self.contract_addr_bytes(), &seq.to_be_bytes(), ]); - let msg = msgs::staking::execute::unstake::Execute { + let msg = execute::unstake::Execute { public_key: sender.pub_key(), proof: sender.prove(&msg_hash), amount: amount.into(), - }; - - // TODO: impl `From` trait - let msg = - crate::msgs::ExecuteMsg::Staking(seda_contract_common::msgs::staking::execute::ExecuteMsg::Unstake(msg)); + } + .into(); self.execute(sender, &msg) } @@ -152,15 +120,12 @@ impl TestInfo { self.contract_addr_bytes(), &seq.to_be_bytes(), ]); - let msg = msgs::staking::execute::withdraw::Execute { + let msg = execute::withdraw::Execute { public_key: sender.pub_key(), proof: sender.prove(&msg_hash), amount: amount.into(), - }; - - // TODO: impl `From` trait - let msg = - crate::msgs::ExecuteMsg::Staking(seda_contract_common::msgs::staking::execute::ExecuteMsg::Withdraw(msg)); + } + .into(); let res = self.execute(sender, &msg); sender.add_seda(10); @@ -169,12 +134,12 @@ impl TestInfo { #[track_caller] pub fn is_executor_eligible(&self, executor: PublicKey) -> bool { - self.query(QueryMsg::IsExecutorEligible { public_key: executor }) + self.query(query::QueryMsg::IsExecutorEligible { public_key: executor }) .unwrap() } #[track_caller] pub fn get_account_sequence(&self, public_key: PublicKey) -> Uint128 { - self.query(QueryMsg::GetAccountSeq { public_key }).unwrap() + self.query(query::QueryMsg::GetAccountSeq { public_key }).unwrap() } } diff --git a/contract/src/test_utils.rs b/contract/src/test_utils.rs index c7bf0876..994d7565 100644 --- a/contract/src/test_utils.rs +++ b/contract/src/test_utils.rs @@ -17,6 +17,7 @@ use k256::{ ecdsa::{SigningKey, VerifyingKey}, elliptic_curve::rand_core::OsRng, }; +use seda_contract_common::msgs::*; use serde::{de::DeserializeOwned, Serialize}; use sha3::{Digest, Keccak256}; use vrf_rs::Secp256k1Sha256; @@ -24,7 +25,6 @@ use vrf_rs::Secp256k1Sha256; use crate::{ contract::*, error::ContractError, - msgs::{ExecuteMsg, InstantiateMsg}, types::{Hash, PublicKey}, }; diff --git a/contract/src/types.rs b/contract/src/types.rs deleted file mode 100644 index f787d89d..00000000 --- a/contract/src/types.rs +++ /dev/null @@ -1,66 +0,0 @@ -use semver::Version; -use sha3::{Digest, Keccak256}; - -pub type Bytes = Vec; -// pub type Commitment = Hash; -pub type Memo = Vec; -pub type Hash = [u8; 32]; -pub type PublicKey = Vec; - -pub trait Hex: AsRef<[u8]> { - fn to_hex(&self) -> String { - hex::encode(self) - } -} - -impl Hex for Hash { - fn to_hex(&self) -> String { - hex::encode(self) - } -} - -pub trait Hasher { - fn hash(&self) -> Hash; -} - -impl Hasher for &str { - fn hash(&self) -> Hash { - let mut hasher = Keccak256::new(); - hasher.update(self.as_bytes()); - hasher.finalize().into() - } -} - -impl Hasher for String { - fn hash(&self) -> Hash { - let refer: &str = self.as_ref(); - refer.hash() - } -} - -impl Hasher for Version { - fn hash(&self) -> Hash { - self.to_string().hash() - } -} - -impl Hasher for Vec { - fn hash(&self) -> Hash { - let mut hasher = Keccak256::new(); - hasher.update(self); - hasher.finalize().into() - } -} - -impl Hasher for Option -where - T: AsRef<[u8]>, -{ - fn hash(&self) -> Hash { - let mut hasher = Keccak256::new(); - if let Some(inner) = self { - hasher.update(inner); - } - hasher.finalize().into() - } -} diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 33687793..42783805 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, env, process::Command}; use anyhow::{bail, Context, Result}; use rand::Rng; -use seda_contract::msgs::data_requests::{DataRequest, DR}; +// use seda_contract::msgs::data_requests::{DataRequest, DR}; use serde_json::json; use xshell::{cmd, Shell}; @@ -35,7 +35,7 @@ fn try_main() -> Result<()> { Some("help") => print_help()?, Some("wasm") => wasm(&sh)?, Some("wasm-opt") => wasm_opt(&sh)?, - Some("tally-data-req-fixture") => data_req_fixture(&sh)?, + // Some("tally-data-req-fixture") => data_req_fixture(&sh)?, _ => print_help()?, } @@ -69,73 +69,73 @@ fn wasm_opt(sh: &Shell) -> Result<()> { Ok(()) } -fn create_data_request( - dr_binary_id: [u8; 32], - tally_binary_id: [u8; 32], - replication_factor: u16, - tally_inputs: Vec, -) -> (String, DR) { - let id = rand::random(); - let dr = DataRequest { - version: semver::Version { - major: 1, - minor: 0, - patch: 0, - pre: semver::Prerelease::EMPTY, - build: semver::BuildMetadata::EMPTY, - }, - id, - dr_binary_id, - tally_binary_id, - dr_inputs: Default::default(), - tally_inputs, - memo: Default::default(), - replication_factor, - gas_price: 10u128.into(), - gas_limit: 20u128.into(), - seda_payload: Default::default(), - commits: Default::default(), - reveals: Default::default(), - payback_address: Default::default(), - }; - - (hex::encode(id), DR::Request(Box::new(dr))) -} - -fn tally_test_fixture() -> HashMap { - let dr_binary_id: [u8; 32] = rand::random(); - let tally_binary_id: [u8; 32] = rand::random(); - let replication_factor = rand::thread_rng().gen_range(1..=3); - - (0..replication_factor) - .map(|_| { - let inputs = [rand::thread_rng().gen_range::(1..=10); 5] - .into_iter() - .flat_map(|i| i.to_be_bytes()) - .collect(); - - create_data_request(dr_binary_id, tally_binary_id, replication_factor, inputs) - }) - .collect() -} - -fn data_req_fixture(_sh: &Shell) -> Result<()> { - let file = std::fs::OpenOptions::new() - .create(true) - .truncate(true) - .write(true) - .open("tally_data_request_fixture.json")?; - - let mut test_two_dr_ready_to_tally_data = tally_test_fixture(); - test_two_dr_ready_to_tally_data.extend(tally_test_fixture()); - - serde_json::to_writer( - file, - &json!({ - "test_one_dr_ready_to_tally": tally_test_fixture(), - "test_two_dr_ready_to_tally": test_two_dr_ready_to_tally_data, - }), - )?; - - Ok(()) -} +// fn create_data_request( +// dr_binary_id: [u8; 32], +// tally_binary_id: [u8; 32], +// replication_factor: u16, +// tally_inputs: Vec, +// ) -> (String, DR) { +// let id = rand::random(); +// let dr = DataRequest { +// version: semver::Version { +// major: 1, +// minor: 0, +// patch: 0, +// pre: semver::Prerelease::EMPTY, +// build: semver::BuildMetadata::EMPTY, +// }, +// id, +// dr_binary_id, +// tally_binary_id, +// dr_inputs: Default::default(), +// tally_inputs, +// memo: Default::default(), +// replication_factor, +// gas_price: 10u128.into(), +// gas_limit: 20u128.into(), +// seda_payload: Default::default(), +// commits: Default::default(), +// reveals: Default::default(), +// payback_address: Default::default(), +// }; + +// (hex::encode(id), DR::Request(Box::new(dr))) +// } + +// fn tally_test_fixture() -> HashMap { +// let dr_binary_id: [u8; 32] = rand::random(); +// let tally_binary_id: [u8; 32] = rand::random(); +// let replication_factor = rand::thread_rng().gen_range(1..=3); + +// (0..replication_factor) +// .map(|_| { +// let inputs = [rand::thread_rng().gen_range::(1..=10); 5] +// .into_iter() +// .flat_map(|i| i.to_be_bytes()) +// .collect(); + +// create_data_request(dr_binary_id, tally_binary_id, replication_factor, inputs) +// }) +// .collect() +// } + +// fn data_req_fixture(_sh: &Shell) -> Result<()> { +// let file = std::fs::OpenOptions::new() +// .create(true) +// .truncate(true) +// .write(true) +// .open("tally_data_request_fixture.json")?; + +// let mut test_two_dr_ready_to_tally_data = tally_test_fixture(); +// test_two_dr_ready_to_tally_data.extend(tally_test_fixture()); + +// serde_json::to_writer( +// file, +// &json!({ +// "test_one_dr_ready_to_tally": tally_test_fixture(), +// "test_two_dr_ready_to_tally": test_two_dr_ready_to_tally_data, +// }), +// )?; + +// Ok(()) +// } From 39e845c498657dbdc3007349708debb2f3c11cf8 Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Fri, 7 Jun 2024 13:17:00 -0600 Subject: [PATCH 07/14] refactor: move data requests to common --- Cargo.lock | 2 + common/Cargo.toml | 1 + .../data_requests/execute/commit_result.rs | 17 ++ common/src/msgs/data_requests/execute/mod.rs | 18 ++ .../data_requests/execute/post_request.rs | 16 ++ .../data_requests/execute/reveal_result.rs | 17 ++ common/src/msgs/data_requests/mod.rs | 9 + common/src/msgs/data_requests/query.rs | 28 +++ common/src/msgs/data_requests/types.rs | 228 ++++++++++++++++++ common/src/msgs/mod.rs | 5 +- .../data_requests/execute/commit_result.rs | 19 +- .../src/msgs/data_requests/execute/mod.rs | 25 +- .../data_requests/execute/post_request.rs | 18 +- .../data_requests/execute/reveal_result.rs | 19 +- contract/src/msgs/data_requests/mod.rs | 219 +---------------- contract/src/msgs/data_requests/query.rs | 32 +-- .../src/msgs/data_requests/test_helpers.rs | 14 +- contract/src/msgs/mod.rs | 6 +- xtask/Cargo.toml | 1 + xtask/src/main.rs | 144 +++++------ 20 files changed, 441 insertions(+), 397 deletions(-) create mode 100644 common/src/msgs/data_requests/execute/commit_result.rs create mode 100644 common/src/msgs/data_requests/execute/mod.rs create mode 100644 common/src/msgs/data_requests/execute/post_request.rs create mode 100644 common/src/msgs/data_requests/execute/reveal_result.rs create mode 100644 common/src/msgs/data_requests/mod.rs create mode 100644 common/src/msgs/data_requests/query.rs create mode 100644 common/src/msgs/data_requests/types.rs diff --git a/Cargo.lock b/Cargo.lock index 6bdf56b5..fc8ae114 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -698,6 +698,7 @@ version = "0.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", + "cw-storage-plus", "hex", "semver", "serde", @@ -942,6 +943,7 @@ dependencies = [ "hex", "rand", "seda-contract", + "seda-contract-common", "semver", "serde_json", "xshell", diff --git a/common/Cargo.toml b/common/Cargo.toml index fa0f4c46..370dc9f7 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -9,6 +9,7 @@ cosmwasm = ["cosmwasm-schema", "cosmwasm-std"] [dependencies] cosmwasm-schema = { workspace = true, optional = true } cosmwasm-std = { workspace = true, optional = true } +cw-storage-plus.workspace = true hex.workspace = true sha3.workspace = true semver.workspace = true diff --git a/common/src/msgs/data_requests/execute/commit_result.rs b/common/src/msgs/data_requests/execute/commit_result.rs new file mode 100644 index 00000000..31ca6262 --- /dev/null +++ b/common/src/msgs/data_requests/execute/commit_result.rs @@ -0,0 +1,17 @@ +use super::*; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub struct Execute { + pub dr_id: Hash, + pub commitment: Hash, + pub public_key: PublicKey, + pub proof: Vec, +} + +impl From for crate::msgs::ExecuteMsg { + fn from(value: Execute) -> Self { + super::ExecuteMsg::CommitDataResult(value).into() + } +} diff --git a/common/src/msgs/data_requests/execute/mod.rs b/common/src/msgs/data_requests/execute/mod.rs new file mode 100644 index 00000000..7dc098c9 --- /dev/null +++ b/common/src/msgs/data_requests/execute/mod.rs @@ -0,0 +1,18 @@ +use super::*; + +pub mod commit_result; +pub mod post_request; +pub mod reveal_result; + +#[cw_serde] +pub enum ExecuteMsg { + CommitDataResult(commit_result::Execute), + PostDataRequest(post_request::Execute), + RevealDataResult(reveal_result::Execute), +} + +impl From for super::ExecuteMsg { + fn from(value: ExecuteMsg) -> Self { + Self::DataRequest(Box::new(value)) + } +} diff --git a/common/src/msgs/data_requests/execute/post_request.rs b/common/src/msgs/data_requests/execute/post_request.rs new file mode 100644 index 00000000..211724af --- /dev/null +++ b/common/src/msgs/data_requests/execute/post_request.rs @@ -0,0 +1,16 @@ +use super::*; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub struct Execute { + pub posted_dr: PostDataRequestArgs, + pub seda_payload: Bytes, + pub payback_address: Bytes, +} + +impl From for crate::msgs::ExecuteMsg { + fn from(value: Execute) -> Self { + super::ExecuteMsg::PostDataRequest(value).into() + } +} diff --git a/common/src/msgs/data_requests/execute/reveal_result.rs b/common/src/msgs/data_requests/execute/reveal_result.rs new file mode 100644 index 00000000..498e018b --- /dev/null +++ b/common/src/msgs/data_requests/execute/reveal_result.rs @@ -0,0 +1,17 @@ +use super::*; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub struct Execute { + pub dr_id: Hash, + pub reveal_body: RevealBody, + pub public_key: PublicKey, + pub proof: Vec, +} + +impl From for crate::msgs::ExecuteMsg { + fn from(value: Execute) -> Self { + super::ExecuteMsg::RevealDataResult(value).into() + } +} diff --git a/common/src/msgs/data_requests/mod.rs b/common/src/msgs/data_requests/mod.rs new file mode 100644 index 00000000..dda352b7 --- /dev/null +++ b/common/src/msgs/data_requests/mod.rs @@ -0,0 +1,9 @@ +use std::collections::HashMap; + +use super::*; + +pub mod execute; +pub mod query; + +mod types; +pub use types::*; diff --git a/common/src/msgs/data_requests/query.rs b/common/src/msgs/data_requests/query.rs new file mode 100644 index 00000000..ed71437e --- /dev/null +++ b/common/src/msgs/data_requests/query.rs @@ -0,0 +1,28 @@ +use super::*; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(feature = "cosmwasm", derive(QueryResponses))] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub enum QueryMsg { + #[cfg_attr(feature = "cosmwasm", returns(DataRequest))] + GetDataRequest { dr_id: Hash }, + #[cfg_attr(feature = "cosmwasm", returns(Option))] + GetDataRequestCommitment { dr_id: Hash, public_key: PublicKey }, + #[cfg_attr(feature = "cosmwasm", returns(HashMap))] + GetDataRequestCommitments { dr_id: Hash }, + #[cfg_attr(feature = "cosmwasm", returns(Option))] + GetDataRequestReveal { dr_id: Hash, public_key: PublicKey }, + #[cfg_attr(feature = "cosmwasm", returns(HashMap))] + GetDataRequestReveals { dr_id: Hash }, + #[cfg_attr(feature = "cosmwasm", returns(DataResult))] + GetResolvedDataRequest { dr_id: Hash }, + #[cfg_attr(feature = "cosmwasm", returns(HashMap))] + GetDataRequestsByStatus { status: DataRequestStatus }, +} + +impl From for super::QueryMsg { + fn from(value: QueryMsg) -> Self { + Self::DataRequest(value) + } +} diff --git a/common/src/msgs/data_requests/types.rs b/common/src/msgs/data_requests/types.rs new file mode 100644 index 00000000..22ba7068 --- /dev/null +++ b/common/src/msgs/data_requests/types.rs @@ -0,0 +1,228 @@ +use semver::Version; +use sha3::{Digest, Keccak256}; + +use super::*; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub enum DataRequestStatus { + Committing, + Revealing, + Tallying, + Resolved, +} + +impl DataRequestStatus { + pub fn is_resolved(&self) -> bool { + matches!(self, DataRequestStatus::Resolved) + } +} + +#[cfg(feature = "cosmwasm")] +impl<'a> cw_storage_plus::PrimaryKey<'a> for &'a DataRequestStatus { + type Prefix = (); + type SubPrefix = (); + type Suffix = &'static str; + type SuperSuffix = &'static str; + + fn key(&self) -> Vec { + vec![cw_storage_plus::Key::Ref( + match self { + DataRequestStatus::Committing => "committing", + DataRequestStatus::Revealing => "revealing", + DataRequestStatus::Tallying => "tallying", + DataRequestStatus::Resolved => "resolved", + } + .as_bytes(), + )] + } +} + +/// Represents a data request at creation time +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub struct DataRequest { + /// Identifier + pub id: Hash, + + // DR definition + /// Semantic Version String + pub version: Version, + /// Identifier of DR WASM binary + pub dr_binary_id: Hash, + /// Inputs for DR WASM binary + pub dr_inputs: Bytes, + /// Identifier of Tally WASM binary + pub tally_binary_id: Hash, + /// Inputs for Tally WASM binary + pub tally_inputs: Bytes, + /// Amount of required DR executors + pub replication_factor: u16, + /// Amount of SEDA tokens per gas unit + pub gas_price: U128, + /// Maximum of gas units to be used by data request executors to resolve a data request + pub gas_limit: U128, + /// Public info attached to DR + pub memo: Memo, + + // Execution Information + /// Payback address set by the relayer + pub payback_address: Bytes, + /// Payload set by SEDA Protocol (e.g. OEV-enabled data requests) + pub seda_payload: Bytes, + /// Commitments submitted by executors + pub commits: HashMap, + /// Reveals submitted by executors + pub reveals: HashMap, +} + +impl DataRequest { + pub fn has_committer(&self, public_key: &str) -> bool { + self.commits.contains_key(public_key) + } + + pub fn get_commitment(&self, public_key: &str) -> Option<&Hash> { + self.commits.get(public_key) + } + + pub fn has_revealer(&self, public_key: &str) -> bool { + self.reveals.contains_key(public_key) + } + + pub fn reveal_started(&self) -> bool { + self.commits.len() >= self.replication_factor as usize + } + + pub fn reveal_over(&self) -> bool { + self.reveals.len() >= self.replication_factor as usize + } + + pub fn get_reveal(&self, public_key: &str) -> Option<&RevealBody> { + self.reveals.get(public_key) + } +} + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub enum DR { + Request(Box), + Result(DataResult), +} + +impl From for DR { + fn from(dr: DataRequest) -> Self { + DR::Request(Box::new(dr)) + } +} + +impl From for DR { + fn from(dr: DataResult) -> Self { + DR::Result(dr) + } +} + +/// Represents a resolved data result +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] +pub struct DataResult { + // DR Result + /// Semantic Version String + pub version: Version, + + /// Data Request Identifier + pub dr_id: Hash, + /// Block Height at which data request was finalized + pub block_height: u64, + /// Exit code of Tally WASM binary execution + pub exit_code: u8, + pub gas_used: U128, + /// Result from Tally WASM binary execution + pub result: Vec, + + // Fields from Data Request Execution + /// Payback address set by the relayer + pub payback_address: Vec, + /// Payload set by SEDA Protocol (e.g. OEV-enabled data requests) + pub seda_payload: Vec, +} + +impl Hasher for DataResult { + fn hash(&self) -> Hash { + let mut hasher = Keccak256::new(); + hasher.update(self.version.hash()); + hasher.update(self.dr_id); + hasher.update(self.block_height.to_be_bytes()); + hasher.update(self.exit_code.to_be_bytes()); + hasher.update(self.result.hash()); + hasher.update(&self.payback_address); + hasher.update(self.seda_payload.hash()); + hasher.finalize().into() + } +} + +/// A revealed data request result that is hashed and signed by the executor +#[cw_serde] +pub struct RevealBody { + pub salt: [u8; 32], + pub exit_code: u8, + pub gas_used: U128, + pub reveal: Vec, +} + +impl Hasher for RevealBody { + fn hash(&self) -> Hash { + let mut hasher = Keccak256::new(); + hasher.update(self.salt); + hasher.update(self.exit_code.to_be_bytes()); + hasher.update(self.gas_used.to_be_bytes()); + hasher.update(self.reveal.hash()); + hasher.finalize().into() + } +} + +#[cw_serde] +pub struct PostDataRequestArgs { + pub version: Version, + pub dr_binary_id: Hash, + pub dr_inputs: Bytes, + pub tally_binary_id: Hash, + pub tally_inputs: Bytes, + pub replication_factor: u16, + pub gas_price: U128, + pub gas_limit: U128, + pub memo: Memo, +} + +impl Hasher for PostDataRequestArgs { + fn hash(&self) -> Hash { + // hash non-fixed-length inputs + let mut dr_inputs_hasher = Keccak256::new(); + dr_inputs_hasher.update(&self.dr_inputs); + let dr_inputs_hash = dr_inputs_hasher.finalize(); + + let mut tally_inputs_hasher = Keccak256::new(); + tally_inputs_hasher.update(&self.tally_inputs); + let tally_inputs_hash = tally_inputs_hasher.finalize(); + + let mut memo_hasher = Keccak256::new(); + memo_hasher.update(&self.memo); + let memo_hash = memo_hasher.finalize(); + + // hash data request + let mut dr_hasher = Keccak256::new(); + dr_hasher.update(self.version.hash()); + dr_hasher.update(self.dr_binary_id); + dr_hasher.update(dr_inputs_hash); + dr_hasher.update(self.tally_binary_id); + dr_hasher.update(tally_inputs_hash); + dr_hasher.update(self.replication_factor.to_be_bytes()); + dr_hasher.update(self.gas_price.to_be_bytes()); + dr_hasher.update(self.gas_limit.to_be_bytes()); + dr_hasher.update(memo_hash); + dr_hasher.finalize().into() + } +} diff --git a/common/src/msgs/mod.rs b/common/src/msgs/mod.rs index ecaec474..1377ddc5 100644 --- a/common/src/msgs/mod.rs +++ b/common/src/msgs/mod.rs @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize}; use crate::types::*; +pub mod data_requests; pub mod owner; pub mod staking; @@ -13,7 +14,7 @@ pub mod staking; #[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] #[serde(untagged)] pub enum ExecuteMsg { - // DataRequest(Box), + DataRequest(Box), Staking(staking::execute::ExecuteMsg), Owner(owner::execute::ExecuteMsg), } @@ -26,7 +27,7 @@ pub enum ExecuteMsg { #[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] #[serde(untagged)] pub enum QueryMsg { - // DataRequest(data_requests::query::QueryMsg), + DataRequest(data_requests::query::QueryMsg), Staking(staking::query::QueryMsg), Owner(owner::query::QueryMsg), } diff --git a/contract/src/msgs/data_requests/execute/commit_result.rs b/contract/src/msgs/data_requests/execute/commit_result.rs index 5ea0ab98..2092a4f9 100644 --- a/contract/src/msgs/data_requests/execute/commit_result.rs +++ b/contract/src/msgs/data_requests/execute/commit_result.rs @@ -1,17 +1,9 @@ use super::*; use crate::state::{inc_get_seq, CHAIN_ID}; -#[cw_serde] -pub struct Execute { - pub(in crate::msgs::data_requests) dr_id: Hash, - pub(in crate::msgs::data_requests) commitment: Hash, - pub(in crate::msgs::data_requests) public_key: PublicKey, - pub(in crate::msgs::data_requests) proof: Vec, -} - -impl Execute { +impl ExecuteHandler for execute::commit_result::Execute { /// Posts a data result of a data request with an attached hash of the answer and salt. - pub fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { + fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { let chain_id = CHAIN_ID.load(deps.storage)?; // compute message hash let message_hash = hash([ @@ -55,10 +47,3 @@ impl Execute { )) } } - -#[cfg(test)] -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::CommitDataResult(value).into() - } -} diff --git a/contract/src/msgs/data_requests/execute/mod.rs b/contract/src/msgs/data_requests/execute/mod.rs index c9d280da..ba491688 100644 --- a/contract/src/msgs/data_requests/execute/mod.rs +++ b/contract/src/msgs/data_requests/execute/mod.rs @@ -1,29 +1,18 @@ -use super::*; +use super::{ + msgs::data_requests::execute::{self, ExecuteMsg}, + *, +}; pub(in crate::msgs::data_requests) mod commit_result; pub(in crate::msgs::data_requests) mod post_request; pub(in crate::msgs::data_requests) mod reveal_result; -#[cw_serde] -pub enum ExecuteMsg { - CommitDataResult(commit_result::Execute), - PostDataRequest(post_request::Execute), - RevealDataResult(reveal_result::Execute), -} - -impl ExecuteMsg { - pub fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { +impl ExecuteHandler for ExecuteMsg { + fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { match self { ExecuteMsg::CommitDataResult(msg) => msg.execute(deps, env, info), - ExecuteMsg::PostDataRequest(msg) => msg.execute(deps, info), + ExecuteMsg::PostDataRequest(msg) => msg.execute(deps, env, info), ExecuteMsg::RevealDataResult(msg) => msg.execute(deps, env, info), } } } - -#[cfg(test)] -impl From for super::ExecuteMsg { - fn from(value: ExecuteMsg) -> Self { - Self::DataRequest(Box::new(value)) - } -} diff --git a/contract/src/msgs/data_requests/execute/post_request.rs b/contract/src/msgs/data_requests/execute/post_request.rs index 6f26de2a..7df0d916 100644 --- a/contract/src/msgs/data_requests/execute/post_request.rs +++ b/contract/src/msgs/data_requests/execute/post_request.rs @@ -1,15 +1,8 @@ use super::*; -#[cw_serde] -pub struct Execute { - pub(in crate::msgs::data_requests) posted_dr: PostDataRequestArgs, - pub(in crate::msgs::data_requests) seda_payload: Bytes, - pub(in crate::msgs::data_requests) payback_address: Bytes, -} - -impl Execute { +impl ExecuteHandler for execute::post_request::Execute { /// Posts a data request to the pool - pub fn execute(self, deps: DepsMut, _info: MessageInfo) -> Result { + fn execute(self, deps: DepsMut, _env: Env, _info: MessageInfo) -> Result { // hash the inputs to get the data request id let dr_id = self.posted_dr.hash(); @@ -61,10 +54,3 @@ impl Execute { Ok(res) } } - -#[cfg(test)] -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::PostDataRequest(value).into() - } -} diff --git a/contract/src/msgs/data_requests/execute/reveal_result.rs b/contract/src/msgs/data_requests/execute/reveal_result.rs index 1d94e454..09419ad0 100644 --- a/contract/src/msgs/data_requests/execute/reveal_result.rs +++ b/contract/src/msgs/data_requests/execute/reveal_result.rs @@ -1,18 +1,10 @@ use super::*; use crate::state::{inc_get_seq, CHAIN_ID}; -#[cw_serde] -pub struct Execute { - pub(in crate::msgs::data_requests) dr_id: Hash, - pub(in crate::msgs::data_requests) reveal_body: RevealBody, - pub(in crate::msgs::data_requests) public_key: PublicKey, - pub(in crate::msgs::data_requests) proof: Vec, -} - -impl Execute { +impl ExecuteHandler for execute::reveal_result::Execute { /// Posts a data result of a data request with an attached result. /// This removes the data request from the pool and creates a new entry in the data results. - pub fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { + fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { let chain_id = CHAIN_ID.load(deps.storage)?; // compute hash of reveal body @@ -111,10 +103,3 @@ impl Execute { Ok(response) } } - -#[cfg(test)] -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::RevealDataResult(value).into() - } -} diff --git a/contract/src/msgs/data_requests/mod.rs b/contract/src/msgs/data_requests/mod.rs index 914280fa..dbbb8658 100644 --- a/contract/src/msgs/data_requests/mod.rs +++ b/contract/src/msgs/data_requests/mod.rs @@ -1,8 +1,6 @@ use std::collections::{HashMap, HashSet}; -use cw_storage_plus::{Key, PrimaryKey}; -use semver::Version; -use sha3::{Digest, Keccak256}; +use msgs::data_requests::*; use super::*; @@ -14,218 +12,3 @@ pub mod state; pub mod test_helpers; #[cfg(test)] mod tests; - -#[cw_serde] -pub enum DataRequestStatus { - Committing, - Revealing, - Tallying, - Resolved, -} - -impl DataRequestStatus { - pub fn is_resolved(&self) -> bool { - matches!(self, DataRequestStatus::Resolved) - } -} - -impl<'a> PrimaryKey<'a> for &'a DataRequestStatus { - type Prefix = (); - type SubPrefix = (); - type Suffix = &'static str; - type SuperSuffix = &'static str; - - fn key(&self) -> Vec { - vec![Key::Ref( - match self { - DataRequestStatus::Committing => "committing", - DataRequestStatus::Revealing => "revealing", - DataRequestStatus::Tallying => "tallying", - DataRequestStatus::Resolved => "resolved", - } - .as_bytes(), - )] - } -} - -/// Represents a data request at creation time -#[cw_serde] -pub struct DataRequest { - /// Identifier - pub id: Hash, - - // DR definition - /// Semantic Version String - pub version: Version, - /// Identifier of DR WASM binary - pub dr_binary_id: Hash, - /// Inputs for DR WASM binary - pub dr_inputs: Bytes, - /// Identifier of Tally WASM binary - pub tally_binary_id: Hash, - /// Inputs for Tally WASM binary - pub tally_inputs: Bytes, - /// Amount of required DR executors - pub replication_factor: u16, - /// Amount of SEDA tokens per gas unit - pub gas_price: Uint128, - /// Maximum of gas units to be used by data request executors to resolve a data request - pub gas_limit: Uint128, - /// Public info attached to DR - pub memo: Memo, - - // Execution Information - /// Payback address set by the relayer - pub payback_address: Bytes, - /// Payload set by SEDA Protocol (e.g. OEV-enabled data requests) - pub seda_payload: Bytes, - /// Commitments submitted by executors - pub commits: HashMap, - /// Reveals submitted by executors - pub reveals: HashMap, -} - -impl DataRequest { - pub fn has_committer(&self, public_key: &str) -> bool { - self.commits.contains_key(public_key) - } - - pub fn get_commitment(&self, public_key: &str) -> Option<&Hash> { - self.commits.get(public_key) - } - - pub fn has_revealer(&self, public_key: &str) -> bool { - self.reveals.contains_key(public_key) - } - - pub fn reveal_started(&self) -> bool { - self.commits.len() >= self.replication_factor as usize - } - - pub fn reveal_over(&self) -> bool { - self.reveals.len() >= self.replication_factor as usize - } - - pub fn get_reveal(&self, public_key: &str) -> Option<&RevealBody> { - self.reveals.get(public_key) - } -} - -#[cw_serde] -pub enum DR { - Request(Box), - Result(DataResult), -} - -impl From for DR { - fn from(dr: DataRequest) -> Self { - DR::Request(Box::new(dr)) - } -} - -impl From for DR { - fn from(dr: DataResult) -> Self { - DR::Result(dr) - } -} - -/// Represents a resolved data result -#[cw_serde] -pub struct DataResult { - // DR Result - /// Semantic Version String - pub version: Version, - - /// Data Request Identifier - pub dr_id: Hash, - /// Block Height at which data request was finalized - pub block_height: u64, - /// Exit code of Tally WASM binary execution - pub exit_code: u8, - pub gas_used: Uint128, - /// Result from Tally WASM binary execution - pub result: Vec, - - // Fields from Data Request Execution - /// Payback address set by the relayer - pub payback_address: Vec, - /// Payload set by SEDA Protocol (e.g. OEV-enabled data requests) - pub seda_payload: Vec, -} - -impl Hasher for DataResult { - fn hash(&self) -> Hash { - let mut hasher = Keccak256::new(); - hasher.update(self.version.hash()); - hasher.update(self.dr_id); - hasher.update(self.block_height.to_be_bytes()); - hasher.update(self.exit_code.to_be_bytes()); - hasher.update(self.result.hash()); - hasher.update(&self.payback_address); - hasher.update(self.seda_payload.hash()); - hasher.finalize().into() - } -} - -/// A revealed data request result that is hashed and signed by the executor -#[cw_serde] -pub struct RevealBody { - pub salt: [u8; 32], - pub exit_code: u8, - pub gas_used: Uint128, - pub reveal: Vec, -} - -impl Hasher for RevealBody { - fn hash(&self) -> Hash { - let mut hasher = Keccak256::new(); - hasher.update(self.salt); - hasher.update(self.exit_code.to_be_bytes()); - hasher.update(self.gas_used.to_be_bytes()); - hasher.update(self.reveal.hash()); - hasher.finalize().into() - } -} - -#[cw_serde] -pub struct PostDataRequestArgs { - pub version: Version, - pub dr_binary_id: Hash, - pub dr_inputs: Bytes, - pub tally_binary_id: Hash, - pub tally_inputs: Bytes, - pub replication_factor: u16, - pub gas_price: Uint128, - pub gas_limit: Uint128, - pub memo: Memo, -} - -impl Hasher for PostDataRequestArgs { - fn hash(&self) -> Hash { - // hash non-fixed-length inputs - let mut dr_inputs_hasher = Keccak256::new(); - dr_inputs_hasher.update(&self.dr_inputs); - let dr_inputs_hash = dr_inputs_hasher.finalize(); - - let mut tally_inputs_hasher = Keccak256::new(); - tally_inputs_hasher.update(&self.tally_inputs); - let tally_inputs_hash = tally_inputs_hasher.finalize(); - - let mut memo_hasher = Keccak256::new(); - memo_hasher.update(&self.memo); - let memo_hash = memo_hasher.finalize(); - - // hash data request - let mut dr_hasher = Keccak256::new(); - dr_hasher.update(self.version.hash()); - dr_hasher.update(self.dr_binary_id); - dr_hasher.update(dr_inputs_hash); - dr_hasher.update(self.tally_binary_id); - dr_hasher.update(tally_inputs_hash); - dr_hasher.update(self.replication_factor.to_be_bytes()); - dr_hasher.update(self.gas_price.to_be_bytes()); - dr_hasher.update(self.gas_limit.to_be_bytes()); - dr_hasher.update(memo_hash); - dr_hasher.finalize().into() - } -} diff --git a/contract/src/msgs/data_requests/query.rs b/contract/src/msgs/data_requests/query.rs index 211d13d4..f4772e66 100644 --- a/contract/src/msgs/data_requests/query.rs +++ b/contract/src/msgs/data_requests/query.rs @@ -1,26 +1,7 @@ -use super::*; +use super::{msgs::data_requests::query::QueryMsg, *}; -#[cw_serde] -#[derive(QueryResponses)] -pub enum QueryMsg { - #[returns(DataRequest)] - GetDataRequest { dr_id: Hash }, - #[returns(Option)] - GetDataRequestCommitment { dr_id: Hash, public_key: PublicKey }, - #[returns(HashMap)] - GetDataRequestCommitments { dr_id: Hash }, - #[returns(Option)] - GetDataRequestReveal { dr_id: Hash, public_key: PublicKey }, - #[returns(HashMap)] - GetDataRequestReveals { dr_id: Hash }, - #[returns(DataResult)] - GetResolvedDataRequest { dr_id: Hash }, - #[returns(HashMap)] - GetDataRequestsByStatus { status: DataRequestStatus }, -} - -impl QueryMsg { - pub fn query(self, deps: Deps, _env: Env) -> StdResult { +impl QueryHandler for QueryMsg { + fn query(self, deps: Deps, _env: Env) -> StdResult { match self { QueryMsg::GetDataRequest { dr_id } => to_json_binary(&state::may_load_req(deps.storage, &dr_id)?), QueryMsg::GetDataRequestCommitment { dr_id, public_key } => { @@ -50,10 +31,3 @@ impl QueryMsg { } } } - -#[cfg(test)] -impl From for super::QueryMsg { - fn from(value: QueryMsg) -> Self { - Self::DataRequest(value) - } -} diff --git a/contract/src/msgs/data_requests/test_helpers.rs b/contract/src/msgs/data_requests/test_helpers.rs index 10e100c4..46b4e829 100644 --- a/contract/src/msgs/data_requests/test_helpers.rs +++ b/contract/src/msgs/data_requests/test_helpers.rs @@ -1,6 +1,10 @@ -use semver::{BuildMetadata, Prerelease}; +use semver::{BuildMetadata, Prerelease, Version}; +use sha3::{Digest, Keccak256}; -use super::{execute::*, *}; +use super::{ + msgs::data_requests::{execute, query}, + *, +}; use crate::{crypto::hash, TestExecutor, TestInfo}; pub fn calculate_dr_id_and_args(nonce: u128, replication_factor: u16) -> PostDataRequestArgs { @@ -84,7 +88,7 @@ impl TestInfo { seda_payload: Vec, payback_address: Vec, ) -> Result { - let msg = post_request::Execute { + let msg = execute::post_request::Execute { posted_dr, seda_payload, payback_address, @@ -115,7 +119,7 @@ impl TestInfo { &seq.to_be_bytes(), ]); - let msg = commit_result::Execute { + let msg = execute::commit_result::Execute { dr_id, commitment, public_key: sender.pub_key(), @@ -147,7 +151,7 @@ impl TestInfo { &seq.to_be_bytes(), ]); - let msg = reveal_result::Execute { + let msg = execute::reveal_result::Execute { reveal_body, dr_id, public_key: sender.pub_key(), diff --git a/contract/src/msgs/mod.rs b/contract/src/msgs/mod.rs index 3c5b3a4d..3030d220 100644 --- a/contract/src/msgs/mod.rs +++ b/contract/src/msgs/mod.rs @@ -12,7 +12,7 @@ use crate::{ types::*, }; -// pub mod data_requests; +pub mod data_requests; pub mod owner; pub mod staking; @@ -27,7 +27,7 @@ pub trait ExecuteHandler { impl ExecuteHandler for msgs::ExecuteMsg { fn execute(self, deps: DepsMut, env: Env, info: MessageInfo) -> Result { match self { - // msgs::ExecuteMsg::DataRequest(msg) => msg.execute(deps, env, info), + msgs::ExecuteMsg::DataRequest(msg) => msg.execute(deps, env, info), msgs::ExecuteMsg::Staking(msg) => msg.execute(deps, env, info), msgs::ExecuteMsg::Owner(msg) => msg.execute(deps, env, info), } @@ -37,7 +37,7 @@ impl ExecuteHandler for msgs::ExecuteMsg { impl QueryHandler for msgs::QueryMsg { fn query(self, deps: Deps, env: Env) -> StdResult { match self { - // msgs::QueryMsg::DataRequest(msg) => msg.query(deps, env), + msgs::QueryMsg::DataRequest(msg) => msg.query(deps, env), msgs::QueryMsg::Staking(msg) => msg.query(deps, env), msgs::QueryMsg::Owner(msg) => msg.query(deps, env), } diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index a2c3cd1e..26d2f4e9 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" anyhow.workspace = true hex.workspace = true seda-contract.workspace = true +seda-contract-common.workspace = true semver.workspace = true serde_json.workspace = true rand.workspace = true diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 42783805..fa4d0652 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, env, process::Command}; use anyhow::{bail, Context, Result}; use rand::Rng; -// use seda_contract::msgs::data_requests::{DataRequest, DR}; +use seda_contract_common::msgs::data_requests::{DataRequest, DR}; use serde_json::json; use xshell::{cmd, Shell}; @@ -35,7 +35,7 @@ fn try_main() -> Result<()> { Some("help") => print_help()?, Some("wasm") => wasm(&sh)?, Some("wasm-opt") => wasm_opt(&sh)?, - // Some("tally-data-req-fixture") => data_req_fixture(&sh)?, + Some("tally-data-req-fixture") => tally_data_req_fixture(&sh)?, _ => print_help()?, } @@ -69,73 +69,73 @@ fn wasm_opt(sh: &Shell) -> Result<()> { Ok(()) } -// fn create_data_request( -// dr_binary_id: [u8; 32], -// tally_binary_id: [u8; 32], -// replication_factor: u16, -// tally_inputs: Vec, -// ) -> (String, DR) { -// let id = rand::random(); -// let dr = DataRequest { -// version: semver::Version { -// major: 1, -// minor: 0, -// patch: 0, -// pre: semver::Prerelease::EMPTY, -// build: semver::BuildMetadata::EMPTY, -// }, -// id, -// dr_binary_id, -// tally_binary_id, -// dr_inputs: Default::default(), -// tally_inputs, -// memo: Default::default(), -// replication_factor, -// gas_price: 10u128.into(), -// gas_limit: 20u128.into(), -// seda_payload: Default::default(), -// commits: Default::default(), -// reveals: Default::default(), -// payback_address: Default::default(), -// }; - -// (hex::encode(id), DR::Request(Box::new(dr))) -// } - -// fn tally_test_fixture() -> HashMap { -// let dr_binary_id: [u8; 32] = rand::random(); -// let tally_binary_id: [u8; 32] = rand::random(); -// let replication_factor = rand::thread_rng().gen_range(1..=3); - -// (0..replication_factor) -// .map(|_| { -// let inputs = [rand::thread_rng().gen_range::(1..=10); 5] -// .into_iter() -// .flat_map(|i| i.to_be_bytes()) -// .collect(); - -// create_data_request(dr_binary_id, tally_binary_id, replication_factor, inputs) -// }) -// .collect() -// } - -// fn data_req_fixture(_sh: &Shell) -> Result<()> { -// let file = std::fs::OpenOptions::new() -// .create(true) -// .truncate(true) -// .write(true) -// .open("tally_data_request_fixture.json")?; - -// let mut test_two_dr_ready_to_tally_data = tally_test_fixture(); -// test_two_dr_ready_to_tally_data.extend(tally_test_fixture()); - -// serde_json::to_writer( -// file, -// &json!({ -// "test_one_dr_ready_to_tally": tally_test_fixture(), -// "test_two_dr_ready_to_tally": test_two_dr_ready_to_tally_data, -// }), -// )?; - -// Ok(()) -// } +fn create_data_request( + dr_binary_id: [u8; 32], + tally_binary_id: [u8; 32], + replication_factor: u16, + tally_inputs: Vec, +) -> (String, DR) { + let id = rand::random(); + let dr = DataRequest { + version: semver::Version { + major: 1, + minor: 0, + patch: 0, + pre: semver::Prerelease::EMPTY, + build: semver::BuildMetadata::EMPTY, + }, + id, + dr_binary_id, + tally_binary_id, + dr_inputs: Default::default(), + tally_inputs, + memo: Default::default(), + replication_factor, + gas_price: 10u128.into(), + gas_limit: 20u128.into(), + seda_payload: Default::default(), + commits: Default::default(), + reveals: Default::default(), + payback_address: Default::default(), + }; + + (hex::encode(id), DR::Request(Box::new(dr))) +} + +fn tally_test_fixture() -> HashMap { + let dr_binary_id: [u8; 32] = rand::random(); + let tally_binary_id: [u8; 32] = rand::random(); + let replication_factor = rand::thread_rng().gen_range(1..=3); + + (0..replication_factor) + .map(|_| { + let inputs = [rand::thread_rng().gen_range::(1..=10); 5] + .into_iter() + .flat_map(|i| i.to_be_bytes()) + .collect(); + + create_data_request(dr_binary_id, tally_binary_id, replication_factor, inputs) + }) + .collect() +} + +fn tally_data_req_fixture(_sh: &Shell) -> Result<()> { + let file = std::fs::OpenOptions::new() + .create(true) + .truncate(true) + .write(true) + .open("tally_data_request_fixture.json")?; + + let mut test_two_dr_ready_to_tally_data = tally_test_fixture(); + test_two_dr_ready_to_tally_data.extend(tally_test_fixture()); + + serde_json::to_writer( + file, + &json!({ + "test_one_dr_ready_to_tally": tally_test_fixture(), + "test_two_dr_ready_to_tally": test_two_dr_ready_to_tally_data, + }), + )?; + + Ok(()) +} From e97b53280ced27a8e31ef28e787d6f0dc35be667 Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Fri, 7 Jun 2024 13:21:35 -0600 Subject: [PATCH 08/14] refactor: trait names nit --- common/src/msgs/data_requests/types.rs | 6 +++--- common/src/types.rs | 16 ++++++++-------- contract/src/msgs/staking/test_helpers.rs | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/common/src/msgs/data_requests/types.rs b/common/src/msgs/data_requests/types.rs index 22ba7068..eef6c72f 100644 --- a/common/src/msgs/data_requests/types.rs +++ b/common/src/msgs/data_requests/types.rs @@ -150,7 +150,7 @@ pub struct DataResult { pub seda_payload: Vec, } -impl Hasher for DataResult { +impl HashSelf for DataResult { fn hash(&self) -> Hash { let mut hasher = Keccak256::new(); hasher.update(self.version.hash()); @@ -173,7 +173,7 @@ pub struct RevealBody { pub reveal: Vec, } -impl Hasher for RevealBody { +impl HashSelf for RevealBody { fn hash(&self) -> Hash { let mut hasher = Keccak256::new(); hasher.update(self.salt); @@ -197,7 +197,7 @@ pub struct PostDataRequestArgs { pub memo: Memo, } -impl Hasher for PostDataRequestArgs { +impl HashSelf for PostDataRequestArgs { fn hash(&self) -> Hash { // hash non-fixed-length inputs let mut dr_inputs_hasher = Keccak256::new(); diff --git a/common/src/types.rs b/common/src/types.rs index 84cb8099..fb4ff68b 100644 --- a/common/src/types.rs +++ b/common/src/types.rs @@ -15,23 +15,23 @@ pub type Memo = Vec; pub type Hash = [u8; 32]; pub type PublicKey = Vec; -pub trait Hex: AsRef<[u8]> { +pub trait ToHexStr: AsRef<[u8]> { fn to_hex(&self) -> String { hex::encode(self) } } -impl Hex for Hash { +impl ToHexStr for Hash { fn to_hex(&self) -> String { hex::encode(self) } } -pub trait Hasher { +pub trait HashSelf { fn hash(&self) -> Hash; } -impl Hasher for &str { +impl HashSelf for &str { fn hash(&self) -> Hash { let mut hasher = Keccak256::new(); hasher.update(self.as_bytes()); @@ -39,20 +39,20 @@ impl Hasher for &str { } } -impl Hasher for String { +impl HashSelf for String { fn hash(&self) -> Hash { let refer: &str = self.as_ref(); refer.hash() } } -impl Hasher for Version { +impl HashSelf for Version { fn hash(&self) -> Hash { self.to_string().hash() } } -impl Hasher for Vec { +impl HashSelf for Vec { fn hash(&self) -> Hash { let mut hasher = Keccak256::new(); hasher.update(self); @@ -60,7 +60,7 @@ impl Hasher for Vec { } } -impl Hasher for Option +impl HashSelf for Option where T: AsRef<[u8]>, { diff --git a/contract/src/msgs/staking/test_helpers.rs b/contract/src/msgs/staking/test_helpers.rs index 9b26e315..af872c6e 100644 --- a/contract/src/msgs/staking/test_helpers.rs +++ b/contract/src/msgs/staking/test_helpers.rs @@ -4,7 +4,7 @@ use super::{ }; use crate::{ crypto::hash, - types::{Hasher, PublicKey}, + types::{HashSelf, PublicKey}, TestExecutor, TestInfo, }; From 123b7967537709e0d2b4a461b26958720f35433f Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Fri, 7 Jun 2024 13:50:38 -0600 Subject: [PATCH 09/14] refactor: move crypto to common --- Cargo.lock | 2 ++ common/Cargo.toml | 3 +++ {contract => common}/src/crypto.rs | 8 ++++--- common/src/error.rs | 24 +++++++++++++++++++ common/src/lib.rs | 2 ++ common/src/msgs/mod.rs | 2 +- common/src/types.rs | 5 +--- contract/Cargo.toml | 12 ++++++---- contract/src/error.rs | 15 +----------- contract/src/lib.rs | 9 ------- .../src/msgs/data_requests/test_helpers.rs | 2 +- contract/src/msgs/mod.rs | 16 ++++++------- contract/src/msgs/staking/execute/unstake.rs | 5 +--- contract/src/msgs/staking/test_helpers.rs | 1 - 14 files changed, 56 insertions(+), 50 deletions(-) rename {contract => common}/src/crypto.rs (78%) create mode 100644 common/src/error.rs diff --git a/Cargo.lock b/Cargo.lock index fc8ae114..3dfcac66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -703,6 +703,8 @@ dependencies = [ "semver", "serde", "sha3", + "thiserror", + "vrf-rs", ] [[package]] diff --git a/common/Cargo.toml b/common/Cargo.toml index 370dc9f7..267faae8 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [features] cosmwasm = ["cosmwasm-schema", "cosmwasm-std"] +test-utils = [] [dependencies] cosmwasm-schema = { workspace = true, optional = true } @@ -14,3 +15,5 @@ hex.workspace = true sha3.workspace = true semver.workspace = true serde = { workspace = true, optional = true } +thiserror.workspace = true +vrf-rs.workspace = true diff --git a/contract/src/crypto.rs b/common/src/crypto.rs similarity index 78% rename from contract/src/crypto.rs rename to common/src/crypto.rs index 14151624..9269aa78 100644 --- a/contract/src/crypto.rs +++ b/common/src/crypto.rs @@ -1,14 +1,16 @@ use sha3::{Digest, Keccak256}; use vrf_rs::Secp256k1Sha256; -use crate::{error::ContractError, types::Hash}; +use crate::{error::Result, types::Hash}; -pub fn verify_proof(public_key: &[u8], proof: &[u8], hash: Hash) -> Result<(), ContractError> { +pub fn verify_proof(public_key: &[u8], proof: &[u8], hash: Hash) -> Result<()> { let verifier = Secp256k1Sha256::default(); let verifed = verifier.verify(public_key, proof, &hash); // If we don't get an error it's always ok - verifed.map_err(ContractError::from).map(|_| ()) + verifed?; + + Ok(()) } pub fn hash<'a, I>(iter: I) -> [u8; 32] diff --git a/common/src/error.rs b/common/src/error.rs new file mode 100644 index 00000000..82f7bb84 --- /dev/null +++ b/common/src/error.rs @@ -0,0 +1,24 @@ +use thiserror::Error; +use vrf_rs::error::VrfError; + +// We need it to be cloneable for tests :c +#[derive(Error, Debug, PartialEq)] +#[cfg_attr(feature = "test-utils", derive(Clone))] +pub enum Error { + #[cfg(not(feature = "test-utils"))] + #[error(transparent)] + Prove(#[from] VrfError), + + #[cfg(feature = "test-utils")] + #[error("{0}")] + Prove(String), +} + +#[cfg(feature = "test-utils")] +impl From for Error { + fn from(err: VrfError) -> Self { + Error::Prove(err.to_string()) + } +} + +pub type Result = core::result::Result; diff --git a/common/src/lib.rs b/common/src/lib.rs index a6643b5c..e394f297 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -1,2 +1,4 @@ +pub mod crypto; +pub mod error; pub mod msgs; pub mod types; diff --git a/common/src/msgs/mod.rs b/common/src/msgs/mod.rs index 1377ddc5..0ad15153 100644 --- a/common/src/msgs/mod.rs +++ b/common/src/msgs/mod.rs @@ -3,7 +3,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; #[cfg(not(feature = "cosmwasm"))] use serde::{Deserialize, Serialize}; -use crate::types::*; +use crate::{crypto::*, types::*}; pub mod data_requests; pub mod owner; diff --git a/common/src/types.rs b/common/src/types.rs index fb4ff68b..29ef90c1 100644 --- a/common/src/types.rs +++ b/common/src/types.rs @@ -1,8 +1,5 @@ #[cfg(feature = "cosmwasm")] -use cosmwasm_std::Uint128; - -#[cfg(feature = "cosmwasm")] -pub(crate) type U128 = Uint128; +pub(crate) type U128 = cosmwasm_std::Uint128; #[cfg(not(feature = "cosmwasm"))] pub(crate) type U128 = String; diff --git a/contract/Cargo.toml b/contract/Cargo.toml index ff05397c..9231e84a 100644 --- a/contract/Cargo.toml +++ b/contract/Cargo.toml @@ -4,9 +4,9 @@ version = "0.1.0" edition = "2021" exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. - "contract.wasm", - "hash.txt", + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", ] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -35,7 +35,7 @@ cw-utils = { workspace = true } cw2 = { workspace = true } hex = { workspace = true } schemars = { workspace = true } -seda-contract-common ={ workspace = true, features = ["cosmwasm"]} +seda-contract-common = { workspace = true, features = ["cosmwasm"] } semver = { workspace = true } serde = { workspace = true } serde-big-array = { workspace = true } @@ -46,4 +46,8 @@ vrf-rs = { workspace = true } [dev-dependencies] cw-multi-test = { workspace = true } k256 = { workspace = true } +seda-contract-common = { workspace = true, features = [ + "cosmwasm", + "test-utils", +] } serde_json = { workspace = true } diff --git a/contract/src/error.rs b/contract/src/error.rs index e57752cc..2003a52f 100644 --- a/contract/src/error.rs +++ b/contract/src/error.rs @@ -1,7 +1,6 @@ use cosmwasm_std::{StdError, Uint128}; use hex::FromHexError; use thiserror::Error; -use vrf_rs::error::VrfError; #[derive(Error, Debug, PartialEq)] #[cfg_attr(test, derive(Clone))] @@ -67,13 +66,8 @@ pub enum ContractError { #[error("FromHex: Invalid hexadecimal input: {0}")] FromHex(#[from] FromHexError), - #[cfg(not(test))] #[error(transparent)] - Prove(#[from] VrfError), - - #[cfg(test)] - #[error("{0}")] - Prove(String), + Common(#[from] seda_contract_common::error::Error), } #[cfg(test)] @@ -82,10 +76,3 @@ impl From for ContractError { ContractError::Std(err.to_string()) } } - -#[cfg(test)] -impl From for ContractError { - fn from(err: VrfError) -> Self { - ContractError::Prove(err.to_string()) - } -} diff --git a/contract/src/lib.rs b/contract/src/lib.rs index af7de396..f553f8cb 100644 --- a/contract/src/lib.rs +++ b/contract/src/lib.rs @@ -1,6 +1,5 @@ pub mod consts; pub mod contract; -mod crypto; mod error; pub mod msgs; pub mod state; @@ -12,11 +11,3 @@ use seda_contract_common::types; mod test_utils; #[cfg(test)] pub use test_utils::*; -// pub mod test_helpers; -#[path = ""] -#[cfg(test)] -pub(crate) mod test { - - // mod config_test; - // mod staking_test; -} diff --git a/contract/src/msgs/data_requests/test_helpers.rs b/contract/src/msgs/data_requests/test_helpers.rs index 46b4e829..ce33c3a3 100644 --- a/contract/src/msgs/data_requests/test_helpers.rs +++ b/contract/src/msgs/data_requests/test_helpers.rs @@ -5,7 +5,7 @@ use super::{ msgs::data_requests::{execute, query}, *, }; -use crate::{crypto::hash, TestExecutor, TestInfo}; +use crate::{TestExecutor, TestInfo}; pub fn calculate_dr_id_and_args(nonce: u128, replication_factor: u16) -> PostDataRequestArgs { let dr_binary_id: Hash = "dr_binary_id".hash(); diff --git a/contract/src/msgs/mod.rs b/contract/src/msgs/mod.rs index 3030d220..80430669 100644 --- a/contract/src/msgs/mod.rs +++ b/contract/src/msgs/mod.rs @@ -1,16 +1,14 @@ use cosmwasm_std::*; use cw_storage_plus::{Item, Map}; -use seda_contract_common::msgs::{ - self, - staking::{Staker, StakingConfig}, +use seda_contract_common::{ + crypto::*, + msgs::{ + self, + staking::{Staker, StakingConfig}, + }, }; -use crate::{ - contract::CONTRACT_VERSION, - crypto::{hash, verify_proof}, - error::ContractError, - types::*, -}; +use crate::{contract::CONTRACT_VERSION, error::ContractError, types::*}; pub mod data_requests; pub mod owner; diff --git a/contract/src/msgs/staking/execute/unstake.rs b/contract/src/msgs/staking/execute/unstake.rs index 20d8c261..b0f771d1 100644 --- a/contract/src/msgs/staking/execute/unstake.rs +++ b/contract/src/msgs/staking/execute/unstake.rs @@ -1,8 +1,5 @@ use super::*; -use crate::{ - crypto::{hash, verify_proof}, - state::*, -}; +use crate::state::*; impl ExecuteHandler for execute::unstake::Execute { /// Unstakes tokens from a given staker, to be withdrawn after a delay. diff --git a/contract/src/msgs/staking/test_helpers.rs b/contract/src/msgs/staking/test_helpers.rs index af872c6e..0e08dedf 100644 --- a/contract/src/msgs/staking/test_helpers.rs +++ b/contract/src/msgs/staking/test_helpers.rs @@ -3,7 +3,6 @@ use super::{ *, }; use crate::{ - crypto::hash, types::{HashSelf, PublicKey}, TestExecutor, TestInfo, From 4b42172e65f9e0b78eab2f55c5fdb7721307ee50 Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Fri, 7 Jun 2024 14:29:29 -0600 Subject: [PATCH 10/14] fix: clippy --- common/src/msgs/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/msgs/mod.rs b/common/src/msgs/mod.rs index 0ad15153..1377ddc5 100644 --- a/common/src/msgs/mod.rs +++ b/common/src/msgs/mod.rs @@ -3,7 +3,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; #[cfg(not(feature = "cosmwasm"))] use serde::{Deserialize, Serialize}; -use crate::{crypto::*, types::*}; +use crate::types::*; pub mod data_requests; pub mod owner; From f186d77b4140825d92cda786d861a4d9d79bfb4d Mon Sep 17 00:00:00 2001 From: Mario Cao Date: Mon, 10 Jun 2024 11:48:18 +0200 Subject: [PATCH 11/14] fix(common): add missing cfg for not cosmwasm --- common/Cargo.toml | 1 + common/src/msgs/data_requests/execute/mod.rs | 3 ++- common/src/msgs/data_requests/types.rs | 6 ++++-- common/src/msgs/staking/types.rs | 6 +++--- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/common/Cargo.toml b/common/Cargo.toml index 267faae8..57ba2679 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2021" [features] +default = ["serde"] cosmwasm = ["cosmwasm-schema", "cosmwasm-std"] test-utils = [] diff --git a/common/src/msgs/data_requests/execute/mod.rs b/common/src/msgs/data_requests/execute/mod.rs index 7dc098c9..fbd62d2e 100644 --- a/common/src/msgs/data_requests/execute/mod.rs +++ b/common/src/msgs/data_requests/execute/mod.rs @@ -4,7 +4,8 @@ pub mod commit_result; pub mod post_request; pub mod reveal_result; -#[cw_serde] +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] pub enum ExecuteMsg { CommitDataResult(commit_result::Execute), PostDataRequest(post_request::Execute), diff --git a/common/src/msgs/data_requests/types.rs b/common/src/msgs/data_requests/types.rs index eef6c72f..b4227eaa 100644 --- a/common/src/msgs/data_requests/types.rs +++ b/common/src/msgs/data_requests/types.rs @@ -165,7 +165,8 @@ impl HashSelf for DataResult { } /// A revealed data request result that is hashed and signed by the executor -#[cw_serde] +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] pub struct RevealBody { pub salt: [u8; 32], pub exit_code: u8, @@ -184,7 +185,8 @@ impl HashSelf for RevealBody { } } -#[cw_serde] +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] pub struct PostDataRequestArgs { pub version: Version, pub dr_binary_id: Hash, diff --git a/common/src/msgs/staking/types.rs b/common/src/msgs/staking/types.rs index 25e7d6a2..efe9fb48 100644 --- a/common/src/msgs/staking/types.rs +++ b/common/src/msgs/staking/types.rs @@ -2,7 +2,7 @@ use super::*; /// A data request executor with staking info and optional p2p multi address #[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), derive(Debug, Serialize, Deserialize))] #[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] pub struct Staker { pub memo: Option, @@ -12,7 +12,7 @@ pub struct Staker { /// Governance-controlled configuration parameters #[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), derive(Debug, Serialize, Deserialize))] #[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] pub struct StakingConfig { /// Minimum amount of SEDA tokens required to register as a data request executor @@ -30,7 +30,7 @@ impl From for crate::msgs::ExecuteMsg { } #[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] +#[cfg_attr(not(feature = "cosmwasm"), derive(Debug, Serialize, Deserialize))] #[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] pub struct StakerAndSeq { pub staker: Option, From 25369fc7c853f1ebe2f8a81fdcea78c4d12d35a8 Mon Sep 17 00:00:00 2001 From: Mario Cao Date: Mon, 10 Jun 2024 11:49:09 +0200 Subject: [PATCH 12/14] fix(common): add U128 bytes for not cosmwasm --- common/src/msgs/data_requests/types.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/common/src/msgs/data_requests/types.rs b/common/src/msgs/data_requests/types.rs index b4227eaa..11712798 100644 --- a/common/src/msgs/data_requests/types.rs +++ b/common/src/msgs/data_requests/types.rs @@ -179,7 +179,15 @@ impl HashSelf for RevealBody { let mut hasher = Keccak256::new(); hasher.update(self.salt); hasher.update(self.exit_code.to_be_bytes()); + #[cfg(feature = "cosmwasm")] hasher.update(self.gas_used.to_be_bytes()); + #[cfg(not(feature = "cosmwasm"))] + hasher.update( + self.gas_used + .parse::() + .expect("`gas_used` should be parseable to u128") + .to_be_bytes(), + ); hasher.update(self.reveal.hash()); hasher.finalize().into() } @@ -222,8 +230,24 @@ impl HashSelf for PostDataRequestArgs { dr_hasher.update(self.tally_binary_id); dr_hasher.update(tally_inputs_hash); dr_hasher.update(self.replication_factor.to_be_bytes()); + #[cfg(feature = "cosmwasm")] dr_hasher.update(self.gas_price.to_be_bytes()); + #[cfg(not(feature = "cosmwasm"))] + dr_hasher.update( + self.gas_price + .parse::() + .expect("`gas_price` should be parseable to u128") + .to_be_bytes(), + ); + #[cfg(feature = "cosmwasm")] dr_hasher.update(self.gas_limit.to_be_bytes()); + #[cfg(not(feature = "cosmwasm"))] + dr_hasher.update( + self.gas_price + .parse::() + .expect("`gas_limit` should be parseable to u128") + .to_be_bytes(), + ); dr_hasher.update(memo_hash); dr_hasher.finalize().into() } From 26dd25d35f21adcc98bbaf088c9b8c87f617c552 Mon Sep 17 00:00:00 2001 From: Mario Cao Date: Tue, 11 Jun 2024 12:45:20 +0200 Subject: [PATCH 13/14] refactor: use seda-common dependency --- Cargo.toml | 7 +- common/Cargo.toml | 20 -- common/src/crypto.rs | 25 -- common/src/error.rs | 24 -- common/src/lib.rs | 4 - .../data_requests/execute/commit_result.rs | 17 -- common/src/msgs/data_requests/execute/mod.rs | 19 -- .../data_requests/execute/post_request.rs | 16 -- .../data_requests/execute/reveal_result.rs | 17 -- common/src/msgs/data_requests/mod.rs | 9 - common/src/msgs/data_requests/query.rs | 28 -- common/src/msgs/data_requests/types.rs | 254 ------------------ common/src/msgs/mod.rs | 40 --- .../msgs/owner/execute/accept_ownership.rs | 12 - .../msgs/owner/execute/add_to_allowlist.rs | 15 -- common/src/msgs/owner/execute/mod.rs | 24 -- .../owner/execute/remove_from_allowlist.rs | 15 -- .../msgs/owner/execute/transfer_ownership.rs | 14 - common/src/msgs/owner/mod.rs | 4 - common/src/msgs/owner/query.rs | 18 -- common/src/msgs/staking/execute/mod.rs | 21 -- common/src/msgs/staking/execute/stake.rs | 16 -- common/src/msgs/staking/execute/unstake.rs | 16 -- common/src/msgs/staking/execute/withdraw.rs | 16 -- common/src/msgs/staking/mod.rs | 7 - common/src/msgs/staking/query.rs | 18 -- common/src/msgs/staking/types.rs | 38 --- common/src/types.rs | 71 ----- contract/Cargo.toml | 7 +- contract/src/bin/schema.rs | 2 +- contract/src/contract.rs | 2 +- contract/src/error.rs | 2 +- contract/src/lib.rs | 2 +- contract/src/msgs/mod.rs | 2 +- contract/src/msgs/owner/tests.rs | 2 +- contract/src/msgs/staking/query.rs | 4 +- contract/src/msgs/staking/state.rs | 2 +- contract/src/msgs/staking/tests.rs | 2 +- contract/src/msgs/staking/utils.rs | 2 +- contract/src/test_utils.rs | 2 +- xtask/Cargo.toml | 3 +- xtask/src/main.rs | 2 +- 42 files changed, 19 insertions(+), 802 deletions(-) delete mode 100644 common/Cargo.toml delete mode 100644 common/src/crypto.rs delete mode 100644 common/src/error.rs delete mode 100644 common/src/lib.rs delete mode 100644 common/src/msgs/data_requests/execute/commit_result.rs delete mode 100644 common/src/msgs/data_requests/execute/mod.rs delete mode 100644 common/src/msgs/data_requests/execute/post_request.rs delete mode 100644 common/src/msgs/data_requests/execute/reveal_result.rs delete mode 100644 common/src/msgs/data_requests/mod.rs delete mode 100644 common/src/msgs/data_requests/query.rs delete mode 100644 common/src/msgs/data_requests/types.rs delete mode 100644 common/src/msgs/mod.rs delete mode 100644 common/src/msgs/owner/execute/accept_ownership.rs delete mode 100644 common/src/msgs/owner/execute/add_to_allowlist.rs delete mode 100644 common/src/msgs/owner/execute/mod.rs delete mode 100644 common/src/msgs/owner/execute/remove_from_allowlist.rs delete mode 100644 common/src/msgs/owner/execute/transfer_ownership.rs delete mode 100644 common/src/msgs/owner/mod.rs delete mode 100644 common/src/msgs/owner/query.rs delete mode 100644 common/src/msgs/staking/execute/mod.rs delete mode 100644 common/src/msgs/staking/execute/stake.rs delete mode 100644 common/src/msgs/staking/execute/unstake.rs delete mode 100644 common/src/msgs/staking/execute/withdraw.rs delete mode 100644 common/src/msgs/staking/mod.rs delete mode 100644 common/src/msgs/staking/query.rs delete mode 100644 common/src/msgs/staking/types.rs delete mode 100644 common/src/types.rs diff --git a/Cargo.toml b/Cargo.toml index 872b78c3..cabc0278 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,6 @@ [workspace] resolver = "2" members = [ - "common", "contract", # "fuzz", "xtask", @@ -25,21 +24,21 @@ cosmwasm-schema = "1.5.5" cosmwasm-std = { version = "1.5.5" } cw-multi-test = "1.1.0" cw-storage-plus = "1.2.0" -cw2 = "1.1.2" cw-utils = "1.0.3" +cw2 = "1.1.2" hex = "0.4.3" k256 = { version = "0.13", default-features = false, features = ["ecdsa"] } libfuzzer-sys = "0.4" rand = "0.8" schemars = { version = "0.8", features = ["semver"] } +seda-common = { git = "https://github.com/sedaprotocol/seda-common-rs.git", version = "0.0.0" } +semver = { version = "1.0", features = ["serde"] } serde = { version = "1.0", default-features = false, features = ["derive"] } serde-big-array = { version = "0.5.1" } serde_json = "1.0.117" sha3 = "0.10" thiserror = { version = "1.0" } -semver = { version = "1.0", features = ["serde"] } vrf-rs = "0.0.0" xshell = "0.2" -seda-contract-common = { path = "./common"} seda-contract = { path = "./contract" } diff --git a/common/Cargo.toml b/common/Cargo.toml deleted file mode 100644 index 57ba2679..00000000 --- a/common/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "seda-contract-common" -version = "0.1.0" -edition = "2021" - -[features] -default = ["serde"] -cosmwasm = ["cosmwasm-schema", "cosmwasm-std"] -test-utils = [] - -[dependencies] -cosmwasm-schema = { workspace = true, optional = true } -cosmwasm-std = { workspace = true, optional = true } -cw-storage-plus.workspace = true -hex.workspace = true -sha3.workspace = true -semver.workspace = true -serde = { workspace = true, optional = true } -thiserror.workspace = true -vrf-rs.workspace = true diff --git a/common/src/crypto.rs b/common/src/crypto.rs deleted file mode 100644 index 9269aa78..00000000 --- a/common/src/crypto.rs +++ /dev/null @@ -1,25 +0,0 @@ -use sha3::{Digest, Keccak256}; -use vrf_rs::Secp256k1Sha256; - -use crate::{error::Result, types::Hash}; - -pub fn verify_proof(public_key: &[u8], proof: &[u8], hash: Hash) -> Result<()> { - let verifier = Secp256k1Sha256::default(); - let verifed = verifier.verify(public_key, proof, &hash); - - // If we don't get an error it's always ok - verifed?; - - Ok(()) -} - -pub fn hash<'a, I>(iter: I) -> [u8; 32] -where - I: IntoIterator, -{ - let mut hasher = Keccak256::new(); - for item in iter { - hasher.update(item); - } - hasher.finalize().into() -} diff --git a/common/src/error.rs b/common/src/error.rs deleted file mode 100644 index 82f7bb84..00000000 --- a/common/src/error.rs +++ /dev/null @@ -1,24 +0,0 @@ -use thiserror::Error; -use vrf_rs::error::VrfError; - -// We need it to be cloneable for tests :c -#[derive(Error, Debug, PartialEq)] -#[cfg_attr(feature = "test-utils", derive(Clone))] -pub enum Error { - #[cfg(not(feature = "test-utils"))] - #[error(transparent)] - Prove(#[from] VrfError), - - #[cfg(feature = "test-utils")] - #[error("{0}")] - Prove(String), -} - -#[cfg(feature = "test-utils")] -impl From for Error { - fn from(err: VrfError) -> Self { - Error::Prove(err.to_string()) - } -} - -pub type Result = core::result::Result; diff --git a/common/src/lib.rs b/common/src/lib.rs deleted file mode 100644 index e394f297..00000000 --- a/common/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod crypto; -pub mod error; -pub mod msgs; -pub mod types; diff --git a/common/src/msgs/data_requests/execute/commit_result.rs b/common/src/msgs/data_requests/execute/commit_result.rs deleted file mode 100644 index 31ca6262..00000000 --- a/common/src/msgs/data_requests/execute/commit_result.rs +++ /dev/null @@ -1,17 +0,0 @@ -use super::*; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct Execute { - pub dr_id: Hash, - pub commitment: Hash, - pub public_key: PublicKey, - pub proof: Vec, -} - -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::CommitDataResult(value).into() - } -} diff --git a/common/src/msgs/data_requests/execute/mod.rs b/common/src/msgs/data_requests/execute/mod.rs deleted file mode 100644 index fbd62d2e..00000000 --- a/common/src/msgs/data_requests/execute/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -use super::*; - -pub mod commit_result; -pub mod post_request; -pub mod reveal_result; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -pub enum ExecuteMsg { - CommitDataResult(commit_result::Execute), - PostDataRequest(post_request::Execute), - RevealDataResult(reveal_result::Execute), -} - -impl From for super::ExecuteMsg { - fn from(value: ExecuteMsg) -> Self { - Self::DataRequest(Box::new(value)) - } -} diff --git a/common/src/msgs/data_requests/execute/post_request.rs b/common/src/msgs/data_requests/execute/post_request.rs deleted file mode 100644 index 211724af..00000000 --- a/common/src/msgs/data_requests/execute/post_request.rs +++ /dev/null @@ -1,16 +0,0 @@ -use super::*; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct Execute { - pub posted_dr: PostDataRequestArgs, - pub seda_payload: Bytes, - pub payback_address: Bytes, -} - -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::PostDataRequest(value).into() - } -} diff --git a/common/src/msgs/data_requests/execute/reveal_result.rs b/common/src/msgs/data_requests/execute/reveal_result.rs deleted file mode 100644 index 498e018b..00000000 --- a/common/src/msgs/data_requests/execute/reveal_result.rs +++ /dev/null @@ -1,17 +0,0 @@ -use super::*; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct Execute { - pub dr_id: Hash, - pub reveal_body: RevealBody, - pub public_key: PublicKey, - pub proof: Vec, -} - -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::RevealDataResult(value).into() - } -} diff --git a/common/src/msgs/data_requests/mod.rs b/common/src/msgs/data_requests/mod.rs deleted file mode 100644 index dda352b7..00000000 --- a/common/src/msgs/data_requests/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -use std::collections::HashMap; - -use super::*; - -pub mod execute; -pub mod query; - -mod types; -pub use types::*; diff --git a/common/src/msgs/data_requests/query.rs b/common/src/msgs/data_requests/query.rs deleted file mode 100644 index ed71437e..00000000 --- a/common/src/msgs/data_requests/query.rs +++ /dev/null @@ -1,28 +0,0 @@ -use super::*; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(feature = "cosmwasm", derive(QueryResponses))] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub enum QueryMsg { - #[cfg_attr(feature = "cosmwasm", returns(DataRequest))] - GetDataRequest { dr_id: Hash }, - #[cfg_attr(feature = "cosmwasm", returns(Option))] - GetDataRequestCommitment { dr_id: Hash, public_key: PublicKey }, - #[cfg_attr(feature = "cosmwasm", returns(HashMap))] - GetDataRequestCommitments { dr_id: Hash }, - #[cfg_attr(feature = "cosmwasm", returns(Option))] - GetDataRequestReveal { dr_id: Hash, public_key: PublicKey }, - #[cfg_attr(feature = "cosmwasm", returns(HashMap))] - GetDataRequestReveals { dr_id: Hash }, - #[cfg_attr(feature = "cosmwasm", returns(DataResult))] - GetResolvedDataRequest { dr_id: Hash }, - #[cfg_attr(feature = "cosmwasm", returns(HashMap))] - GetDataRequestsByStatus { status: DataRequestStatus }, -} - -impl From for super::QueryMsg { - fn from(value: QueryMsg) -> Self { - Self::DataRequest(value) - } -} diff --git a/common/src/msgs/data_requests/types.rs b/common/src/msgs/data_requests/types.rs deleted file mode 100644 index 11712798..00000000 --- a/common/src/msgs/data_requests/types.rs +++ /dev/null @@ -1,254 +0,0 @@ -use semver::Version; -use sha3::{Digest, Keccak256}; - -use super::*; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub enum DataRequestStatus { - Committing, - Revealing, - Tallying, - Resolved, -} - -impl DataRequestStatus { - pub fn is_resolved(&self) -> bool { - matches!(self, DataRequestStatus::Resolved) - } -} - -#[cfg(feature = "cosmwasm")] -impl<'a> cw_storage_plus::PrimaryKey<'a> for &'a DataRequestStatus { - type Prefix = (); - type SubPrefix = (); - type Suffix = &'static str; - type SuperSuffix = &'static str; - - fn key(&self) -> Vec { - vec![cw_storage_plus::Key::Ref( - match self { - DataRequestStatus::Committing => "committing", - DataRequestStatus::Revealing => "revealing", - DataRequestStatus::Tallying => "tallying", - DataRequestStatus::Resolved => "resolved", - } - .as_bytes(), - )] - } -} - -/// Represents a data request at creation time -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct DataRequest { - /// Identifier - pub id: Hash, - - // DR definition - /// Semantic Version String - pub version: Version, - /// Identifier of DR WASM binary - pub dr_binary_id: Hash, - /// Inputs for DR WASM binary - pub dr_inputs: Bytes, - /// Identifier of Tally WASM binary - pub tally_binary_id: Hash, - /// Inputs for Tally WASM binary - pub tally_inputs: Bytes, - /// Amount of required DR executors - pub replication_factor: u16, - /// Amount of SEDA tokens per gas unit - pub gas_price: U128, - /// Maximum of gas units to be used by data request executors to resolve a data request - pub gas_limit: U128, - /// Public info attached to DR - pub memo: Memo, - - // Execution Information - /// Payback address set by the relayer - pub payback_address: Bytes, - /// Payload set by SEDA Protocol (e.g. OEV-enabled data requests) - pub seda_payload: Bytes, - /// Commitments submitted by executors - pub commits: HashMap, - /// Reveals submitted by executors - pub reveals: HashMap, -} - -impl DataRequest { - pub fn has_committer(&self, public_key: &str) -> bool { - self.commits.contains_key(public_key) - } - - pub fn get_commitment(&self, public_key: &str) -> Option<&Hash> { - self.commits.get(public_key) - } - - pub fn has_revealer(&self, public_key: &str) -> bool { - self.reveals.contains_key(public_key) - } - - pub fn reveal_started(&self) -> bool { - self.commits.len() >= self.replication_factor as usize - } - - pub fn reveal_over(&self) -> bool { - self.reveals.len() >= self.replication_factor as usize - } - - pub fn get_reveal(&self, public_key: &str) -> Option<&RevealBody> { - self.reveals.get(public_key) - } -} - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub enum DR { - Request(Box), - Result(DataResult), -} - -impl From for DR { - fn from(dr: DataRequest) -> Self { - DR::Request(Box::new(dr)) - } -} - -impl From for DR { - fn from(dr: DataResult) -> Self { - DR::Result(dr) - } -} - -/// Represents a resolved data result -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct DataResult { - // DR Result - /// Semantic Version String - pub version: Version, - - /// Data Request Identifier - pub dr_id: Hash, - /// Block Height at which data request was finalized - pub block_height: u64, - /// Exit code of Tally WASM binary execution - pub exit_code: u8, - pub gas_used: U128, - /// Result from Tally WASM binary execution - pub result: Vec, - - // Fields from Data Request Execution - /// Payback address set by the relayer - pub payback_address: Vec, - /// Payload set by SEDA Protocol (e.g. OEV-enabled data requests) - pub seda_payload: Vec, -} - -impl HashSelf for DataResult { - fn hash(&self) -> Hash { - let mut hasher = Keccak256::new(); - hasher.update(self.version.hash()); - hasher.update(self.dr_id); - hasher.update(self.block_height.to_be_bytes()); - hasher.update(self.exit_code.to_be_bytes()); - hasher.update(self.result.hash()); - hasher.update(&self.payback_address); - hasher.update(self.seda_payload.hash()); - hasher.finalize().into() - } -} - -/// A revealed data request result that is hashed and signed by the executor -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -pub struct RevealBody { - pub salt: [u8; 32], - pub exit_code: u8, - pub gas_used: U128, - pub reveal: Vec, -} - -impl HashSelf for RevealBody { - fn hash(&self) -> Hash { - let mut hasher = Keccak256::new(); - hasher.update(self.salt); - hasher.update(self.exit_code.to_be_bytes()); - #[cfg(feature = "cosmwasm")] - hasher.update(self.gas_used.to_be_bytes()); - #[cfg(not(feature = "cosmwasm"))] - hasher.update( - self.gas_used - .parse::() - .expect("`gas_used` should be parseable to u128") - .to_be_bytes(), - ); - hasher.update(self.reveal.hash()); - hasher.finalize().into() - } -} - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -pub struct PostDataRequestArgs { - pub version: Version, - pub dr_binary_id: Hash, - pub dr_inputs: Bytes, - pub tally_binary_id: Hash, - pub tally_inputs: Bytes, - pub replication_factor: u16, - pub gas_price: U128, - pub gas_limit: U128, - pub memo: Memo, -} - -impl HashSelf for PostDataRequestArgs { - fn hash(&self) -> Hash { - // hash non-fixed-length inputs - let mut dr_inputs_hasher = Keccak256::new(); - dr_inputs_hasher.update(&self.dr_inputs); - let dr_inputs_hash = dr_inputs_hasher.finalize(); - - let mut tally_inputs_hasher = Keccak256::new(); - tally_inputs_hasher.update(&self.tally_inputs); - let tally_inputs_hash = tally_inputs_hasher.finalize(); - - let mut memo_hasher = Keccak256::new(); - memo_hasher.update(&self.memo); - let memo_hash = memo_hasher.finalize(); - - // hash data request - let mut dr_hasher = Keccak256::new(); - dr_hasher.update(self.version.hash()); - dr_hasher.update(self.dr_binary_id); - dr_hasher.update(dr_inputs_hash); - dr_hasher.update(self.tally_binary_id); - dr_hasher.update(tally_inputs_hash); - dr_hasher.update(self.replication_factor.to_be_bytes()); - #[cfg(feature = "cosmwasm")] - dr_hasher.update(self.gas_price.to_be_bytes()); - #[cfg(not(feature = "cosmwasm"))] - dr_hasher.update( - self.gas_price - .parse::() - .expect("`gas_price` should be parseable to u128") - .to_be_bytes(), - ); - #[cfg(feature = "cosmwasm")] - dr_hasher.update(self.gas_limit.to_be_bytes()); - #[cfg(not(feature = "cosmwasm"))] - dr_hasher.update( - self.gas_price - .parse::() - .expect("`gas_limit` should be parseable to u128") - .to_be_bytes(), - ); - dr_hasher.update(memo_hash); - dr_hasher.finalize().into() - } -} diff --git a/common/src/msgs/mod.rs b/common/src/msgs/mod.rs deleted file mode 100644 index 1377ddc5..00000000 --- a/common/src/msgs/mod.rs +++ /dev/null @@ -1,40 +0,0 @@ -#[cfg(feature = "cosmwasm")] -use cosmwasm_schema::{cw_serde, QueryResponses}; -#[cfg(not(feature = "cosmwasm"))] -use serde::{Deserialize, Serialize}; - -use crate::types::*; - -pub mod data_requests; -pub mod owner; -pub mod staking; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -#[serde(untagged)] -pub enum ExecuteMsg { - DataRequest(Box), - Staking(staking::execute::ExecuteMsg), - Owner(owner::execute::ExecuteMsg), -} - -// https://github.com/CosmWasm/cosmwasm/issues/2030 -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(feature = "cosmwasm", derive(QueryResponses))] -#[cfg_attr(feature = "cosmwasm", query_responses(nested))] -#[cfg_attr(not(feature = "cosmwasm"), derive(serde::Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -#[serde(untagged)] -pub enum QueryMsg { - DataRequest(data_requests::query::QueryMsg), - Staking(staking::query::QueryMsg), - Owner(owner::query::QueryMsg), -} - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -pub struct InstantiateMsg { - pub token: String, - pub owner: String, - pub chain_id: String, -} diff --git a/common/src/msgs/owner/execute/accept_ownership.rs b/common/src/msgs/owner/execute/accept_ownership.rs deleted file mode 100644 index 2c65d342..00000000 --- a/common/src/msgs/owner/execute/accept_ownership.rs +++ /dev/null @@ -1,12 +0,0 @@ -use super::*; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct Execute {} - -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::AcceptOwnership(value).into() - } -} diff --git a/common/src/msgs/owner/execute/add_to_allowlist.rs b/common/src/msgs/owner/execute/add_to_allowlist.rs deleted file mode 100644 index 07c0b95c..00000000 --- a/common/src/msgs/owner/execute/add_to_allowlist.rs +++ /dev/null @@ -1,15 +0,0 @@ -use super::*; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct Execute { - /// The public key of the person. - pub public_key: PublicKey, -} - -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::AddToAllowlist(value).into() - } -} diff --git a/common/src/msgs/owner/execute/mod.rs b/common/src/msgs/owner/execute/mod.rs deleted file mode 100644 index 5b27c791..00000000 --- a/common/src/msgs/owner/execute/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -use super::*; - -pub mod accept_ownership; -pub mod add_to_allowlist; -pub mod remove_from_allowlist; -pub mod transfer_ownership; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub enum ExecuteMsg { - TransferOwnership(transfer_ownership::Execute), - AcceptOwnership(accept_ownership::Execute), - /// Add a user to the allowlist. - AddToAllowlist(add_to_allowlist::Execute), - /// Remove a user from the allowlist. - RemoveFromAllowlist(remove_from_allowlist::Execute), -} - -impl From for super::ExecuteMsg { - fn from(value: ExecuteMsg) -> Self { - Self::Owner(value) - } -} diff --git a/common/src/msgs/owner/execute/remove_from_allowlist.rs b/common/src/msgs/owner/execute/remove_from_allowlist.rs deleted file mode 100644 index ff7fed06..00000000 --- a/common/src/msgs/owner/execute/remove_from_allowlist.rs +++ /dev/null @@ -1,15 +0,0 @@ -use super::*; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct Execute { - /// The public key of the person. - pub public_key: PublicKey, -} - -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::RemoveFromAllowlist(value).into() - } -} diff --git a/common/src/msgs/owner/execute/transfer_ownership.rs b/common/src/msgs/owner/execute/transfer_ownership.rs deleted file mode 100644 index a15d33ac..00000000 --- a/common/src/msgs/owner/execute/transfer_ownership.rs +++ /dev/null @@ -1,14 +0,0 @@ -use super::*; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct Execute { - pub new_owner: String, -} - -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::TransferOwnership(value).into() - } -} diff --git a/common/src/msgs/owner/mod.rs b/common/src/msgs/owner/mod.rs deleted file mode 100644 index cddbfbd2..00000000 --- a/common/src/msgs/owner/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod execute; -pub mod query; - -use super::*; diff --git a/common/src/msgs/owner/query.rs b/common/src/msgs/owner/query.rs deleted file mode 100644 index 6106e6de..00000000 --- a/common/src/msgs/owner/query.rs +++ /dev/null @@ -1,18 +0,0 @@ -use super::*; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(feature = "cosmwasm", derive(QueryResponses))] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub enum QueryMsg { - #[cfg_attr(feature = "cosmwasm", returns(cosmwasm_std::Addr))] - GetOwner {}, - #[cfg_attr(feature = "cosmwasm", returns(Option))] - GetPendingOwner {}, -} - -impl From for super::QueryMsg { - fn from(value: QueryMsg) -> Self { - Self::Owner(value) - } -} diff --git a/common/src/msgs/staking/execute/mod.rs b/common/src/msgs/staking/execute/mod.rs deleted file mode 100644 index 3ea0edd8..00000000 --- a/common/src/msgs/staking/execute/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -use super::*; - -pub mod stake; -pub mod unstake; -pub mod withdraw; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub enum ExecuteMsg { - Stake(stake::Execute), - Unstake(unstake::Execute), - Withdraw(withdraw::Execute), - SetStakingConfig(StakingConfig), -} - -impl From for super::ExecuteMsg { - fn from(value: ExecuteMsg) -> Self { - Self::Staking(value) - } -} diff --git a/common/src/msgs/staking/execute/stake.rs b/common/src/msgs/staking/execute/stake.rs deleted file mode 100644 index c283123d..00000000 --- a/common/src/msgs/staking/execute/stake.rs +++ /dev/null @@ -1,16 +0,0 @@ -use super::*; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct Execute { - pub public_key: PublicKey, - pub proof: Vec, - pub memo: Option, -} - -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::Stake(value).into() - } -} diff --git a/common/src/msgs/staking/execute/unstake.rs b/common/src/msgs/staking/execute/unstake.rs deleted file mode 100644 index ac9a7b93..00000000 --- a/common/src/msgs/staking/execute/unstake.rs +++ /dev/null @@ -1,16 +0,0 @@ -use super::*; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct Execute { - pub public_key: PublicKey, - pub proof: Vec, - pub amount: U128, -} - -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::Unstake(value).into() - } -} diff --git a/common/src/msgs/staking/execute/withdraw.rs b/common/src/msgs/staking/execute/withdraw.rs deleted file mode 100644 index aae1dfae..00000000 --- a/common/src/msgs/staking/execute/withdraw.rs +++ /dev/null @@ -1,16 +0,0 @@ -use super::*; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct Execute { - pub public_key: PublicKey, - pub proof: Vec, - pub amount: U128, -} - -impl From for crate::msgs::ExecuteMsg { - fn from(value: Execute) -> Self { - super::ExecuteMsg::Withdraw(value).into() - } -} diff --git a/common/src/msgs/staking/mod.rs b/common/src/msgs/staking/mod.rs deleted file mode 100644 index 58872e42..00000000 --- a/common/src/msgs/staking/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod execute; -pub mod query; - -mod types; -pub use types::*; - -use super::*; diff --git a/common/src/msgs/staking/query.rs b/common/src/msgs/staking/query.rs deleted file mode 100644 index 43d3a0fe..00000000 --- a/common/src/msgs/staking/query.rs +++ /dev/null @@ -1,18 +0,0 @@ -use super::*; - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(feature = "cosmwasm", derive(QueryResponses))] -#[cfg_attr(not(feature = "cosmwasm"), derive(Serialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub enum QueryMsg { - #[cfg_attr(feature = "cosmwasm", returns(Option))] - GetStaker { public_key: PublicKey }, - #[cfg_attr(feature = "cosmwasm", returns(U128))] - GetAccountSeq { public_key: PublicKey }, - #[cfg_attr(feature = "cosmwasm", returns(StakerAndSeq))] - GetStakerAndSeq { public_key: PublicKey }, - #[cfg_attr(feature = "cosmwasm", returns(bool))] - IsExecutorEligible { public_key: PublicKey }, - #[cfg_attr(feature = "cosmwasm", returns(StakingConfig))] - GetStakingConfig {}, -} diff --git a/common/src/msgs/staking/types.rs b/common/src/msgs/staking/types.rs deleted file mode 100644 index efe9fb48..00000000 --- a/common/src/msgs/staking/types.rs +++ /dev/null @@ -1,38 +0,0 @@ -use super::*; - -/// A data request executor with staking info and optional p2p multi address -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Debug, Serialize, Deserialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct Staker { - pub memo: Option, - pub tokens_staked: U128, - pub tokens_pending_withdrawal: U128, -} - -/// Governance-controlled configuration parameters -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Debug, Serialize, Deserialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct StakingConfig { - /// Minimum amount of SEDA tokens required to register as a data request executor - pub minimum_stake_to_register: U128, - /// Minimum amount of SEDA tokens required to be eligible for committee inclusion - pub minimum_stake_for_committee_eligibility: U128, - /// Whether the allowlist is enabled - pub allowlist_enabled: bool, -} - -impl From for crate::msgs::ExecuteMsg { - fn from(config: StakingConfig) -> Self { - super::execute::ExecuteMsg::SetStakingConfig(config).into() - } -} - -#[cfg_attr(feature = "cosmwasm", cw_serde)] -#[cfg_attr(not(feature = "cosmwasm"), derive(Debug, Serialize, Deserialize))] -#[cfg_attr(not(feature = "cosmwasm"), serde(rename_all = "snake_case"))] -pub struct StakerAndSeq { - pub staker: Option, - pub seq: U128, -} diff --git a/common/src/types.rs b/common/src/types.rs deleted file mode 100644 index 29ef90c1..00000000 --- a/common/src/types.rs +++ /dev/null @@ -1,71 +0,0 @@ -#[cfg(feature = "cosmwasm")] -pub(crate) type U128 = cosmwasm_std::Uint128; -#[cfg(not(feature = "cosmwasm"))] -pub(crate) type U128 = String; - -use semver::Version; -use sha3::{Digest, Keccak256}; - -pub type Bytes = Vec; -// pub type Commitment = Hash; -pub type Memo = Vec; -pub type Hash = [u8; 32]; -pub type PublicKey = Vec; - -pub trait ToHexStr: AsRef<[u8]> { - fn to_hex(&self) -> String { - hex::encode(self) - } -} - -impl ToHexStr for Hash { - fn to_hex(&self) -> String { - hex::encode(self) - } -} - -pub trait HashSelf { - fn hash(&self) -> Hash; -} - -impl HashSelf for &str { - fn hash(&self) -> Hash { - let mut hasher = Keccak256::new(); - hasher.update(self.as_bytes()); - hasher.finalize().into() - } -} - -impl HashSelf for String { - fn hash(&self) -> Hash { - let refer: &str = self.as_ref(); - refer.hash() - } -} - -impl HashSelf for Version { - fn hash(&self) -> Hash { - self.to_string().hash() - } -} - -impl HashSelf for Vec { - fn hash(&self) -> Hash { - let mut hasher = Keccak256::new(); - hasher.update(self); - hasher.finalize().into() - } -} - -impl HashSelf for Option -where - T: AsRef<[u8]>, -{ - fn hash(&self) -> Hash { - let mut hasher = Keccak256::new(); - if let Some(inner) = self { - hasher.update(inner); - } - hasher.finalize().into() - } -} diff --git a/contract/Cargo.toml b/contract/Cargo.toml index 9231e84a..e4345d61 100644 --- a/contract/Cargo.toml +++ b/contract/Cargo.toml @@ -35,7 +35,7 @@ cw-utils = { workspace = true } cw2 = { workspace = true } hex = { workspace = true } schemars = { workspace = true } -seda-contract-common = { workspace = true, features = ["cosmwasm"] } +seda-common = { workspace = true, features = ["cosmwasm"] } semver = { workspace = true } serde = { workspace = true } serde-big-array = { workspace = true } @@ -46,8 +46,5 @@ vrf-rs = { workspace = true } [dev-dependencies] cw-multi-test = { workspace = true } k256 = { workspace = true } -seda-contract-common = { workspace = true, features = [ - "cosmwasm", - "test-utils", -] } +seda-common = { workspace = true, features = ["cosmwasm", "test-utils"] } serde_json = { workspace = true } diff --git a/contract/src/bin/schema.rs b/contract/src/bin/schema.rs index f85b3939..55ab4424 100644 --- a/contract/src/bin/schema.rs +++ b/contract/src/bin/schema.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::write_api; -use seda_contract_common::msgs::*; +use seda_common::msgs::*; fn main() { write_api! { diff --git a/contract/src/contract.rs b/contract/src/contract.rs index db68e43a..adfea7fb 100644 --- a/contract/src/contract.rs +++ b/contract/src/contract.rs @@ -2,7 +2,7 @@ use cosmwasm_std::{entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Response}; use cosmwasm_std::{StdResult, Uint128}; use cw2::set_contract_version; -use seda_contract_common::msgs::*; +use seda_common::msgs::*; use staking::StakingConfig; use crate::{ diff --git a/contract/src/error.rs b/contract/src/error.rs index 2003a52f..09922561 100644 --- a/contract/src/error.rs +++ b/contract/src/error.rs @@ -67,7 +67,7 @@ pub enum ContractError { FromHex(#[from] FromHexError), #[error(transparent)] - Common(#[from] seda_contract_common::error::Error), + Common(#[from] seda_common::error::Error), } #[cfg(test)] diff --git a/contract/src/lib.rs b/contract/src/lib.rs index f553f8cb..3c9e2f30 100644 --- a/contract/src/lib.rs +++ b/contract/src/lib.rs @@ -5,7 +5,7 @@ pub mod msgs; pub mod state; mod utils; -use seda_contract_common::types; +use seda_common::types; #[cfg(test)] mod test_utils; diff --git a/contract/src/msgs/mod.rs b/contract/src/msgs/mod.rs index 80430669..67d76c84 100644 --- a/contract/src/msgs/mod.rs +++ b/contract/src/msgs/mod.rs @@ -1,6 +1,6 @@ use cosmwasm_std::*; use cw_storage_plus::{Item, Map}; -use seda_contract_common::{ +use seda_common::{ crypto::*, msgs::{ self, diff --git a/contract/src/msgs/owner/tests.rs b/contract/src/msgs/owner/tests.rs index 32aefc0f..5e597f83 100644 --- a/contract/src/msgs/owner/tests.rs +++ b/contract/src/msgs/owner/tests.rs @@ -1,4 +1,4 @@ -use seda_contract_common::msgs::staking::StakingConfig; +use seda_common::msgs::staking::StakingConfig; use crate::{error::ContractError, TestInfo}; diff --git a/contract/src/msgs/staking/query.rs b/contract/src/msgs/staking/query.rs index fe92e512..99f02703 100644 --- a/contract/src/msgs/staking/query.rs +++ b/contract/src/msgs/staking/query.rs @@ -1,5 +1,5 @@ -pub use seda_contract_common::msgs::staking::query::QueryMsg; -use seda_contract_common::msgs::staking::StakerAndSeq; +pub use seda_common::msgs::staking::query::QueryMsg; +use seda_common::msgs::staking::StakerAndSeq; use super::*; use crate::state::get_seq; diff --git a/contract/src/msgs/staking/state.rs b/contract/src/msgs/staking/state.rs index 46b9c42a..349edea8 100644 --- a/contract/src/msgs/staking/state.rs +++ b/contract/src/msgs/staking/state.rs @@ -1,4 +1,4 @@ -use seda_contract_common::msgs::staking::{Staker, StakingConfig}; +use seda_common::msgs::staking::{Staker, StakingConfig}; use super::*; diff --git a/contract/src/msgs/staking/tests.rs b/contract/src/msgs/staking/tests.rs index 4f465e88..b7874078 100644 --- a/contract/src/msgs/staking/tests.rs +++ b/contract/src/msgs/staking/tests.rs @@ -1,4 +1,4 @@ -use seda_contract_common::msgs::staking::{Staker, StakingConfig}; +use seda_common::msgs::staking::{Staker, StakingConfig}; use super::*; use crate::TestInfo; diff --git a/contract/src/msgs/staking/utils.rs b/contract/src/msgs/staking/utils.rs index a7174d17..21748146 100644 --- a/contract/src/msgs/staking/utils.rs +++ b/contract/src/msgs/staking/utils.rs @@ -1,4 +1,4 @@ -use seda_contract_common::msgs::staking::Staker; +use seda_common::msgs::staking::Staker; use super::{ state::{CONFIG, STAKERS}, diff --git a/contract/src/test_utils.rs b/contract/src/test_utils.rs index 994d7565..586a1ded 100644 --- a/contract/src/test_utils.rs +++ b/contract/src/test_utils.rs @@ -17,7 +17,7 @@ use k256::{ ecdsa::{SigningKey, VerifyingKey}, elliptic_curve::rand_core::OsRng, }; -use seda_contract_common::msgs::*; +use seda_common::msgs::*; use serde::{de::DeserializeOwned, Serialize}; use sha3::{Digest, Keccak256}; use vrf_rs::Secp256k1Sha256; diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 26d2f4e9..30a7f181 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -3,12 +3,11 @@ name = "xtask" version = "0.1.0" edition = "2021" - [dependencies] anyhow.workspace = true hex.workspace = true seda-contract.workspace = true -seda-contract-common.workspace = true +seda-common.workspace = true semver.workspace = true serde_json.workspace = true rand.workspace = true diff --git a/xtask/src/main.rs b/xtask/src/main.rs index fa4d0652..9f57a5e5 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, env, process::Command}; use anyhow::{bail, Context, Result}; use rand::Rng; -use seda_contract_common::msgs::data_requests::{DataRequest, DR}; +use seda_common::msgs::data_requests::{DataRequest, DR}; use serde_json::json; use xshell::{cmd, Shell}; From cae94be53b0a1a208afcf1da26e24a998d552ff8 Mon Sep 17 00:00:00 2001 From: Mario Cao Date: Tue, 11 Jun 2024 12:47:04 +0200 Subject: [PATCH 14/14] fix(data requests): fix wrong state map name --- contract/src/msgs/data_requests/state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contract/src/msgs/data_requests/state.rs b/contract/src/msgs/data_requests/state.rs index c51082e5..f017e6e8 100644 --- a/contract/src/msgs/data_requests/state.rs +++ b/contract/src/msgs/data_requests/state.rs @@ -1,6 +1,6 @@ use super::*; -const DATA_REQUESTS: Map<&Hash, DataRequest> = Map::new("data_results_pool"); +const DATA_REQUESTS: Map<&Hash, DataRequest> = Map::new("data_request_pool"); const DATA_REQUESTS_BY_STATUS: Map<&DataRequestStatus, HashSet> = Map::new("data_requests_by_status"); const DATA_RESULTS: Map<&Hash, DataResult> = Map::new("data_results_pool");