Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • nodes/rust/duniter-v2s
  • llaq/lc-core-substrate
  • pini-gh/duniter-v2s
  • vincentux/duniter-v2s
  • mildred/duniter-v2s
  • d0p1/duniter-v2s
  • bgallois/duniter-v2s
  • Nicolas80/duniter-v2s
8 results
Show changes
Showing
with 2512 additions and 517 deletions
......@@ -170,6 +170,6 @@ async fn main() {
DuniterWorld::cucumber()
//.fail_on_skipped()
.max_concurrent_scenarios(4)
.run_and_exit("features")
.run_and_exit("cucumber-features")
.await;
}
[package]
authors = ['Axiom-Team Developers <https://axiom-team.fr>']
build = 'build.rs'
description = 'Crypto-currency software (based on Substrate framework) to operate Ğ1 libre currency'
edition = '2018'
homepage = 'https://substrate.dev'
license = 'AGPL-3.0'
name = 'duniter'
repository = 'https://git.duniter.org/nodes/rust/duniter-v2s'
version = '3.0.0'
[package.metadata.docs.rs]
targets = ['x86_64-unknown-linux-gnu']
[[bin]]
name = 'duniter'
[features]
default = ["gdev", "gtest"]
g1 = ["g1-runtime"]
gdev = ["gdev-runtime"]
gtest = ["gtest-runtime"]
runtime-benchmarks = [
'g1-runtime',
'g1-runtime/runtime-benchmarks',
'gdev-runtime',
'gdev-runtime/runtime-benchmarks',
'gtest-runtime',
'gtest-runtime/runtime-benchmarks',
]
[build-dependencies]
substrate-build-script-utils = { git = 'https://github.com/librelois/substrate.git', branch = 'duniter-monthly-2022-01' }
# substrate dev-dependencies
sp-keyring = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" }
[dependencies]
# local dependencies
common-runtime = { path = '../runtime/common' }
g1-runtime = { path = '../runtime/g1', optional = true }
gdev-runtime = { path = '../runtime/gdev', optional = true }
gtest-runtime = { path = '../runtime/gtest', optional = true }
pallet-certification = { path = '../pallets/certification' }
sp-membership = { path = '../primitives/membership' }
# crates.io dependencies
async-io = "1.3"
futures = { version = "0.3.1", features = ["compat"] }
jsonrpc-core = '18.0.0'
log = "0.4"
maplit = '1.0.2'
serde_json = "1.0.64"
structopt = '0.3.8'
# substrate dependencies
[dependencies.frame-benchmarking]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.frame-benchmarking-cli]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.pallet-grandpa]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.pallet-transaction-payment-rpc]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.pallet-transaction-payment-rpc-runtime-api]
default-features = false
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-basic-authorship]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-chain-spec]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-cli]
features = ['wasmtime']
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-client-api]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-consensus]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.babe]
package = "sc-consensus-babe"
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-consensus-manual-seal]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-consensus-uncles]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-executor]
features = ['wasmtime']
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-finality-grandpa]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-keystore]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-rpc]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-rpc-api]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-service]
features = ['wasmtime']
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-telemetry]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-transaction-pool]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sc-transaction-pool-api]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-api]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-authority-discovery]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-block-builder]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-blockchain]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-consensus]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-consensus-babe]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-core]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-finality-grandpa]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-offchain]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-inherents]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-runtime]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-session]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-storage]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-timestamp]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-transaction-pool]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.sp-trie]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
[dependencies.substrate-frame-rpc-system]
git = 'https://github.com/librelois/substrate.git'
branch = 'duniter-monthly-2022-01'
use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed};
// Copyright 2021 Axiom-Team
//
// This file is part of Substrate-Libre-Currency.
//
// Substrate-Libre-Currency is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// Substrate-Libre-Currency is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
fn main() {
generate_cargo_keys();
//cli::main();
rerun_if_git_head_changed();
substrate_build_script_utils::generate_cargo_keys();
substrate_build_script_utils::rerun_if_git_head_changed();
}
/*
mod cli {
include!("src/cli.rs");
use clap::{ArgEnum, IntoApp};
use clap_complete::{generate_to, Shell};
use std::{env, fs, path::Path};
use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed};
pub fn main() {
build_shell_completion();
generate_cargo_keys();
rerun_if_git_head_changed();
}
/// Build shell completion scripts for all known shells
fn build_shell_completion() {
for shell in Shell::value_variants() {
build_completion(shell);
}
}
/// Build the shell auto-completion for a given Shell
fn build_completion(shell: &Shell) {
let outdir = match env::var_os("OUT_DIR") {
None => return,
Some(dir) => dir,
};
let path = Path::new(&outdir)
.parent()
.unwrap()
.parent()
.unwrap()
.parent()
.unwrap()
.join("completion-scripts");
fs::create_dir(&path).ok();
let _ = generate_to(*shell, &mut Cli::into_app(), "substrate-node", &path);
}
}*/
......@@ -14,6 +14,8 @@
// You should have received a copy of the GNU Affero General Public License
// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
pub mod gen_genesis_data;
#[cfg(feature = "g1")]
pub mod g1;
#[cfg(feature = "gdev")]
......@@ -28,6 +30,8 @@ use std::collections::BTreeMap;
pub type AccountPublic = <Signature as Verify>::Signer;
pub const NAMES: [&str; 6] = ["Alice", "Bob", "Charlie", "Dave", "Eve", "Ferdie"];
/// Generate a crypto pair from seed.
pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
TPublic::Pair::from_string(&format!("//{}", seed), None)
......
......@@ -15,29 +15,48 @@
// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
use super::*;
use common_runtime::entities::IdtyName;
use common_runtime::constants::*;
use common_runtime::*;
use gdev_runtime::{
AccountId, BalancesConfig, GenesisConfig, GrandpaConfig, IdentityConfig, IdtyRight, IdtyValue,
MembershipConfig, StrongCertConfig, SudoConfig, SystemConfig, UdAccountsStorageConfig,
UniversalDividendConfig, WASM_BINARY,
opaque::SessionKeys, AccountConfig, AccountId, AuthorityMembersConfig, BabeConfig,
BalancesConfig, CertConfig, GenesisConfig, IdentityConfig, ImOnlineId, MembershipConfig,
ParametersConfig, SessionConfig, SmithsCertConfig, SmithsMembershipConfig, SudoConfig,
SystemConfig, UdAccountsStorageConfig, UniversalDividendConfig, WASM_BINARY,
};
use maplit::btreemap;
use sc_service::ChainType;
use sp_core::sr25519;
use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
use sp_consensus_babe::AuthorityId as BabeId;
use sp_core::{blake2_256, sr25519, Encode, H256};
use sp_finality_grandpa::AuthorityId as GrandpaId;
use sp_membership::MembershipData;
use std::collections::BTreeMap;
pub type AuthorityKeys = (
AccountId,
BabeId,
GrandpaId,
ImOnlineId,
AuthorityDiscoveryId,
);
pub type ChainSpec = sc_service::GenericChainSpec<GenesisConfig>;
type GenesisParameters = gdev_runtime::GenesisParameters<u32, u32, u64>;
const TOKEN_DECIMALS: usize = 2;
const TOKEN_SYMBOL: &str = "ĞD";
// The URL for the telemetry server.
// const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
/// Generate an authority keys.
pub fn get_authority_keys_from_seed(s: &str) -> GrandpaId {
get_from_seed::<GrandpaId>(s)
pub fn get_authority_keys_from_seed(s: &str) -> AuthorityKeys {
(
get_account_id_from_seed::<sr25519::Public>(s),
get_from_seed::<BabeId>(s),
get_from_seed::<GrandpaId>(s),
get_from_seed::<ImOnlineId>(s),
get_from_seed::<AuthorityDiscoveryId>(s),
)
}
pub fn development_chain_spec() -> Result<ChainSpec, String> {
......@@ -50,16 +69,109 @@ pub fn development_chain_spec() -> Result<ChainSpec, String> {
"gdev",
ChainType::Development,
move || {
devnet_genesis(
gen_genesis_conf(
wasm_binary,
// Initial authorities len
1,
// Initial smiths members len
3,
// Inital identities len
4,
// Sudo account
get_account_id_from_seed::<sr25519::Public>("Alice"),
true,
)
},
// Bootnodes
vec![],
// Telemetry
None,
// Protocol ID
None,
//Fork ID
None,
// Properties
Some(
serde_json::json!({
"tokenDecimals": TOKEN_DECIMALS,
"tokenSymbol": TOKEN_SYMBOL,
})
.as_object()
.expect("must be a map")
.clone(),
),
// Extensions
None,
))
}
pub fn gen_live_conf() -> Result<ChainSpec, String> {
let wasm_binary = WASM_BINARY.ok_or_else(|| "wasm not available".to_string())?;
super::gen_genesis_data::generate_genesis_data(
|genesis_data| {
ChainSpec::from_genesis(
// Name
"Ğdev",
// ID
"gdev",
sc_service::ChainType::Live,
move || genesis_data_to_gdev_genesis_conf(genesis_data.clone(), wasm_binary),
// Bootnodes
vec![],
// Telemetry
None,
// Protocol ID
None,
//Fork ID
None,
// Properties
Some(
serde_json::json!({
"tokenDecimals": TOKEN_DECIMALS,
"tokenSymbol": TOKEN_SYMBOL,
})
.as_object()
.expect("must be a map")
.clone(),
),
// Extensions
None,
)
},
Some(super::gen_genesis_data::ParamsAppliedAtGenesis {
genesis_certs_expire_on: 100_000,
genesis_smith_certs_expire_on: 100_000,
genesis_memberships_expire_on: 100_000,
genesis_memberships_renewable_on: 50,
genesis_smith_memberships_expire_on: 100_000,
genesis_smith_memberships_renewable_on: 50,
}),
)
}
pub fn local_testnet_config(
initial_authorities_len: usize,
initial_smiths_len: usize,
initial_identities_len: usize,
) -> Result<ChainSpec, String> {
let wasm_binary = WASM_BINARY.ok_or_else(|| "wasm not available".to_string())?;
Ok(ChainSpec::from_genesis(
// Name
"Ğdev Local Testnet",
// ID
"gdev_local_testnet",
ChainType::Local,
move || {
gen_genesis_conf(
wasm_binary,
// Initial authorities
vec![get_authority_keys_from_seed("Alice")],
// Inital identities
btreemap![
IdtyName::from("Alice") => get_account_id_from_seed::<sr25519::Public>("Alice"),
IdtyName::from("Bob") => get_account_id_from_seed::<sr25519::Public>("Bob"),
IdtyName::from("Charlie") => get_account_id_from_seed::<sr25519::Public>("Charlie"),
],
// Initial authorities len
initial_authorities_len,
// Initial smiths len,
initial_smiths_len,
// Initial identities len
initial_identities_len,
// Sudo account
get_account_id_from_seed::<sr25519::Public>("Alice"),
true,
......@@ -71,6 +183,8 @@ pub fn development_chain_spec() -> Result<ChainSpec, String> {
None,
// Protocol ID
None,
//Fork ID
None,
// Properties
Some(
serde_json::json!({
......@@ -86,23 +200,122 @@ pub fn development_chain_spec() -> Result<ChainSpec, String> {
))
}
fn devnet_genesis(
fn gen_genesis_conf(
wasm_binary: &[u8],
initial_authorities: Vec<GrandpaId>,
initial_identities: BTreeMap<IdtyName, AccountId>,
initial_authorities_len: usize,
initial_smiths_len: usize,
initial_identities_len: usize,
root_key: AccountId,
_enable_println: bool,
) -> gdev_runtime::GenesisConfig {
assert!(initial_identities_len <= 6);
assert!(initial_smiths_len <= initial_identities_len);
assert!(initial_authorities_len <= initial_smiths_len);
let babe_epoch_duration = get_env_u32("DUNITER_BABE_EPOCH_DURATION", 30) as u64;
let cert_validity_period = get_env_u32("DUNITER_CERT_VALIDITY_PERIOD", 1_000);
let membership_period = get_env_u32("DUNITER_MEMBERSHIP_PERIOD", 1_000);
let membership_renewable_period = get_env_u32("DUNITER_MEMBERSHIP_RENEWABLE_PERIOD", 50);
let smith_cert_validity_period = get_env_u32("DUNITER_SMITH_CERT_VALIDITY_PERIOD", 1_000);
let smith_membership_renewable_period =
get_env_u32("DUNITER_SMITH_MEMBERSHIP_RENEWABLE_PERIOD", 20);
let smith_membership_period = get_env_u32("DUNITER_SMITH_MEMBERSHIP_PERIOD", 1_000);
let ud_reeval_period = get_env_u32("DUNITER_UD_REEEVAL_PERIOD", 20);
let initial_smiths = (0..initial_smiths_len)
.map(|i| get_authority_keys_from_seed(NAMES[i]))
.collect::<Vec<AuthorityKeys>>();
let initial_identities = (0..initial_smiths_len)
.map(|i| {
(
IdtyName::from(NAMES[i]),
get_account_id_from_seed::<sr25519::Public>(NAMES[i]),
)
})
.collect::<BTreeMap<IdtyName, AccountId>>();
gdev_runtime::GenesisConfig {
system: SystemConfig {
// Add Wasm runtime to storage.
code: wasm_binary.to_vec(),
},
account: AccountConfig {
accounts: initial_identities
.iter()
.enumerate()
.map(|(i, (_, owner_key))| {
(
owner_key.clone(),
GenesisAccountData {
random_id: H256(blake2_256(&(i as u32, owner_key).encode())),
balance: 0,
is_identity: true,
},
)
})
.collect(),
},
parameters: ParametersConfig {
parameters: GenesisParameters {
babe_epoch_duration,
cert_period: 15,
cert_max_by_issuer: 10,
cert_min_received_cert_to_issue_cert: 2,
cert_renewable_period: 50,
cert_validity_period,
idty_confirm_period: 40,
idty_creation_period: 50,
idty_max_disabled_period: 1_000,
membership_period,
membership_renewable_period,
pending_membership_period: 500,
ud_creation_period: 10,
ud_first_reeval: 100,
ud_reeval_period: ud_reeval_period as u64,
ud_reeval_period_in_blocks: 10 * ud_reeval_period,
smith_cert_period: 15,
smith_cert_max_by_issuer: 8,
smith_cert_min_received_cert_to_issue_cert: 2,
smith_cert_renewable_period: 50,
smith_cert_validity_period: 1_000,
smith_membership_period,
smith_membership_renewable_period: 50,
smith_pending_membership_period: 500,
smiths_wot_first_cert_issuable_on: 20,
smiths_wot_min_cert_for_membership: 2,
wot_first_cert_issuable_on: 20,
wot_min_cert_for_create_idty_right: 2,
wot_min_cert_for_membership: 2,
},
},
authority_discovery: Default::default(),
authority_members: AuthorityMembersConfig {
initial_authorities: initial_smiths
.iter()
.enumerate()
.map(|(i, keys)| (i as u32 + 1, (keys.0.clone(), i < initial_authorities_len)))
.collect(),
},
balances: BalancesConfig {
balances: Default::default(),
},
grandpa: GrandpaConfig {
authorities: initial_authorities.iter().map(|x| (x.clone(), 1)).collect(),
babe: BabeConfig {
authorities: Vec::with_capacity(0),
epoch_config: Some(BABE_GENESIS_EPOCH_CONFIG),
},
grandpa: Default::default(),
im_online: Default::default(),
session: SessionConfig {
keys: initial_smiths
.iter()
.map(|x| {
(
x.0.clone(),
x.0.clone(),
session_keys(x.1.clone(), x.2.clone(), x.3.clone(), x.4.clone()),
)
})
.collect::<Vec<_>>(),
},
sudo: SudoConfig {
// Assign network admin rights.
......@@ -111,18 +324,16 @@ fn devnet_genesis(
identity: IdentityConfig {
identities: initial_identities
.iter()
.map(|(name, account)| IdtyValue {
data: Default::default(),
owner_key: account.clone(),
.enumerate()
.map(|(i, (name, owner_key))| GenesisIdty {
index: i as u32 + 1,
name: name.clone(),
next_creatable_identity_on: Default::default(),
removable_on: 0,
rights: vec![
(IdtyRight::CreateIdty, None),
(IdtyRight::StrongCert, None),
(IdtyRight::Ud, None),
],
status: gdev_runtime::IdtyStatus::Validated,
value: IdtyValue {
next_creatable_identity_on: Default::default(),
owner_key: owner_key.clone(),
removable_on: 0,
status: IdtyStatus::Validated,
},
})
.collect(),
},
......@@ -132,21 +343,42 @@ fn devnet_genesis(
(
i as u32,
MembershipData {
expire_on: gdev_runtime::MembershipPeriod::get(),
renewable_on: gdev_runtime::RenewablePeriod::get(),
expire_on: membership_period,
renewable_on: membership_renewable_period,
},
)
})
.collect(),
},
strong_cert: StrongCertConfig {
certs_by_issuer: clique_wot(
initial_identities.len(),
gdev_runtime::parameters::ValidityPeriod::get(),
),
cert: CertConfig {
apply_cert_period_at_genesis: false,
certs_by_issuer: clique_wot(initial_identities.len(), cert_validity_period),
},
smiths_membership: SmithsMembershipConfig {
memberships: (1..=initial_smiths_len)
.map(|i| {
(
i as u32,
MembershipData {
expire_on: 0,
renewable_on: smith_membership_renewable_period,
},
)
})
.collect(),
},
smiths_cert: SmithsCertConfig {
apply_cert_period_at_genesis: false,
certs_by_issuer: clique_wot(initial_smiths_len, smith_cert_validity_period),
},
smiths_collective: Default::default(),
ud_accounts_storage: UdAccountsStorageConfig {
ud_accounts: initial_identities.values().cloned().collect(),
ud_accounts: initial_identities
.values()
.cloned()
.enumerate()
.map(|(i, account)| (account, (i + 1) as u32))
.collect(),
},
universal_dividend: UniversalDividendConfig {
first_ud: 1_000,
......@@ -154,3 +386,105 @@ fn devnet_genesis(
},
}
}
fn get_env_u32(env_var_name: &'static str, default_value: u32) -> u32 {
std::env::var(env_var_name)
.map_or(Ok(default_value), |s| s.parse())
.unwrap_or_else(|_| panic!("{} must be a number", env_var_name))
}
fn session_keys(
babe: BabeId,
grandpa: GrandpaId,
im_online: ImOnlineId,
authority_discovery: AuthorityDiscoveryId,
) -> SessionKeys {
SessionKeys {
babe,
grandpa,
im_online,
authority_discovery,
}
}
fn genesis_data_to_gdev_genesis_conf(
genesis_data: super::gen_genesis_data::GenesisData<GenesisParameters, SessionKeys>,
wasm_binary: &[u8],
) -> gdev_runtime::GenesisConfig {
let super::gen_genesis_data::GenesisData {
accounts,
certs_by_issuer,
first_ud,
identities,
initial_authorities,
initial_monetary_mass,
memberships,
parameters,
session_keys_map,
smiths_certs_by_issuer,
smiths_memberships,
sudo_key,
ud_accounts,
} = genesis_data;
gdev_runtime::GenesisConfig {
system: SystemConfig {
// Add Wasm runtime to storage.
code: wasm_binary.to_vec(),
},
account: AccountConfig { accounts },
parameters: ParametersConfig { parameters },
authority_discovery: Default::default(),
authority_members: AuthorityMembersConfig {
initial_authorities,
},
balances: Default::default(),
babe: BabeConfig {
authorities: Vec::with_capacity(0),
epoch_config: Some(common_runtime::constants::BABE_GENESIS_EPOCH_CONFIG),
},
grandpa: Default::default(),
im_online: Default::default(),
session: SessionConfig {
keys: session_keys_map
.into_iter()
.map(|(account_id, session_keys)| (account_id.clone(), account_id, session_keys))
.collect::<Vec<_>>(),
},
sudo: SudoConfig { key: sudo_key },
identity: IdentityConfig {
identities: identities
.into_iter()
.enumerate()
.map(|(i, (name, pubkey))| common_runtime::GenesisIdty {
index: i as u32 + 1,
name: common_runtime::IdtyName::from(name.as_str()),
value: common_runtime::IdtyValue {
next_creatable_identity_on: 0,
owner_key: pubkey,
removable_on: 0,
status: IdtyStatus::Validated,
},
})
.collect(),
},
cert: CertConfig {
apply_cert_period_at_genesis: true,
certs_by_issuer,
},
membership: MembershipConfig { memberships },
smiths_cert: SmithsCertConfig {
apply_cert_period_at_genesis: true,
certs_by_issuer: smiths_certs_by_issuer,
},
smiths_membership: SmithsMembershipConfig {
memberships: smiths_memberships,
},
smiths_collective: Default::default(),
ud_accounts_storage: UdAccountsStorageConfig { ud_accounts },
universal_dividend: UniversalDividendConfig {
first_ud,
initial_monetary_mass,
},
}
}
// Copyright 2021 Axiom-Team
//
// This file is part of Substrate-Libre-Currency.
//
// Substrate-Libre-Currency is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// Substrate-Libre-Currency is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
use common_runtime::*;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use sp_core::{blake2_256, Decode, Encode, H256};
use std::collections::BTreeMap;
type MembershipData = sp_membership::MembershipData<u32>;
#[derive(Clone)]
pub struct GenesisData<Parameters: DeserializeOwned, SessionKeys: Decode> {
pub accounts: BTreeMap<AccountId, GenesisAccountData<u64>>,
pub certs_by_issuer: BTreeMap<u32, BTreeMap<u32, u32>>,
pub first_ud: u64,
pub identities: Vec<(String, AccountId)>,
pub initial_authorities: BTreeMap<u32, (AccountId, bool)>,
pub initial_monetary_mass: u64,
pub memberships: BTreeMap<u32, MembershipData>,
pub parameters: Parameters,
pub session_keys_map: BTreeMap<AccountId, SessionKeys>,
pub smiths_certs_by_issuer: BTreeMap<u32, BTreeMap<u32, u32>>,
pub smiths_memberships: BTreeMap<u32, MembershipData>,
pub sudo_key: Option<AccountId>,
pub ud_accounts: BTreeMap<AccountId, u32>,
}
#[derive(Default)]
pub struct ParamsAppliedAtGenesis {
pub genesis_certs_expire_on: u32,
pub genesis_smith_certs_expire_on: u32,
pub genesis_memberships_expire_on: u32,
pub genesis_memberships_renewable_on: u32,
pub genesis_smith_memberships_expire_on: u32,
pub genesis_smith_memberships_renewable_on: u32,
}
#[derive(Deserialize, Serialize)]
struct GenesisConfig<Parameters> {
first_ud: u64,
identities: BTreeMap<String, Idty>,
#[serde(default)]
parameters: Parameters,
#[serde(rename = "smiths")]
smith_identities: BTreeMap<String, SmithData>,
sudo_key: Option<AccountId>,
}
#[derive(Clone, Deserialize, Serialize)]
struct Idty {
#[serde(default)]
balance: u64,
#[serde(default)]
certs: Vec<String>,
#[serde(rename = "expire_on")]
membership_expire_on: Option<u64>,
pubkey: AccountId,
}
#[derive(Clone, Deserialize, Serialize)]
struct SmithData {
#[serde(default)]
authority: bool,
session_keys: String,
#[serde(default)]
certs: Vec<String>,
}
pub fn generate_genesis_data<CS, P, SK, F>(
f: F,
params_applied_at_genesis: Option<ParamsAppliedAtGenesis>,
) -> Result<CS, String>
where
P: Default + DeserializeOwned,
SK: Decode,
F: Fn(GenesisData<P, SK>) -> CS,
{
let ParamsAppliedAtGenesis {
genesis_certs_expire_on,
genesis_smith_certs_expire_on,
genesis_memberships_expire_on,
genesis_memberships_renewable_on,
genesis_smith_memberships_expire_on,
genesis_smith_memberships_renewable_on,
} = params_applied_at_genesis.unwrap_or_default();
let genesis_timestamp: u64 =
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 {
sudo_key,
first_ud,
parameters,
identities,
smith_identities,
} = genesis_config;
// MONEY AND WOT //
let mut accounts = BTreeMap::new();
let mut identities_ = Vec::with_capacity(identities.len());
let mut idty_index: u32 = 1;
let mut idty_index_of = BTreeMap::new();
let mut initial_monetary_mass = 0;
let mut memberships = BTreeMap::new();
//let mut total_dust = 0;
let mut ud_accounts = BTreeMap::new();
for (idty_name, identity) in &identities {
if !validate_idty_name(idty_name) {
return Err(format!("Identity name '{}' is invalid", &idty_name));
}
// Money
let balance = if identity.balance >= 100 {
identity.balance
} else {
//total_dust += identity.balance;
0
};
accounts.insert(
identity.pubkey.clone(),
GenesisAccountData {
random_id: H256(blake2_256(&(idty_index, &identity.pubkey).encode())),
balance,
is_identity: true,
},
);
// We must count the money under the existential deposit because what we count is
// the monetary mass created (for the revaluation of the DU)
initial_monetary_mass += identity.balance;
ud_accounts.insert(identity.pubkey.clone(), idty_index);
// Wot
identities_.push((idty_name.clone(), identity.pubkey.clone()));
memberships.insert(
idty_index,
MembershipData {
expire_on: identity
.membership_expire_on
.map_or(genesis_memberships_expire_on, |expire_on| {
to_bn(genesis_timestamp, expire_on)
}),
renewable_on: genesis_memberships_renewable_on,
},
);
// Identity index
idty_index_of.insert(idty_name, idty_index);
idty_index += 1;
}
// CERTIFICATIONS //
let mut certs_by_issuer = BTreeMap::new();
for (idty_name, identity) in &identities {
let issuer_index = idty_index_of
.get(&idty_name)
.ok_or(format!("Identity '{}' not exist", &idty_name))?;
let mut issuer_certs = BTreeMap::new();
for receiver in &identity.certs {
let receiver_index = idty_index_of
.get(receiver)
.ok_or(format!("Identity '{}' not exist", receiver))?;
issuer_certs.insert(*receiver_index, genesis_certs_expire_on);
}
certs_by_issuer.insert(*issuer_index, issuer_certs);
}
// SMITHS SUB-WOT //
let mut initial_authorities = BTreeMap::new();
let mut session_keys_map = BTreeMap::new();
let mut smiths_memberships = BTreeMap::new();
let mut smiths_certs_by_issuer = BTreeMap::new();
for (idty_name, smith_data) in smith_identities {
let idty_index = idty_index_of
.get(&idty_name)
.ok_or(format!("Identity '{}' not exist", &idty_name))?;
let identity = identities
.get(&idty_name)
.ok_or(format!("Identity '{}' not exist", &idty_name))?;
// Initial authorities
initial_authorities.insert(*idty_index, (identity.pubkey.clone(), smith_data.authority));
// Session keys
let session_keys_bytes = hex::decode(&smith_data.session_keys[2..])
.map_err(|_| format!("invalid session keys for idty {}", &idty_name))?;
session_keys_map.insert(
identity.pubkey.clone(),
SK::decode(&mut &session_keys_bytes[..])
.map_err(|_| format!("invalid session keys for idty {}", &idty_name))?,
);
// Certifications
let mut issuer_certs = BTreeMap::new();
for receiver in &smith_data.certs {
let receiver_index = idty_index_of
.get(receiver)
.ok_or(format!("Identity '{}' not exist", receiver))?;
issuer_certs.insert(*receiver_index, genesis_smith_certs_expire_on);
}
smiths_certs_by_issuer.insert(*idty_index, issuer_certs);
// Memberships
smiths_memberships.insert(
*idty_index,
MembershipData {
expire_on: genesis_smith_memberships_expire_on,
renewable_on: genesis_smith_memberships_renewable_on,
},
);
}
let genesis_data = GenesisData {
accounts,
certs_by_issuer,
first_ud,
identities: identities_,
initial_authorities,
initial_monetary_mass,
memberships,
parameters,
session_keys_map,
smiths_certs_by_issuer,
smiths_memberships,
sudo_key,
ud_accounts,
};
Ok(f(genesis_data))
}
// Timestamp to block number
fn to_bn(genesis_timestamp: u64, timestamp: u64) -> u32 {
let duration_in_secs = timestamp.saturating_sub(genesis_timestamp);
(duration_in_secs / 6) as u32
}
fn validate_idty_name(name: &str) -> bool {
name.len() <= 64
}
This diff is collapsed.
......@@ -14,29 +14,23 @@
// You should have received a copy of the GNU Affero General Public License
// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
use sc_cli::RunCmd;
use std::str::FromStr;
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
#[derive(Debug, clap::Parser)]
pub struct Cli {
#[structopt(subcommand)]
#[clap(subcommand)]
pub subcommand: Option<Subcommand>,
#[structopt(flatten)]
pub run: RunCmd,
#[clap(flatten)]
pub run: sc_cli::RunCmd,
/// When blocks should be sealed in the dev service.
/// How blocks should be sealed
///
/// Options are "instant", "manual", or timer interval in milliseconds
#[structopt(long, default_value = "6000")]
pub sealing: Sealing,
/// Options are "production", "instant", "manual", or timer interval in milliseconds
#[clap(long, default_value = "production")]
pub sealing: crate::cli::Sealing,
}
#[derive(Debug, StructOpt)]
#[derive(Debug, clap::Subcommand)]
pub enum Subcommand {
/// Key management cli utilities
Key(sc_cli::KeySubcommand),
/// Build a chain specification.
BuildSpec(sc_cli::BuildSpecCmd),
......@@ -49,6 +43,10 @@ pub enum Subcommand {
/// Export the state of a given block into a chain spec.
ExportState(sc_cli::ExportStateCmd),
/// Key management cli utilities
#[clap(subcommand)]
Key(crate::command::key::KeySubcommand),
/// Import blocks.
ImportBlocks(sc_cli::ImportBlocksCmd),
......@@ -58,14 +56,29 @@ pub enum Subcommand {
/// Revert the chain to a previous state.
Revert(sc_cli::RevertCmd),
/// Sign a message, with a given (secret) key.
Sign(sc_cli::SignCmd),
/// Some tools for developers and advanced testers
#[clap(subcommand)]
Utils(crate::command::utils::UtilsSubCommand),
/// Generate a seed that provides a vanity address.
Vanity(sc_cli::VanityCmd),
/// Verify a signature for a message, provided on STDIN, with a given (public or secret) key.
Verify(sc_cli::VerifyCmd),
/// The custom benchmark subcommmand benchmarking runtime pallets.
#[structopt(name = "benchmark", about = "Benchmark runtime pallets.")]
#[clap(name = "benchmark", about = "Benchmark runtime pallets.")]
Benchmark(frame_benchmarking_cli::BenchmarkCmd),
}
/// Block authoring scheme to be used by the dev service.
#[derive(Debug)]
/// Block authoring scheme to be used by the node
#[derive(Clone, Copy, Debug, PartialEq, Eq, clap::ArgEnum)]
pub enum Sealing {
/// Author a block using normal runtime behavior (mandatory for production networks)
Production,
/// Author a block immediately upon receiving a transaction into the transaction pool
Instant,
/// Author a block upon receiving an RPC command
......@@ -74,11 +87,18 @@ pub enum Sealing {
Interval(u64),
}
impl FromStr for Sealing {
impl Sealing {
pub fn is_manual_consensus(self) -> bool {
self != Self::Production
}
}
impl std::str::FromStr for Sealing {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"production" => Self::Production,
"instant" => Self::Instant,
"manual" => Self::Manual,
s => {
......
This diff is collapsed.
This diff is collapsed.
// Copyright 2021 Axiom-Team
//
// This file is part of Substrate-Libre-Currency.
//
// Substrate-Libre-Currency is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// Substrate-Libre-Currency is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
use sc_cli::{Error, SubstrateCli};
use sp_io::hashing::twox_128;
#[derive(Debug, clap::Subcommand)]
pub enum UtilsSubCommand {
/// Compute the raw storage key prefix
StorageKeyPrefix(StorageKeyPrefixCmd),
}
impl UtilsSubCommand {
/// Run the command
pub fn run<C: SubstrateCli>(&self, cli: &C) -> Result<(), Error> {
match self {
Self::StorageKeyPrefix(cmd) => cmd.run(cli),
}
}
}
#[derive(Debug, clap::Parser)]
pub struct StorageKeyPrefixCmd {
/// Pallet name
#[clap(short = 'p', long)]
pallet_name: Option<String>,
/// Storage item name
#[clap(short = 'i', long)]
item_name: Option<String>,
}
impl StorageKeyPrefixCmd {
/// Run the command
pub fn run<C: SubstrateCli>(&self, _cli: &C) -> Result<(), Error> {
let mut key_prefix = Vec::new();
let mut print_key_prefix = false;
if let Some(ref pallet_name) = self.pallet_name {
print_key_prefix = true;
let pallet_prefix = twox_128(pallet_name.as_bytes());
println!("Pallet prefix: 0x{}", hex::encode(&pallet_prefix));
key_prefix.extend_from_slice(&pallet_prefix[..]);
}
if let Some(ref item_name) = self.item_name {
let item_prefix = twox_128(item_name.as_bytes());
println!("Item prefix: 0x{}", hex::encode(item_prefix));
key_prefix.extend_from_slice(&item_prefix[..]);
}
if print_key_prefix {
println!("Key prefix: 0x{}", hex::encode(key_prefix));
}
Ok(())
}
}
......@@ -16,5 +16,6 @@
pub mod chain_spec;
pub mod cli;
pub mod command;
pub mod rpc;
pub mod service;
......@@ -14,7 +14,8 @@
// You should have received a copy of the GNU Affero General Public License
// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
//! duniter CLI library.
//! Duniter Node CLI.
#![warn(missing_docs)]
mod chain_spec;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.