From 4c91a851579c1c0656f6ae5fccffe0eb91be7892 Mon Sep 17 00:00:00 2001 From: Blake Byrnes Date: Thu, 14 Nov 2024 15:03:58 -0500 Subject: [PATCH] Control unsigned ismp with a storage item This PR adds a storage item, genesis setting and runtime api to control the activation of unsigned transactions for the ISMP pallet. The unsigned feature flag is removed, and the development testnet configs have the enableUnsignedTransactions flag turned on by default. --- .gitmodules | 2 +- .../ismp/pallets/call-decompressor/Cargo.toml | 2 +- modules/ismp/pallets/pallet/Cargo.toml | 1 - modules/ismp/pallets/pallet/README.md | 2 +- modules/ismp/pallets/pallet/src/lib.rs | 58 +++++++++++++++---- parachain/node/src/chain_spec.rs | 3 + parachain/runtimes/gargantua/Cargo.toml | 2 +- parachain/runtimes/messier/Cargo.toml | 2 +- parachain/runtimes/nexus/Cargo.toml | 2 +- 9 files changed, 56 insertions(+), 18 deletions(-) diff --git a/.gitmodules b/.gitmodules index 67354b109..21020e077 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "evm/lib/forge-std"] path = evm/lib/forge-std - url = git@github.com:foundry-rs/forge-std + url = https://github.com/foundry-rs/forge-std [submodule "evm/lib/solidity-stringutils"] path = evm/lib/solidity-stringutils url = https://github.com/Arachnid/solidity-stringutils diff --git a/modules/ismp/pallets/call-decompressor/Cargo.toml b/modules/ismp/pallets/call-decompressor/Cargo.toml index 2b0e3a49c..25c7c200b 100644 --- a/modules/ismp/pallets/call-decompressor/Cargo.toml +++ b/modules/ismp/pallets/call-decompressor/Cargo.toml @@ -20,7 +20,7 @@ sp-api = { workspace = true } # polytope labs ismp = { workspace = true } -pallet-ismp = { workspace = true, features = ["unsigned"] } +pallet-ismp = { workspace = true } pallet-ismp-relayer = { workspace = true } # crates.io diff --git a/modules/ismp/pallets/pallet/Cargo.toml b/modules/ismp/pallets/pallet/Cargo.toml index 6bc5f5d9a..71cb0a82e 100644 --- a/modules/ismp/pallets/pallet/Cargo.toml +++ b/modules/ismp/pallets/pallet/Cargo.toml @@ -70,4 +70,3 @@ try-runtime = [ "frame-system/try-runtime", "sp-runtime/try-runtime", ] -unsigned = [] diff --git a/modules/ismp/pallets/pallet/README.md b/modules/ismp/pallets/pallet/README.md index 00374d8a1..ab11c1c67 100644 --- a/modules/ismp/pallets/pallet/README.md +++ b/modules/ismp/pallets/pallet/README.md @@ -32,7 +32,7 @@ To use it in your runtime, you need to implement the ismp ### Dispatchable Functions - `handle` - Handles incoming ISMP messages. -- `handle_unsigned` Unsigned variant for handling incoming messages, enabled by `feature = ["unsigned"]` +- `handle_unsigned` Unsigned variant for handling incoming messages - `create_consensus_client` - Handles creation of various properties for a particular consensus client. Can only be called by the `AdminOrigin`. - `update_consensus_state` - Updates consensus client properties in storage. Can only be called by the `AdminOrigin`. - `fund_message` - In cases where the initially provided relayer fees have now become insufficient, due to a transaction fee spike on the destination chain. Allows a user to add more funds to the request to be used for delivery and execution. Should never be called on a completed request. diff --git a/modules/ismp/pallets/pallet/src/lib.rs b/modules/ismp/pallets/pallet/src/lib.rs index 0de9048b2..c548f97fd 100644 --- a/modules/ismp/pallets/pallet/src/lib.rs +++ b/modules/ismp/pallets/pallet/src/lib.rs @@ -62,8 +62,7 @@ //! ### Dispatchable Functions //! //! * `handle` - Handles incoming ISMP messages. -//! * `handle_unsigned` Unsigned variant for handling incoming messages, enabled by `feature = -//! ["unsigned"]` +//! * `handle_unsigned` Unsigned variant for handling incoming messages //! * `create_consensus_client` - Handles creation of various properties for a particular consensus //! client. Can only be called by the `AdminOrigin`. //! * `update_consensus_state` - Updates consensus client properties in storage. Can only be called @@ -229,8 +228,14 @@ pub mod pallet { messaging::{CreateConsensusState, Message}, router::IsmpRouter, }; + use ismp::{ + handlers::MessageResult, + messaging::{hash_request, ConsensusMessage, FraudProofMessage, RequestMessage}, + router::Request, + }; + use sp_core::{storage::ChildInfo, H256}; - #[cfg(feature = "unsigned")] + use sp_runtime::transaction_validity::{ InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError, ValidTransaction, @@ -383,6 +388,12 @@ pub mod pallet { #[pallet::getter(fn responded)] pub type Responded = StorageMap<_, Identity, H256, bool, ValueQuery>; + /// Should unsigned transactions be enabled. Preferred mode for testnet to simplify relayer + /// token acquisition, but this can be abused in production. Use with caution. + #[pallet::storage] + #[pallet::getter(fn enable_unsigned)] + pub type EnableUnsigned = StorageValue<_, bool, ValueQuery>; + /// Latest nonce for messages sent from this chain #[pallet::storage] #[pallet::getter(fn nonce)] @@ -394,6 +405,24 @@ pub mod pallet { pub type ChildTrieRoot = StorageValue<_, ::Hash, ValueQuery>; + /// Genesis settings + #[pallet::genesis_config] + #[derive(frame_support::DefaultNoBound)] + pub struct GenesisConfig { + /// Should unsigned transactions be enabled. Preferred mode for testnet to simplify relayer + pub enable_unsigned_transactions: bool, + /// Phantom data + #[serde(skip)] + pub _phantom: PhantomData, + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + EnableUnsigned::::put(self.enable_unsigned_transactions); + } + } + // Pallet implements [`Hooks`] trait to define some logic to execute in some context. #[pallet::hooks] impl Hooks> for Pallet @@ -436,7 +465,6 @@ pub mod pallet { /// - `messages`: the messages to handle or process. /// /// Emits different message events based on the Message received if successful. - #[cfg(feature = "unsigned")] #[pallet::weight(get_weight::(&messages))] #[pallet::call_index(0)] #[frame_support::transactional] @@ -457,7 +485,6 @@ pub mod pallet { /// - `messages`: A set of ISMP [`Message`]s to handle or process. /// /// Emits different message events based on the Message received if successful. - #[cfg(not(feature = "unsigned"))] #[pallet::weight(get_weight::(&messages))] #[pallet::call_index(1)] #[frame_support::transactional] @@ -565,6 +592,18 @@ pub mod pallet { Ok(()) } + + /// Change the activation of the Enable Unsigned feature. This feature allows relayers to submit ISMP messages without fees. + #[pallet::weight(::DbWeight::get().writes(1))] + #[pallet::call_index(5)] + pub fn update_enable_unsigned( + origin: OriginFor, + enable_unsigned_transactions: bool, + ) -> DispatchResult { + T::AdminOrigin::ensure_origin(origin)?; + EnableUnsigned::::put(enable_unsigned_transactions); + Ok(()) + } } /// Pallet Events @@ -654,7 +693,6 @@ pub mod pallet { } /// This allows users execute ISMP datagrams for free. Use with caution. - #[cfg(feature = "unsigned")] #[pallet::validate_unsigned] impl ValidateUnsigned for Pallet { type Call = Call; @@ -665,11 +703,9 @@ pub mod pallet { } fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity { - use ismp::{ - handlers::MessageResult, - messaging::{hash_request, ConsensusMessage, FraudProofMessage, RequestMessage}, - router::Request, - }; + if !EnableUnsigned::::get() { + return Err(TransactionValidityError::Invalid(InvalidTransaction::Call)); + } let messages = match call { Call::handle_unsigned { messages } => messages, _ => Err(TransactionValidityError::Invalid(InvalidTransaction::Call))?, diff --git a/parachain/node/src/chain_spec.rs b/parachain/node/src/chain_spec.rs index 0b1102e4e..4496fbb77 100644 --- a/parachain/node/src/chain_spec.rs +++ b/parachain/node/src/chain_spec.rs @@ -205,6 +205,9 @@ fn testnet_genesis( "invulnerables": invulnerables.iter().cloned().map(|(acc, _)| acc).collect::>(), "candidacyBond": EXISTENTIAL_DEPOSIT * 16, }, + "ismp": { + "enableUnsignedTransactions": true + }, "ismpParachain": { "parachains": vec![sibling] }, diff --git a/parachain/runtimes/gargantua/Cargo.toml b/parachain/runtimes/gargantua/Cargo.toml index 61e5b6239..4cc3bc0d9 100644 --- a/parachain/runtimes/gargantua/Cargo.toml +++ b/parachain/runtimes/gargantua/Cargo.toml @@ -83,7 +83,7 @@ parachains-common = { workspace = true } # local modules ismp = { workspace = true } -pallet-ismp = { workspace = true, features = ["unsigned"] } +pallet-ismp = { workspace = true } pallet-fishermen = { workspace = true } pallet-ismp-demo = { workspace = true } pallet-ismp-runtime-api = { workspace = true } diff --git a/parachain/runtimes/messier/Cargo.toml b/parachain/runtimes/messier/Cargo.toml index 121c7ba9f..5cded714e 100644 --- a/parachain/runtimes/messier/Cargo.toml +++ b/parachain/runtimes/messier/Cargo.toml @@ -85,7 +85,7 @@ parachains-common = { workspace = true } # ismp modules ismp = { workspace = true } -pallet-ismp = { workspace = true, features = ["unsigned"] } +pallet-ismp = { workspace = true } pallet-ismp-demo = { workspace = true } pallet-ismp-runtime-api = { workspace = true } ismp-parachain = { workspace = true } diff --git a/parachain/runtimes/nexus/Cargo.toml b/parachain/runtimes/nexus/Cargo.toml index e4b72cbbe..5e3f937c4 100644 --- a/parachain/runtimes/nexus/Cargo.toml +++ b/parachain/runtimes/nexus/Cargo.toml @@ -91,7 +91,7 @@ parachains-common = { workspace = true } # ismp modules ismp = { workspace = true } -pallet-ismp = { workspace = true, features = ["unsigned"] } +pallet-ismp = { workspace = true } pallet-ismp-demo = { workspace = true } pallet-ismp-runtime-api = { workspace = true } ismp-parachain = { workspace = true }