From f2fb3616315f6c30fb5f354e9b3147d581c9d8d2 Mon Sep 17 00:00:00 2001 From: Rodrigo Quelhas Date: Thu, 23 May 2024 11:44:10 +0100 Subject: [PATCH] add MockSignature and MockSigner to precompile test utils --- precompiles/src/testing/account.rs | 88 ++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/precompiles/src/testing/account.rs b/precompiles/src/testing/account.rs index ad83047713..77aa0f6c7b 100644 --- a/precompiles/src/testing/account.rs +++ b/precompiles/src/testing/account.rs @@ -100,6 +100,94 @@ impl sp_runtime::traits::Convert for MockAccount { } } +#[derive( + Eq, + PartialEq, + Clone, + Encode, + Decode, + sp_core::RuntimeDebug, + TypeInfo, + Serialize, + Deserialize +)] +pub struct MockSignature(sp_core::ecdsa::Signature); + +impl From for MockSignature { + fn from(x: sp_core::ecdsa::Signature) -> Self { + MockSignature(x) + } +} + +impl From for MockSignature { + fn from(signature: sp_runtime::MultiSignature) -> Self { + match signature { + sp_runtime::MultiSignature::Ed25519(_) => { + panic!("Ed25519 not supported for MockSignature") + } + sp_runtime::MultiSignature::Sr25519(_) => { + panic!("Sr25519 not supported for MockSignature") + } + sp_runtime::MultiSignature::Ecdsa(sig) => Self(sig), + } + } +} + +impl sp_runtime::traits::Verify for MockSignature { + type Signer = MockSigner; + fn verify>(&self, mut msg: L, signer: &MockAccount) -> bool { + let mut m = [0u8; 32]; + m.copy_from_slice(::digest(msg.get()).as_slice()); + match sp_io::crypto::secp256k1_ecdsa_recover(self.0.as_ref(), &m) { + Ok(pubkey) => { + MockAccount(sp_core::H160::from_slice( + &::digest(pubkey).as_slice()[12..32], + )) == *signer + } + Err(sp_io::EcdsaVerifyError::BadRS) => { + log::error!(target: "evm", "Error recovering: Incorrect value of R or S"); + false + } + Err(sp_io::EcdsaVerifyError::BadV) => { + log::error!(target: "evm", "Error recovering: Incorrect value of V"); + false + } + Err(sp_io::EcdsaVerifyError::BadSignature) => { + log::error!(target: "evm", "Error recovering: Invalid signature"); + false + } + } + } +} + +/// Public key for an Ethereum compatible account +#[derive( + Eq, + PartialEq, + Ord, + PartialOrd, + Clone, + Encode, + Decode, + sp_core::RuntimeDebug, + TypeInfo +)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct MockSigner([u8; 20]); + +impl sp_runtime::traits::IdentifyAccount for MockSigner { + type AccountId = MockAccount; + fn into_account(self) -> MockAccount { + MockAccount(self.0.into()) + } +} + +impl From<[u8; 20]> for MockSigner { + fn from(x: [u8; 20]) -> Self { + MockSigner(x) + } +} + #[macro_export] macro_rules! mock_account { ($name:ident, $convert:expr) => {