From a3a0ef51cf407d4c89d96a943438efe75bc5db61 Mon Sep 17 00:00:00 2001
From: cgeek <cem.moreau@gmail.com>
Date: Sat, 14 Oct 2023 12:31:01 +0200
Subject: [PATCH] fix(#125): bug initial_members: OK

---
 Cargo.lock                              | 18 ++++++--
 Cargo.toml                              |  1 +
 node/src/chain_spec/gen_genesis_data.rs | 56 ++++++++++++++++++++++++-
 3 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index d04e1a103..8945b86fa 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 c95bc94fa..1eed30f5b 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 2fdd6cef0..d523266ad 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()
+        );
+    }
+}
-- 
GitLab