diff --git a/state-chain/chains/src/btc.rs b/state-chain/chains/src/btc.rs index 42bbb107ad..dc9a216823 100644 --- a/state-chain/chains/src/btc.rs +++ b/state-chain/chains/src/btc.rs @@ -254,6 +254,7 @@ pub enum PreviousOrCurrent { #[derive(Clone, Debug, PartialEq, Eq)] pub struct BitcoinCrypto; impl ChainCrypto for BitcoinCrypto { + const NAME: &'static str = "Bitcoin"; type UtxoChain = ConstBool; type AggKey = AggKey; diff --git a/state-chain/chains/src/dot.rs b/state-chain/chains/src/dot.rs index 643945da54..93ea4aabc2 100644 --- a/state-chain/chains/src/dot.rs +++ b/state-chain/chains/src/dot.rs @@ -357,6 +357,7 @@ impl ChannelLifecycleHooks for PolkadotChannelState { #[derive(Clone, Debug, PartialEq, Eq)] pub struct PolkadotCrypto; impl ChainCrypto for PolkadotCrypto { + const NAME: &'static str = "Polkadot"; type UtxoChain = ConstBool; type AggKey = PolkadotPublicKey; diff --git a/state-chain/chains/src/evm.rs b/state-chain/chains/src/evm.rs index add93328cd..3a935732c9 100644 --- a/state-chain/chains/src/evm.rs +++ b/state-chain/chains/src/evm.rs @@ -33,6 +33,7 @@ pub struct DepositDetails { pub struct EvmCrypto; impl ChainCrypto for EvmCrypto { + const NAME: &'static str = "EVM"; type UtxoChain = ConstBool; type AggKey = evm::AggKey; diff --git a/state-chain/chains/src/lib.rs b/state-chain/chains/src/lib.rs index 7fc4c80909..4e2a3088f1 100644 --- a/state-chain/chains/src/lib.rs +++ b/state-chain/chains/src/lib.rs @@ -280,6 +280,7 @@ pub trait Chain: Member + Parameter + ChainInstanceAlias { /// Common crypto-related types and operations for some external chain. pub trait ChainCrypto: ChainCryptoInstanceAlias { + const NAME: &'static str; type UtxoChain: Get; /// The chain's `AggKey` format. The AggKey is the threshold key that controls the vault. diff --git a/state-chain/chains/src/mocks.rs b/state-chain/chains/src/mocks.rs index 2aacf1c90f..b51b494cae 100644 --- a/state-chain/chains/src/mocks.rs +++ b/state-chain/chains/src/mocks.rs @@ -253,6 +253,7 @@ pub const BAD_AGG_KEY_POST_HANDOVER: MockAggKey = MockAggKey(*b"bad!"); #[derive(Copy, Clone, RuntimeDebug, Default, PartialEq, Eq, Encode, Decode, TypeInfo)] pub struct MockEthereumChainCrypto; impl ChainCrypto for MockEthereumChainCrypto { + const NAME: &'static str = "MockEthereum"; type UtxoChain = ConstBool; type AggKey = MockAggKey; diff --git a/state-chain/chains/src/none.rs b/state-chain/chains/src/none.rs index 2a6d024cf2..72bc55e9ae 100644 --- a/state-chain/chains/src/none.rs +++ b/state-chain/chains/src/none.rs @@ -43,6 +43,7 @@ impl FeeRefundCalculator for () { #[derive(Clone, Debug, PartialEq, Eq)] pub struct NoneChainCrypto; impl ChainCrypto for NoneChainCrypto { + const NAME: &'static str = "None"; type UtxoChain = ConstBool; type AggKey = (); type Payload = (); diff --git a/state-chain/chains/src/sol.rs b/state-chain/chains/src/sol.rs index 04877d7de6..11a2a17572 100644 --- a/state-chain/chains/src/sol.rs +++ b/state-chain/chains/src/sol.rs @@ -81,6 +81,7 @@ impl Chain for Solana { pub struct SolanaCrypto; impl ChainCrypto for SolanaCrypto { + const NAME: &'static str = "Solana"; type UtxoChain = ConstBool; type KeyHandoverIsRequired = ConstBool; diff --git a/state-chain/pallets/cf-threshold-signature/src/lib.rs b/state-chain/pallets/cf-threshold-signature/src/lib.rs index d86c6b2dea..3576b4f2f6 100644 --- a/state-chain/pallets/cf-threshold-signature/src/lib.rs +++ b/state-chain/pallets/cf-threshold-signature/src/lib.rs @@ -18,7 +18,7 @@ mod response_status; use response_status::ResponseStatus; use codec::{Decode, Encode, MaxEncodedLen}; -use scale_info::TypeInfo; +use scale_info::{build::Fields, Path, Type, TypeInfo}; use cf_chains::ChainCrypto; use cf_primitives::{ @@ -234,8 +234,7 @@ pub mod pallet { }; use frame_system::ensure_none; /// Context for tracking the progress of a threshold signature ceremony. - #[derive(Clone, RuntimeDebug, PartialEq, Eq, Encode, Decode, TypeInfo)] - #[scale_info(skip_type_params(T, I))] + #[derive(Clone, RuntimeDebug, PartialEq, Eq, Encode, Decode)] pub struct CeremonyContext, I: 'static> { pub request_context: RequestContext, /// The respondents that have yet to reply. @@ -252,8 +251,7 @@ pub mod pallet { pub threshold_ceremony_type: ThresholdCeremonyType, } - #[derive(Clone, RuntimeDebug, PartialEq, Eq, Encode, Decode, TypeInfo)] - #[scale_info(skip_type_params(T, I))] + #[derive(Clone, RuntimeDebug, PartialEq, Eq, Encode, Decode)] pub struct RequestContext, I: 'static> { pub request_id: RequestId, /// The number of ceremonies attempted so far, excluding the current one. @@ -1199,6 +1197,88 @@ pub mod pallet { } } +macro_rules! append_chain_to_name { + ($name:ident) => { + match T::TargetChainCrypto::NAME { + "EVM" => concat!(stringify!($name), "EVM"), + "Polkadot" => concat!(stringify!($name), "Polkadot"), + "Bitcoin" => concat!(stringify!($name), "Bitcoin"), + "Solana" => concat!(stringify!($name), "Solana"), + _ => concat!(stringify!($name), "Other"), + } + }; +} + +impl TypeInfo for pallet::CeremonyContext +where + T: Config, + I: 'static, +{ + type Identity = Self; + fn type_info() -> Type { + Type::builder() + .path(Path::new(append_chain_to_name!(CeremonyContext), module_path!())) + .composite( + Fields::named() + .field(|f| { + f.ty::>() + .type_name(append_chain_to_name!(RequestContext)) + .name("request_context") + }) + .field(|f| { + f.ty::>() + .type_name("BTreeSet") + .name("remaining_respondents") + }) + .field(|f| { + f.ty::>() + .type_name("BTreeMap") + .name("blame_counts") + }) + .field(|f| { + f.ty::>() + .type_name("BTreeSet") + .name("candidates") + }) + .field(|f| f.ty::().type_name("EpochIndex").name("epoch")) + .field(|f| { + f.ty::<::AggKey>() + .type_name(append_chain_to_name!(Key)) + .name("key") + }) + .field(|f| { + f.ty::() + .type_name("ThresholdCeremonyType") + .name("threshold_ceremony_type") + }), + ) + } +} + +impl TypeInfo for pallet::RequestContext +where + T: Config, + I: 'static, +{ + type Identity = Self; + fn type_info() -> Type { + Type::builder() + .path(Path::new(append_chain_to_name!(RequestContext), module_path!())) + .composite( + Fields::named() + .field(|f| f.ty::().type_name("RequestId").name("request_id")) + .field(|f| { + f.ty::().type_name("AttemptCount").name("attempt_count") + }) + .field(|f| { + f.ty::>() + .type_name(append_chain_to_name!(PayloadFor)) + .name("payload") + }), + ) + } +} + impl, I: 'static> Pallet { /// Initiate a new signature request, returning the request id. fn inner_request_signature(