diff --git a/Cargo.lock b/Cargo.lock index d04e1a10390886842e588789ca9423d8cce686af..8945b86fa5f525c29fd2edb467b308a5bb5e8bab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -558,6 +558,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "tinyvec", +] + [[package]] name = "bstr" version = "1.2.0" @@ -1592,7 +1601,7 @@ dependencies = [ "sp-distance", "sp-runtime", "subxt", - "time 0.1.45", + "time 0.3.23", "time-macros", "tokio", ] @@ -1643,6 +1652,7 @@ name = "duniter" version = "0.3.0" dependencies = [ "async-io", + "bs58 0.5.0", "clap 4.1.4", "clap_complete", "common-runtime", @@ -3903,7 +3913,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "799676bb0807c788065e57551c6527d461ad572162b0519d1958946ff9e0539d" dependencies = [ "asn1_der", - "bs58", + "bs58 0.4.0", "ed25519-dalek", "either", "fnv", @@ -4595,7 +4605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c580bfdd8803cce319b047d239559a22f809094aaea4ac13902a1fdcfcd4261" dependencies = [ "arrayref", - "bs58", + "bs58 0.4.0", "byteorder", "data-encoding", "multihash", @@ -9915,7 +9925,7 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "digest 0.10.6", "rand 0.8.5", "static_assertions", diff --git a/Cargo.toml b/Cargo.toml index c95bc94fae11599c1fbd3e1a320dd973149221e9..1eed30f5b62826f229d04afe31048e4bdaf45f29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,6 +75,7 @@ sp-membership = { path = 'primitives/membership' } # crates.io dependencies async-io = "1.3" +bs58 = "0.5.0" clap = { version = "4.0", features = ["derive"] } clap_complete = { version = "4" } futures = { version = "0.3.1", features = ["compat"] } diff --git a/node/src/chain_spec/gen_genesis_data.rs b/node/src/chain_spec/gen_genesis_data.rs index 2fdd6cef08caa4a40d06c1c9b40e6ec197f44a14..d523266adba024330f87a0739126b8316289445b 100644 --- a/node/src/chain_spec/gen_genesis_data.rs +++ b/node/src/chain_spec/gen_genesis_data.rs @@ -14,9 +14,11 @@ // You should have received a copy of the GNU Affero General Public License // along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>. +use crate::chain_spec::AccountPublic; use common_runtime::*; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use sp_core::{blake2_256, Decode, Encode, H256}; +use sp_core::{blake2_256, ed25519, Decode, Encode, H256}; +use sp_runtime::traits::IdentifyAccount; use std::collections::BTreeMap; type MembershipData = sp_membership::MembershipData<u32>; @@ -405,3 +407,55 @@ fn to_bn(genesis_timestamp: u64, timestamp: u64) -> u32 { fn validate_idty_name(name: &str) -> bool { name.len() <= 64 } + +// Base58 encoded Ed25519 public key +#[derive(Clone, Deserialize, Serialize, Ord, PartialOrd, Eq, PartialEq)] +struct PubkeyV1(String); + +/// Converts a Duniter v1 public key (Ed25519) to an Account Id. +/// No need to convert to address. +fn v1_pubkey_to_account_id(pubkey: PubkeyV1) -> AccountId { + let bytes = bs58::decode(pubkey.0) + .into_vec() + .expect("Duniter v1 pubkey should be decodable"); + let prepend = vec![0u8; 32 - &bytes.len()]; + let bytes: [u8; 32] = [prepend.as_slice(), bytes.as_slice()] + .concat() + .as_slice() + .try_into() + .expect("incorrect pubkey length"); + AccountPublic::from(ed25519::Public::from_raw(bytes)).into_account() +} + +/// Converts a number of seconds to a number of 6-seconds blocs +/// use lower approximation +/// example : 2 seconds will be block 0 +/// example : 7 seconds will be block 1 +fn seconds_to_blocs(seconds: u32) -> u32 { + seconds / 6 +} + +#[cfg(test)] +mod tests { + use super::*; + use sp_core::crypto::{Ss58AddressFormat, Ss58Codec}; + use std::str::FromStr; + + #[test] + fn test_timestamp_to_relative_blocs() { + assert_eq!(seconds_to_blocs(2), 0); + assert_eq!(seconds_to_blocs(6), 1); + assert_eq!(seconds_to_blocs(7), 1); + } + + #[test] + fn test_v1_pubkey_to_v2_address_translation() { + assert_eq!( + v1_pubkey_to_account_id(PubkeyV1 { + 0: "2ny7YAdmzReQxAayyJZsyVYwYhVyax2thKcGknmQy5nQ".to_string() + }) + .to_ss58check_with_version(Ss58AddressFormat::custom(42)), + "5CfdJjEgh3jDkg3bzmZ1ED1xVhXAARtNmZJWbcXh53rU8z5a".to_owned() + ); + } +}