diff --git a/pallets/gear-builtin/src/bls12_381.rs b/pallets/gear-builtin/src/bls12_381.rs index 891e23c51e0..79a2205eabd 100644 --- a/pallets/gear-builtin/src/bls12_381.rs +++ b/pallets/gear-builtin/src/bls12_381.rs @@ -30,8 +30,6 @@ const IS_VALIDATED: Validate = ark_scale::is_validated(HOST_CALL); pub struct Actor(PhantomData); impl BuiltinActor for Actor { - const ID: u64 = 1; - type Error = BuiltinActorError; fn handle(dispatch: &StoredDispatch, gas_limit: u64) -> (Result, u64) { diff --git a/pallets/gear-builtin/src/lib.rs b/pallets/gear-builtin/src/lib.rs index f25afc7dce7..e3ca28e0c3c 100644 --- a/pallets/gear-builtin/src/lib.rs +++ b/pallets/gear-builtin/src/lib.rs @@ -51,6 +51,7 @@ use alloc::{ collections::{btree_map::Entry, BTreeMap}, string::ToString, }; +use core::marker::PhantomData; use core_processor::{ common::{ActorExecutionErrorReplyReason, DispatchResult, JournalNote, TrapExplanation}, process_execution_error, process_success, SuccessfulDispatchResultKind, @@ -109,13 +110,28 @@ impl From for ActorExecutionErrorReplyReason { pub trait BuiltinActor { type Error; - /// The global unique ID of the trait implementer type. - const ID: u64; - /// Handles a message and returns a result and the actual gas spent. fn handle(dispatch: &StoredDispatch, gas_limit: u64) -> (Result, u64); } +/// A marker struct to associate a builtin actor with its unique ID. +pub struct ActorWithId(PhantomData); + +/// Glue trait to implement `BuiltinCollection` for a tuple of `ActorWithId`. +trait BuiltinActorWithId { + const ID: u64; + + type Error; + type Actor: BuiltinActor; +} + +impl BuiltinActorWithId for ActorWithId { + const ID: u64 = ID; + + type Error = A::Error; + type Actor = A; +} + /// A trait defining a method to convert a tuple of `BuiltinActor` types into /// a in-memory collection of builtin actors. pub trait BuiltinCollection { @@ -127,7 +143,7 @@ pub trait BuiltinCollection { // Assuming as many as 16 builtin actors for the meantime #[impl_for_tuples(16)] -#[tuple_types_custom_trait_bound(BuiltinActor + 'static)] +#[tuple_types_custom_trait_bound(BuiltinActorWithId + 'static)] impl BuiltinCollection for Tuple { fn collect( registry: &mut BTreeMap>>, @@ -137,7 +153,7 @@ impl BuiltinCollection for Tuple { #( let actor_id = id_converter(Tuple::ID); if let Entry::Vacant(e) = registry.entry(actor_id) { - e.insert(Box::new(Tuple::handle)); + e.insert(Box::new(Tuple::Actor::handle)); } else { unreachable!("Duplicate builtin ids"); } diff --git a/pallets/gear-builtin/src/mock.rs b/pallets/gear-builtin/src/mock.rs index 9a668d0581a..cc3d91664ab 100644 --- a/pallets/gear-builtin/src/mock.rs +++ b/pallets/gear-builtin/src/mock.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use crate::{self as pallet_gear_builtin, bls12_381, BuiltinActor, BuiltinActorError}; +use crate::{self as pallet_gear_builtin, bls12_381, ActorWithId, BuiltinActor, BuiltinActorError}; use common::{GasProvider, GasTree}; use core::cell::RefCell; use frame_support::{ @@ -131,8 +131,6 @@ pub struct SuccessBuiltinActor {} impl BuiltinActor for SuccessBuiltinActor { type Error = BuiltinActorError; - const ID: u64 = u64::from_le_bytes(*b"bltn/suc"); - fn handle( dispatch: &StoredDispatch, _gas_limit: u64, @@ -140,7 +138,7 @@ impl BuiltinActor for SuccessBuiltinActor { if !in_transaction() { DEBUG_EXECUTION_TRACE.with(|d| { d.borrow_mut().push(ExecutionTraceFrame { - destination: ::ID, + destination: SUCCESS_ACTOR_ID, source: dispatch.source(), input: dispatch.payload_bytes().to_vec(), is_success: true, @@ -160,8 +158,6 @@ pub struct ErrorBuiltinActor {} impl BuiltinActor for ErrorBuiltinActor { type Error = BuiltinActorError; - const ID: u64 = u64::from_le_bytes(*b"bltn/err"); - fn handle( dispatch: &StoredDispatch, _gas_limit: u64, @@ -169,7 +165,7 @@ impl BuiltinActor for ErrorBuiltinActor { if !in_transaction() { DEBUG_EXECUTION_TRACE.with(|d| { d.borrow_mut().push(ExecutionTraceFrame { - destination: ::ID, + destination: ERROR_ACTOR_ID, source: dispatch.source(), input: dispatch.payload_bytes().to_vec(), is_success: false, @@ -185,8 +181,6 @@ pub struct HonestBuiltinActor {} impl BuiltinActor for HonestBuiltinActor { type Error = BuiltinActorError; - const ID: u64 = u64::from_le_bytes(*b"bltn/hon"); - fn handle( dispatch: &StoredDispatch, gas_limit: u64, @@ -196,7 +190,7 @@ impl BuiltinActor for HonestBuiltinActor { if !in_transaction() { DEBUG_EXECUTION_TRACE.with(|d| { d.borrow_mut().push(ExecutionTraceFrame { - destination: ::ID, + destination: HONEST_ACTOR_ID, source: dispatch.source(), input: dispatch.payload_bytes().to_vec(), is_success: !is_error, @@ -215,13 +209,17 @@ impl BuiltinActor for HonestBuiltinActor { } } +const HONEST_ACTOR_ID: u64 = u64::from_le_bytes(*b"bltn/hon"); +const SUCCESS_ACTOR_ID: u64 = u64::from_le_bytes(*b"bltn/suc"); +const ERROR_ACTOR_ID: u64 = u64::from_le_bytes(*b"bltn/err"); + impl pallet_gear_builtin::Config for Test { type RuntimeCall = RuntimeCall; type Builtins = ( - SuccessBuiltinActor, - ErrorBuiltinActor, - HonestBuiltinActor, - bls12_381::Actor, + ActorWithId, + ActorWithId, + ActorWithId, + ActorWithId<1, bls12_381::Actor>, ); type WeightInfo = (); } diff --git a/pallets/gear-builtin/src/staking.rs b/pallets/gear-builtin/src/staking.rs index 9699c513b8c..d6900bb5f68 100644 --- a/pallets/gear-builtin/src/staking.rs +++ b/pallets/gear-builtin/src/staking.rs @@ -142,8 +142,6 @@ where T::AccountId: Origin, CallOf: From>, { - const ID: u64 = 2; - type Error = BuiltinActorError; fn handle(dispatch: &StoredDispatch, gas_limit: u64) -> (Result, u64) { diff --git a/pallets/gear-builtin/src/tests/bad_builtin_ids.rs b/pallets/gear-builtin/src/tests/bad_builtin_ids.rs index d56fe44d96f..af1f58552c6 100644 --- a/pallets/gear-builtin/src/tests/bad_builtin_ids.rs +++ b/pallets/gear-builtin/src/tests/bad_builtin_ids.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use crate::{self as pallet_gear_builtin, BuiltinActor, BuiltinActorError}; +use crate::{self as pallet_gear_builtin, ActorWithId, BuiltinActor, BuiltinActorError}; use frame_support::{ construct_runtime, parameter_types, traits::{ConstBool, ConstU32, ConstU64, FindAuthor, OnFinalize, OnInitialize}, @@ -95,61 +95,10 @@ pallet_gear::impl_config!( BuiltinDispatcherFactory = GearBuiltin, ); -pub struct FirstBuiltinActor {} -impl BuiltinActor for FirstBuiltinActor { +pub struct SomeBuiltinActor {} +impl BuiltinActor for SomeBuiltinActor { type Error = BuiltinActorError; - const ID: u64 = 1_u64; - - fn handle( - _dispatch: &StoredDispatch, - _gas_limit: u64, - ) -> (Result, u64) { - let payload = b"Success".to_vec().try_into().expect("Small vector"); - - (Ok(payload), 1_000_u64) - } -} - -pub struct SecondBuiltinActor {} -impl BuiltinActor for SecondBuiltinActor { - type Error = BuiltinActorError; - - const ID: u64 = 2_u64; - - fn handle( - _dispatch: &StoredDispatch, - _gas_limit: u64, - ) -> (Result, u64) { - let payload = b"Success".to_vec().try_into().expect("Small vector"); - - (Ok(payload), 1_000_u64) - } -} - -pub struct ThirdBuiltinActor {} -impl BuiltinActor for ThirdBuiltinActor { - type Error = BuiltinActorError; - - const ID: u64 = 3_u64; - - fn handle( - _dispatch: &StoredDispatch, - _gas_limit: u64, - ) -> (Result, u64) { - let payload = b"Success".to_vec().try_into().expect("Small vector"); - - (Ok(payload), 1_000_u64) - } -} - -// Duplicate builtin id: `BuiltinId(2)` already exists. -pub struct DuplicateBuiltinActor {} -impl BuiltinActor for DuplicateBuiltinActor { - type Error = BuiltinActorError; - - const ID: u64 = 2_u64; - fn handle( _dispatch: &StoredDispatch, _gas_limit: u64, @@ -163,10 +112,10 @@ impl BuiltinActor for DuplicateBuiltinActor { impl pallet_gear_builtin::Config for Test { type RuntimeCall = RuntimeCall; type Builtins = ( - FirstBuiltinActor, - SecondBuiltinActor, - ThirdBuiltinActor, - DuplicateBuiltinActor, + ActorWithId<1, SomeBuiltinActor>, + ActorWithId<2, SomeBuiltinActor>, + ActorWithId<3, SomeBuiltinActor>, + ActorWithId<2, SomeBuiltinActor>, // 2 already exists ); type WeightInfo = (); } diff --git a/pallets/gear-builtin/src/tests/staking.rs b/pallets/gear-builtin/src/tests/staking.rs index d85c0c0e3c6..bd806206ef5 100644 --- a/pallets/gear-builtin/src/tests/staking.rs +++ b/pallets/gear-builtin/src/tests/staking.rs @@ -592,7 +592,7 @@ mod util { BLOCK_AUTHOR, ENDOWMENT, EXISTENTIAL_DEPOSIT, MILLISECS_PER_BLOCK, SIGNER, UNITS, VAL_1_STASH, VAL_2_STASH, VAL_3_STASH, }; - use crate::{self as pallet_gear_builtin, staking::Actor as StakingBuiltin}; + use crate::{self as pallet_gear_builtin, staking::Actor as StakingBuiltin, ActorWithId}; pub(super) use common::Origin; pub(super) use demo_staking_broker::WASM_BINARY; use frame_election_provider_support::{ @@ -757,7 +757,7 @@ mod util { impl pallet_gear_builtin::Config for Test { type RuntimeCall = RuntimeCall; - type Builtins = (StakingBuiltin,); + type Builtins = (ActorWithId<2, StakingBuiltin>,); type WeightInfo = (); } diff --git a/pallets/gear-eth-bridge/src/builtin.rs b/pallets/gear-eth-bridge/src/builtin.rs index 038a4759532..68223d976d0 100644 --- a/pallets/gear-eth-bridge/src/builtin.rs +++ b/pallets/gear-eth-bridge/src/builtin.rs @@ -39,8 +39,6 @@ impl BuiltinActor for Actor where T::AccountId: Origin, { - const ID: u64 = 3; - type Error = BuiltinActorError; fn handle(dispatch: &StoredDispatch, gas_limit: u64) -> (Result, u64) { diff --git a/pallets/gear-eth-bridge/src/mock.rs b/pallets/gear-eth-bridge/src/mock.rs index 9bf83023569..3f93bc0cec9 100644 --- a/pallets/gear-eth-bridge/src/mock.rs +++ b/pallets/gear-eth-bridge/src/mock.rs @@ -24,6 +24,7 @@ use frame_support::{ use frame_support_test::TestRandomness; use frame_system::{self as system, pallet_prelude::BlockNumberFor}; use gprimitives::ActorId; +use pallet_gear_builtin::ActorWithId; use pallet_session::{SessionManager, ShouldEndSession}; use sp_core::{ed25519::Public, H256}; use sp_runtime::{ @@ -172,9 +173,11 @@ pallet_gear::impl_config!( BuiltinDispatcherFactory = GearBuiltin, ); +pub const BUILTIN_ID: u64 = 1; + impl pallet_gear_builtin::Config for Test { type RuntimeCall = RuntimeCall; - type Builtins = (crate::builtin::Actor,); + type Builtins = (ActorWithId>,); type WeightInfo = (); } diff --git a/pallets/gear-eth-bridge/src/tests.rs b/pallets/gear-eth-bridge/src/tests.rs index 6ee1fea4aab..e95fb3fdf1e 100644 --- a/pallets/gear-eth-bridge/src/tests.rs +++ b/pallets/gear-eth-bridge/src/tests.rs @@ -539,10 +539,9 @@ mod utils { use crate::builtin; use gear_core::message::UserMessage; use gprimitives::{ActorId, MessageId}; - use pallet_gear_builtin::BuiltinActor; pub(crate) fn builtin_id() -> ActorId { - GearBuiltin::generate_actor_id(builtin::Actor::::ID) + GearBuiltin::generate_actor_id(BUILTIN_ID) } #[track_caller] diff --git a/runtime/vara/src/lib.rs b/runtime/vara/src/lib.rs index c8f51a1d27f..f927ef46050 100644 --- a/runtime/vara/src/lib.rs +++ b/runtime/vara/src/lib.rs @@ -67,6 +67,7 @@ use frame_system::{ }; use pallet_election_provider_multi_phase::{GeometricDepositBase, SolutionAccuracyOf}; pub use pallet_gear::manager::{ExtManager, HandleKind}; +use pallet_gear_builtin::ActorWithId; pub use pallet_gear_payment::CustomChargeTransactionPayment; pub use pallet_gear_staking_rewards::StakingBlackList; use pallet_grandpa::{ @@ -1172,16 +1173,16 @@ impl pallet_gear_messenger::Config for Runtime { /// Builtin actors arranged in a tuple. #[cfg(not(feature = "dev"))] pub type BuiltinActors = ( - pallet_gear_builtin::bls12_381::Actor, - pallet_gear_builtin::staking::Actor, + ActorWithId<1, pallet_gear_builtin::bls12_381::Actor>, + ActorWithId<2, pallet_gear_builtin::staking::Actor>, ); /// Builtin actors arranged in a tuple. #[cfg(feature = "dev")] pub type BuiltinActors = ( - pallet_gear_builtin::bls12_381::Actor, - pallet_gear_builtin::staking::Actor, - pallet_gear_eth_bridge::Actor, + ActorWithId<1, pallet_gear_builtin::bls12_381::Actor>, + ActorWithId<2, pallet_gear_builtin::staking::Actor>, + ActorWithId<3, pallet_gear_eth_bridge::Actor>, ); impl pallet_gear_builtin::Config for Runtime {