Skip to content
Snippets Groups Projects
Commit 40823408 authored by Cédric Moreau's avatar Cédric Moreau
Browse files

fix(#125): dissociate genesis config from genesis migration

parent b145f36f
No related branches found
No related tags found
No related merge requests found
...@@ -15,9 +15,12 @@ ...@@ -15,9 +15,12 @@
// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>. // along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
use common_runtime::*; use common_runtime::*;
use maplit::btreemap;
use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde::{de::DeserializeOwned, Deserialize, Serialize};
use sp_core::crypto::AccountId32;
use sp_core::{blake2_256, Decode, Encode, H256}; use sp_core::{blake2_256, Decode, Encode, H256};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fmt::format;
type MembershipData = sp_membership::MembershipData<u32>; type MembershipData = sp_membership::MembershipData<u32>;
...@@ -55,7 +58,6 @@ struct GenesisConfig<Parameters> { ...@@ -55,7 +58,6 @@ struct GenesisConfig<Parameters> {
first_ud: Option<u64>, first_ud: Option<u64>,
first_ud_reeval: Option<u64>, first_ud_reeval: Option<u64>,
genesis_parameters: ParamsAppliedAtGenesis, genesis_parameters: ParamsAppliedAtGenesis,
identities: BTreeMap<String, Idty>,
#[serde(default)] #[serde(default)]
parameters: Parameters, parameters: Parameters,
#[serde(rename = "smiths")] #[serde(rename = "smiths")]
...@@ -63,6 +65,11 @@ struct GenesisConfig<Parameters> { ...@@ -63,6 +65,11 @@ struct GenesisConfig<Parameters> {
sudo_key: Option<AccountId>, sudo_key: Option<AccountId>,
technical_committee: Vec<String>, technical_committee: Vec<String>,
ud: u64, ud: u64,
}
#[derive(Deserialize, Serialize)]
struct GenesisMigrationData {
identities: BTreeMap<String, Idty>,
#[serde(default)] #[serde(default)]
wallets: BTreeMap<AccountId, u64>, wallets: BTreeMap<AccountId, u64>,
} }
...@@ -112,36 +119,8 @@ where ...@@ -112,36 +119,8 @@ where
SK: Decode, SK: Decode,
F: Fn(GenesisData<P, SK>) -> CS, F: Fn(GenesisData<P, SK>) -> CS,
{ {
let genesis_timestamp: u64 = let genesis_timestamp: u64 = get_genesis_timestamp()?;
if let Ok(genesis_timestamp) = std::env::var("DUNITER_GENESIS_TIMESTAMP") {
genesis_timestamp
.parse()
.map_err(|_| "DUNITER_GENESIS_TIMESTAMP must be a number".to_owned())?
} else {
use std::time::SystemTime;
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("SystemTime before UNIX EPOCH!")
.as_secs()
};
let json_file_path = std::env::var("DUNITER_GENESIS_CONFIG")
.unwrap_or_else(|_| "duniter-gen-conf.json".to_owned());
// We mmap the file into memory first, as this is *a lot* faster than using
// `serde_json::from_reader`. See https://github.com/serde-rs/json/issues/160
let file = std::fs::File::open(&json_file_path)
.map_err(|e| format!("Error opening gen conf file `{}`: {}", json_file_path, e))?;
// SAFETY: `mmap` is fundamentally unsafe since technically the file can change
// underneath us while it is mapped; in practice it's unlikely to be a problem
let bytes = unsafe {
memmap2::Mmap::map(&file)
.map_err(|e| format!("Error mmaping gen conf file `{}`: {}", json_file_path, e))?
};
let genesis_config = serde_json::from_slice(&bytes)
.map_err(|e| format!("Error parsing gen conf file: {}", e))?;
let GenesisConfig { let GenesisConfig {
sudo_key, sudo_key,
first_ud, first_ud,
...@@ -154,12 +133,19 @@ where ...@@ -154,12 +133,19 @@ where
genesis_smith_memberships_expire_on, genesis_smith_memberships_expire_on,
}, },
parameters, parameters,
identities, // identities,
smith_identities, smith_identities,
technical_committee, technical_committee,
ud, ud,
// wallets,
} = get_genesis_config::<P>()?;
let GenesisMigrationData {
identities,
wallets, wallets,
} = genesis_config; } = get_genesis_migration_data()?;
check_parameters_consistency(&wallets, &first_ud, &first_ud_reeval, &ud)?;
// MONEY AND WOT // // MONEY AND WOT //
...@@ -396,6 +382,89 @@ where ...@@ -396,6 +382,89 @@ where
Ok(f(genesis_data)) Ok(f(genesis_data))
} }
fn check_parameters_consistency(
wallets: &BTreeMap<AccountId32, u64>,
first_ud: &Option<u64>,
first_reeval: &Option<u64>,
ud: &u64,
) -> Result<(), String> {
// No empty wallet
if let Some((account, _)) = wallets.iter().find(|(_, amount)| **amount == 0) {
return Err(format!("Wallet {} is empty", account));
}
// TODO: check ud_reeval_period / ud_creation_period (can round to zero)
if first_reeval.is_none() {
return Err("Please provied a value for `first_ud_reeval`".to_owned());
}
if first_ud.is_none() {
return Err("Please provied a value for `first_ud`".to_owned());
}
if first_ud.unwrap() > first_reeval.unwrap() {
return Err(format!(
"`first_ud` ({}) should be lower than `first_ud_reeval` ({})",
first_ud.unwrap(),
first_reeval.unwrap()
)
.to_owned());
}
if *ud == 0 {
return Err("`ud` is expected to be > 0".to_owned());
}
Ok(())
}
fn get_genesis_config<P: Default + DeserializeOwned>() -> Result<GenesisConfig<P>, String> {
let json_file_path = std::env::var("DUNITER_GENESIS_CONFIG")
.unwrap_or_else(|_| "duniter-gen-conf.json".to_owned());
// We mmap the file into memory first, as this is *a lot* faster than using
// `serde_json::from_reader`. See https://github.com/serde-rs/json/issues/160
let file = std::fs::File::open(&json_file_path)
.map_err(|e| format!("Error opening gen conf file `{}`: {}", json_file_path, e))?;
// SAFETY: `mmap` is fundamentally unsafe since technically the file can change
// underneath us while it is mapped; in practice it's unlikely to be a problem
let bytes = unsafe {
memmap2::Mmap::map(&file)
.map_err(|e| format!("Error mmaping gen conf file `{}`: {}", json_file_path, e))?
};
serde_json::from_slice::<GenesisConfig<P>>(&bytes)
.map_err(|e| format!("Error parsing gen conf file: {}", e))
}
fn get_genesis_migration_data() -> Result<GenesisMigrationData, String> {
if let Ok(json_file_path) = std::env::var("DUNITER_GENESIS_MIGRATION") {
let file = std::fs::File::open(&json_file_path)
.map_err(|e| format!("Error opening gen conf file `{}`: {}", json_file_path, e))?;
let bytes = unsafe {
memmap2::Mmap::map(&file)
.map_err(|e| format!("Error mmaping gen conf file `{}`: {}", json_file_path, e))?
};
serde_json::from_slice::<GenesisMigrationData>(&bytes)
.map_err(|e| format!("Error parsing gen conf file: {}", e))
} else {
// No data
Ok(GenesisMigrationData {
wallets: btreemap! {},
identities: btreemap! {},
})
}
}
fn get_genesis_timestamp() -> Result<u64, String> {
if let Ok(genesis_timestamp) = std::env::var("DUNITER_GENESIS_TIMESTAMP") {
genesis_timestamp
.parse()
.map_err(|_| "DUNITER_GENESIS_TIMESTAMP must be a number".to_owned())
} else {
use std::time::SystemTime;
Ok(SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("SystemTime before UNIX EPOCH!")
.as_secs())
}
}
// Timestamp to block number // Timestamp to block number
fn to_bn(genesis_timestamp: u64, timestamp: u64) -> u32 { fn to_bn(genesis_timestamp: u64, timestamp: u64) -> u32 {
let duration_in_secs = timestamp.saturating_sub(genesis_timestamp); let duration_in_secs = timestamp.saturating_sub(genesis_timestamp);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment