diff --git a/Cargo.lock b/Cargo.lock index b8f42cc068abe956a266a2166f141a36a1c77ed2..92c7b383b48ab90fc506ef9099dab7162ec65d2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "Inflector" @@ -9058,7 +9058,6 @@ dependencies = [ "base64 0.22.1", "bs58", "duniter-primitives", - "ed25519-dalek", "frame-benchmarking", "frame-support", "frame-system", diff --git a/Cargo.toml b/Cargo.toml index 54ee0162e19d9448da4c9371a08a143c0219c79a..44e1a7c9bfb0a47f6a680a9d14d90e26794e83fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,7 +52,6 @@ base64 = { version = "0.22.1", default-features = false } countmap = { version = "0.2.0", default-features = false } ctrlc = { version = "3.4.4", default-features = false } cucumber = { version = "0.20.2", default-features = false } -ed25519-dalek = { version = "2.1.1", default-features = false } env_logger = { version = "0.11.3", default-features = false } notify = { version = "6.1.1", default-features = false } portpicker = { version = "0.1.1", default-features = false } @@ -248,8 +247,6 @@ cranelift-wasm = { opt-level = 3 } crc32fast = { opt-level = 3 } crossbeam-deque = { opt-level = 3 } crypto-mac = { opt-level = 3 } -curve25519-dalek = { opt-level = 3 } -ed25519-dalek = { opt-level = 3 } futures-channel = { opt-level = 3 } hashbrown = { opt-level = 3 } hash-db = { opt-level = 3 } diff --git a/pallets/distance/src/mock.rs b/pallets/distance/src/mock.rs index e804df741245c2fc738b79305e15f226033c2333..06b89976b8ef40c36cb03ad5cf1718a023eeac2a 100644 --- a/pallets/distance/src/mock.rs +++ b/pallets/distance/src/mock.rs @@ -27,7 +27,7 @@ use sp_core::{ConstU32, H256}; use sp_runtime::{ impl_opaque_keys, key_types::DUMMY, - testing::{TestSignature, UintAuthorityId}, + testing::{TestSignature as SubtrateTestSignature, UintAuthorityId}, traits::{BlakeTwo256, ConvertInto, IdentityLookup, IsMember, OpaqueKeys}, BuildStorage, KeyTypeId, Perbill, }; @@ -36,6 +36,39 @@ type Balance = u64; type Block = frame_system::mocking::MockBlock<Test>; pub type AccountId = u64; +pub struct AccountId32Mock(u64); +impl From<AccountId32Mock> for u64 { + fn from(account: AccountId32Mock) -> u64 { + account.0 + } +} +impl From<[u8; 32]> for AccountId32Mock { + fn from(bytes: [u8; 32]) -> Self { + Self(u64::from_be_bytes([ + bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], + ])) + } +} + +/// Test signature that impl From<ed25519::Signature> (required to compile pallet identity) +#[derive(Clone, codec::Decode, Debug, Eq, codec::Encode, PartialEq, scale_info::TypeInfo)] +pub struct TestSignature(SubtrateTestSignature); +impl From<sp_core::ed25519::Signature> for TestSignature { + fn from(_: sp_core::ed25519::Signature) -> Self { + // Implementation here only to satisfy traits bounds at compilation + // This convertion should not be used inside pallet distance tests + unimplemented!() + } +} + +impl sp_runtime::traits::Verify for TestSignature { + type Signer = UintAuthorityId; + + fn verify<L: sp_runtime::traits::Lazy<[u8]>>(&self, msg: L, signer: &u64) -> bool { + <SubtrateTestSignature as sp_runtime::traits::Verify>::verify::<L>(&self.0, msg, signer) + } +} + impl_opaque_keys! { pub struct MockSessionKeys { pub dummy: UintAuthorityId, @@ -217,6 +250,7 @@ impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl { } impl pallet_identity::Config for Test { + type AccountId32 = AccountId32Mock; type AccountLinker = (); type AutorevocationPeriod = AutorevocationPeriod; type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod; diff --git a/pallets/duniter-wot/src/mock.rs b/pallets/duniter-wot/src/mock.rs index a3c550632f5febae809a1bf20cff4c28f75eb579..e246133a0353c68fbeda9c3566dd20b5485de6a1 100644 --- a/pallets/duniter-wot/src/mock.rs +++ b/pallets/duniter-wot/src/mock.rs @@ -20,7 +20,7 @@ use frame_support::{derive_impl, parameter_types, traits::Everything}; use frame_system as system; use sp_core::H256; use sp_runtime::{ - testing::{TestSignature, UintAuthorityId}, + testing::{TestSignature as SubtrateTestSignature, UintAuthorityId}, traits::{BlakeTwo256, IdentityLookup}, BuildStorage, }; @@ -30,6 +30,46 @@ use std::collections::BTreeMap; type AccountId = u64; type Block = frame_system::mocking::MockBlock<Test>; +pub struct AccountId32Mock(u64); +impl From<AccountId32Mock> for u64 { + fn from(account: AccountId32Mock) -> u64 { + account.0 + } +} +impl From<[u8; 32]> for AccountId32Mock { + fn from(bytes: [u8; 32]) -> Self { + Self(u64::from_be_bytes([ + bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], + ])) + } +} + +/// Test signature that impl From<ed25519::Signature> (required to compile pallet identity) +#[derive(Clone, codec::Decode, Debug, Eq, codec::Encode, PartialEq, scale_info::TypeInfo)] +pub struct TestSignature(SubtrateTestSignature); + +impl TestSignature { + pub fn new(signer: u64, message: Vec<u8>) -> Self { + Self(SubtrateTestSignature(signer, message)) + } +} + +impl From<sp_core::ed25519::Signature> for TestSignature { + fn from(_: sp_core::ed25519::Signature) -> Self { + // Implementation here only to satisfy traits bounds at compilation + // This convertion should not be used inside pallet distance tests + unimplemented!() + } +} + +impl sp_runtime::traits::Verify for TestSignature { + type Signer = UintAuthorityId; + + fn verify<L: sp_runtime::traits::Lazy<[u8]>>(&self, msg: L, signer: &u64) -> bool { + <SubtrateTestSignature as sp_runtime::traits::Verify>::verify::<L>(&self.0, msg, signer) + } +} + // Configure a mock runtime to test the pallet. frame_support::construct_runtime!( pub enum Test { @@ -96,6 +136,7 @@ impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl { } impl pallet_identity::Config for Test { + type AccountId32 = AccountId32Mock; type AccountLinker = (); type AutorevocationPeriod = AutorevocationPeriod; type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod; diff --git a/pallets/duniter-wot/src/tests.rs b/pallets/duniter-wot/src/tests.rs index a6baf65e2791e2803458c1df65d126966f8b7167..6db6cfe80a7c31ff84781095c17803d13009258d 100644 --- a/pallets/duniter-wot/src/tests.rs +++ b/pallets/duniter-wot/src/tests.rs @@ -21,7 +21,6 @@ use pallet_identity::{ IdtyName, IdtyStatus, RevocationPayload, RevocationReason, REVOCATION_PAYLOAD_PREFIX, }; use pallet_membership::MembershipRemovalReason; -use sp_runtime::testing::TestSignature; /// test that genesis builder creates the good number of identities /// and good identity and certification metadate @@ -186,7 +185,7 @@ fn test_revoke_idty() { RuntimeOrigin::signed(1), 1, 1, - TestSignature( + TestSignature::new( 1, ( REVOCATION_PAYLOAD_PREFIX, @@ -211,7 +210,7 @@ fn test_revoke_idty() { RuntimeOrigin::signed(42), 2, 2, - TestSignature( + TestSignature::new( 2, ( REVOCATION_PAYLOAD_PREFIX, diff --git a/pallets/identity/Cargo.toml b/pallets/identity/Cargo.toml index f86d0f991a07c616da8cd97aaa0975a96297bb8b..13eb8edf3896a1852937ba904d11a1744291d8ba 100644 --- a/pallets/identity/Cargo.toml +++ b/pallets/identity/Cargo.toml @@ -46,7 +46,6 @@ base64 = { workspace = true } bs58 = { workspace = true } codec = { workspace = true, features = ["derive"] } duniter-primitives = { workspace = true } -ed25519-dalek = { workspace = true } frame-benchmarking = { workspace = true, optional = true } frame-support = { workspace = true } frame-system = { workspace = true } diff --git a/pallets/identity/src/lib.rs b/pallets/identity/src/lib.rs index 64f47fe83edbed60889149f263e66a6cd14f6afd..0e00c7e7a061ca8d70c7c716dddc116d3a045802 100644 --- a/pallets/identity/src/lib.rs +++ b/pallets/identity/src/lib.rs @@ -103,6 +103,9 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { + /// The way to deserialize accound id from 32 raw bytes + type AccountId32: From<[u8; 32]> + Into<Self::AccountId>; + /// The period during which the owner can confirm the new identity. #[pallet::constant] type ConfirmPeriod: Get<BlockNumberFor<Self>>; @@ -173,7 +176,9 @@ pub mod pallet { type Signer: IdentifyAccount<AccountId = Self::AccountId>; /// Signature type for payload verification. - type Signature: Parameter + Verify<Signer = Self::Signer>; + type Signature: Parameter + + Verify<Signer = Self::Signer> + + From<sp_core::ed25519::Signature>; /// The overarching event type. type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>; @@ -637,10 +642,15 @@ pub mod pallet { ) .into_array_const::<32>() .map_err(|_| Error::<T>::InvalidLegacyRevocationFormat)?; - ed25519_dalek::VerifyingKey::from_bytes(&issuer) - .map_err(|_| Error::<T>::InvalidLegacyRevocationFormat)? - .verify_strict(document, &ed25519_dalek::Signature::from_bytes(&signature)) - .map_err(|_| Error::<T>::InvalidSignature)?; + + // Verify signature + let revocation_key = T::AccountId32::from(issuer).into(); + let signature = T::Signature::from(sp_core::ed25519::Signature::from(signature)); + ensure!( + signature.verify(document, &revocation_key), + Error::<T>::InvalidSignature + ); + let username = line_username .get(14..) .ok_or(Error::<T>::InvalidLegacyRevocationFormat)?; @@ -657,8 +667,6 @@ pub mod pallet { IdtyStatus::Revoked => Err(Error::<T>::AlreadyRevoked), }?; - let revocation_key = T::AccountId::decode(&mut &issuer[..]).unwrap(); - ensure!( if let Some((ref old_owner_key, last_change)) = idty_value.old_owner_key { // old owner key can also revoke the identity until the period expired diff --git a/pallets/identity/src/mock.rs b/pallets/identity/src/mock.rs index 70758bc813260c41b9175e9e2225338b89c35c9f..de48f0a2e24cf7ba19dc423a52bf03b306a64dee 100644 --- a/pallets/identity/src/mock.rs +++ b/pallets/identity/src/mock.rs @@ -89,6 +89,7 @@ impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl { } impl pallet_identity::Config for Test { + type AccountId32 = AccountId; type AccountLinker = (); type AutorevocationPeriod = AutorevocationPeriod; type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod; diff --git a/pallets/quota/src/mock.rs b/pallets/quota/src/mock.rs index f39b053dfe4c1f565549dd401b54bf52d8b0a1de..dcfd30f778936b5d9cc55b5e2195da82ffa1c806 100644 --- a/pallets/quota/src/mock.rs +++ b/pallets/quota/src/mock.rs @@ -133,6 +133,7 @@ impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl { } } impl pallet_identity::Config for Test { + type AccountId32 = AccountId; type AccountLinker = (); type AutorevocationPeriod = AutorevocationPeriod; type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod; diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs index 04fa45d061f2ee8a191a9dd12db531d536707677..c3b6e728fcb533c49189598ed05a840cef2016f5 100644 --- a/runtime/common/src/pallets_config.rs +++ b/runtime/common/src/pallets_config.rs @@ -432,6 +432,7 @@ macro_rules! pallets_config { pub const ValidationPeriod: BlockNumber = 2 * MONTHS; } impl pallet_identity::Config for Runtime { + type AccountId32 = AccountId; type AccountLinker = Account; type AutorevocationPeriod = AutorevocationPeriod; type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod; diff --git a/scripts/check_metadata.sh b/scripts/check_metadata.sh index 69bd92b6f755a18b7945df0d1766bd051902352a..053b92c185fb291ffdedce4a52ec931d20f6ad87 100755 --- a/scripts/check_metadata.sh +++ b/scripts/check_metadata.sh @@ -1,6 +1,6 @@ #!/bin/sh -cargo install subxt-cli +cargo install subxt-cli --git https://github.com/duniter/subxt --branch subxt-v0.38.0-duniter-substrate-v1.17.0 cargo build target/debug/duniter --dev& sleep 20