From d0a5deb55050015fbdc915360a717d8aeee29877 Mon Sep 17 00:00:00 2001
From: cgeek <cem.moreau@gmail.com>
Date: Wed, 11 Oct 2023 21:51:13 +0200
Subject: [PATCH] fix(#125): review: invalid pubkeys (len 33)
---
node/src/chain_spec/gen_genesis_data.rs | 60 ++++++++++++++++++-------
1 file changed, 44 insertions(+), 16 deletions(-)
diff --git a/node/src/chain_spec/gen_genesis_data.rs b/node/src/chain_spec/gen_genesis_data.rs
index 230b8612a..9b7b89e9d 100644
--- a/node/src/chain_spec/gen_genesis_data.rs
+++ b/node/src/chain_spec/gen_genesis_data.rs
@@ -36,6 +36,7 @@ use sp_runtime::Perbill;
use std::collections::{BTreeMap, HashMap};
use std::fmt::{Debug, Display, Formatter};
use std::fs;
+use std::ops::{Add, Sub};
static G1_DUNITER_V1_EXISTENTIAL_DEPOSIT: u64 = 100;
static G1_DUNITER_V1_DECIMALS: usize = 2;
@@ -241,7 +242,8 @@ where
std::env::var("DUNITER_GENESIS_CONFIG").unwrap_or_else(|_| json_file_path.to_owned()),
)?;
- let treasury_funder = v1_pubkey_to_account_id(treasury_funder);
+ let treasury_funder = v1_pubkey_to_account_id(treasury_funder)
+ .expect("treasury founder must have a valid public key");
let common_parameters = get_common_parameters(¶meters);
@@ -296,7 +298,8 @@ where
name,
IdentityV2 {
index: i.index,
- owner_key: v1_pubkey_to_account_id(i.owner_key),
+ owner_key: v1_pubkey_to_account_id(i.owner_key)
+ .expect("a G1 identity necessarily has a valid pubkey"),
old_owner_key: None,
membership_expire_on: timestamp_to_relative_blocs(
i.membership_expire_on,
@@ -390,6 +393,7 @@ where
// smith certifications
let mut smith_certs_by_receiver = BTreeMap::new();
let mut initial_monetary_mass = 0;
+ let mut invalid_wallets = 0;
//let mut total_dust = 0;
// FORCED AUTHORITY //
@@ -463,15 +467,19 @@ where
monetary_mass += balance;
// json prevents duplicate wallets
- let owner_key = v1_pubkey_to_account_id(pubkey.clone());
- accounts.insert(
- owner_key.clone(),
- GenesisAccountData {
- random_id: H256(blake2_256(&(balance, &owner_key).encode())),
- balance: *balance,
- is_identity: false,
- },
- );
+ if let Ok(owner_key) = v1_pubkey_to_account_id(pubkey.clone()) {
+ accounts.insert(
+ owner_key.clone(),
+ GenesisAccountData {
+ random_id: H256(blake2_256(&(balance, &owner_key).encode())),
+ balance: *balance,
+ is_identity: false,
+ },
+ );
+ } else {
+ log::warn!("wallet {pubkey} has wrong format");
+ invalid_wallets = invalid_wallets.add(1);
+ }
}
// Technical Comittee //
@@ -949,7 +957,7 @@ where
);
assert_eq!(
accounts.len(),
- identity_index.len() + genesis_data.wallets.len()
+ identity_index.len() + genesis_data.wallets.len().sub(invalid_wallets)
);
// no inactive tech comm
for tech_com_member in &technical_committee {
@@ -1014,12 +1022,18 @@ where
transactions_history: genesis_data.transactions_history.map(|history| {
history
.iter()
+ // Avoid wrong pubkeys in tx history
+ .filter(|(pubkey, _)| v1_pubkey_to_account_id((*pubkey).clone()).is_ok())
.map(|(pubkey, txs)| {
(
- v1_pubkey_to_account_id(pubkey.clone()),
+ v1_pubkey_to_account_id(pubkey.clone())
+ .expect("already checked account"),
txs.iter()
+ // Avoid wrong pubkeys in tx history
+ .filter(|tx| v1_pubkey_to_account_id(tx.issuer.clone()).is_ok())
.map(|tx| TransactionV2 {
- issuer: v1_pubkey_to_account_id(tx.issuer.clone()),
+ issuer: v1_pubkey_to_account_id(tx.issuer.clone())
+ .expect("already checked tx.issuer"),
amount: tx.amount.clone(),
written_time: tx.written_time,
comment: tx.comment.clone(),
@@ -1303,17 +1317,20 @@ fn get_authority_keys_from_seed(s: &str) -> AuthorityKeys {
/// 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 {
+fn v1_pubkey_to_account_id(pubkey: PubkeyV1) -> Result<AccountId, String> {
let bytes = bs58::decode(pubkey.0)
.into_vec()
.expect("Duniter v1 pubkey should be decodable");
+ if bytes.len() > 32 {
+ return Err("Pubkey is too long".to_string());
+ }
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()
+ Ok(AccountPublic::from(ed25519::Public::from_raw(bytes)).into_account())
}
fn timestamp_to_relative_blocs(timestamp: TimestampV1, start: u64) -> u32 {
@@ -1348,8 +1365,19 @@ mod tests {
v1_pubkey_to_account_id(PubkeyV1 {
0: "2ny7YAdmzReQxAayyJZsyVYwYhVyax2thKcGknmQy5nQ".to_string()
})
+ .unwrap()
.to_ss58check_with_version(Ss58AddressFormat::custom(42)),
"5CfdJjEgh3jDkg3bzmZ1ED1xVhXAARtNmZJWbcXh53rU8z5a".to_owned()
);
}
+
+ #[test]
+ fn test_pubkey_with_33_bytes() {
+ assert_eq!(
+ v1_pubkey_to_account_id(PubkeyV1 {
+ 0: "d2meevcahfts2gqmvmrw5hzi25jddikk4nc4u1fkwrau".to_string()
+ }),
+ Err("Pubkey is too long".to_owned())
+ );
+ }
}
--
GitLab