diff --git a/deps/concordium-rust-sdk b/deps/concordium-rust-sdk index 1e983721..3cb3ff08 160000 --- a/deps/concordium-rust-sdk +++ b/deps/concordium-rust-sdk @@ -1 +1 @@ -Subproject commit 1e983721de4472ca85345c895dac3e3135cf687b +Subproject commit 3cb3ff0833d4c309a6fccdf32f2717611c65e1c9 diff --git a/genesis-creator/CHANGELOG.md b/genesis-creator/CHANGELOG.md index bdf5a6ff..76ffc59d 100644 --- a/genesis-creator/CHANGELOG.md +++ b/genesis-creator/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.0 + +- Support genesis data format of protocol version 8. + ## 0.3.0 - Support genesis data format of protocol version 7. diff --git a/genesis-creator/Cargo.lock b/genesis-creator/Cargo.lock index 61bec585..f2977aa0 100644 --- a/genesis-creator/Cargo.lock +++ b/genesis-creator/Cargo.lock @@ -1080,7 +1080,7 @@ dependencies = [ [[package]] name = "genesis-creator" -version = "0.3.0" +version = "0.4.0" dependencies = [ "anyhow", "chrono", diff --git a/genesis-creator/Cargo.toml b/genesis-creator/Cargo.toml index 7037eb95..fbd48188 100644 --- a/genesis-creator/Cargo.toml +++ b/genesis-creator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "genesis-creator" -version = "0.3.0" +version = "0.4.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/genesis-creator/README.md b/genesis-creator/README.md index 9c3107bb..accf5d9d 100644 --- a/genesis-creator/README.md +++ b/genesis-creator/README.md @@ -408,9 +408,9 @@ transactionFeeDistribution = { baker = 0.45, gasAccount = 0.45 } gASRewards = { baker = 0.25, finalizationProof = 0.005, accountCreation = 0.02, chainUpdate = 0.005 } ``` -#### Protocol version 6 +#### Protocol version 6 and 7 -Protocol version 6 parameters are provided in the following form: +Protocol version 6 and 7 parameters are provided in the following form: ```toml [parameters] @@ -461,6 +461,14 @@ gASRewards = { baker = 0.25, accountCreation = 0.02, chainUpdate = 0.005 } ``` where the concrete values above are replaced with those desired. +#### Protocol version 8 + +Protocol version 8 parameters extend the version 6/7 parameters with one additional parameter: + +```toml +[parameters.chain.validatorScoreParameters] +maxMissedRounds = 10 +``` ## The `assemble` mode To generate a genesis from existing file, run diff --git a/genesis-creator/examples/genesis8.toml b/genesis-creator/examples/genesis8.toml new file mode 100644 index 00000000..7528aa0e --- /dev/null +++ b/genesis-creator/examples/genesis8.toml @@ -0,0 +1,124 @@ +# An example genesis configuration file to construct a protocol 8 genesis. +# This creates a genesis with +# - 5 bakers +# - one additional foundation account +# - genesis time set to the time when the tool runs +# - minimum block time set to 1s + +protocolVersion = "8" + +[out] +updateKeys = "./update-keys" +accountKeys = "./accounts" +bakerKeys = "./bakers" +identityProviders = "./idps" +anonymityRevokers = "./ars" +genesis = "./genesis.dat" +cryptographicParameters = "./global" +deleteExisting = true +genesisHash = "./genesis_hash" + +[cryptographicParameters] +kind = "generate" +genesisString = "Test genesis parameters." + +[[anonymityRevokers]] +kind = "fresh" +id = 1 +repeat = 3 + +[[identityProviders]] +kind = "fresh" +id = 0 +repeat = 3 + +[[accounts]] +kind = "fresh" +balance = "1000000000000000" +stake = "500000000000000" +template = "baker" +identityProvider = 0 +numKeys = 1 +threshold = 1 +repeat = 5 + +[[accounts]] +kind = "fresh" +balance = "1000000000000000" +template = "foundation" +identityProvider = 0 +numKeys = 1 +threshold = 1 +repeat = 1 +foundation = true + +[updates] +root = { threshold = 5, keys = [{kind = "fresh", repeat = 7}]} +level1 = { threshold = 7, keys = [{kind = "fresh", repeat = 15}]} + +[updates.level2] +keys = [{kind = "fresh", repeat = 15}] +emergency = {authorizedKeys = [0,1,2,3,4,5,6], threshold = 7} +protocol = {authorizedKeys = [0,1,2,3,4,5,6], threshold = 7} +electionDifficulty = {authorizedKeys = [0,1,2,3,4,5,6], threshold = 7} +euroPerEnergy = {authorizedKeys = [0,1,2,3,4,5,6], threshold = 7} +microCCDPerEuro = {authorizedKeys = [0,1,2,3,4,5,6], threshold = 7} +foundationAccount = {authorizedKeys = [0,1,2,3,4,5,6], threshold = 7} +mintDistribution = {authorizedKeys = [0,1,2,3,4,5,6], threshold = 7} +transactionFeeDistribution = {authorizedKeys = [0,1,2,3,4,5,6], threshold = 7} +gasRewards = {authorizedKeys = [0,1,2,3,4,5,6], threshold = 7} +poolParameters = {authorizedKeys = [0,1,2,3,4,5,6], threshold = 7} +addAnonymityRevoker = {authorizedKeys = [0,1,2,3,4,5,6], threshold = 7} +addIdentityProvider = {authorizedKeys = [0,1,2,3,4,5,6], threshold = 7} +cooldownParameters = {authorizedKeys = [0,1,2,3,4,5,6], threshold = 7} +timeParameters = {authorizedKeys = [0,1,2,3,4,5,6], threshold = 7} + +[parameters] +# genesisTime = "2022-06-24T11:12:43Z" # Falls back to use the current time for genesis time. +leadershipElectionNonce = "d1bc8d3ba4afc7e109612cb73acbdddac052c93025aa1f82942edabb7deb82a1" +epochDuration = "1h" # Meaning 1 hour. +signatureThreshold = {numerator = 2, denominator = 3} # Must be between 2/3 and 1. + +[parameters.chain] +minBlockTime = "1s" # Meaning 1 second. +blockEnergyLimit = 3_000_000 +euroPerEnergy = 0.00002 +microCCDPerEuro = 500_000 +accountCreationLimit = 10 + +[parameters.chain.timeoutParameters] +base = "2s" # Meaning 2 seconds +increase = 1.25 # Must be greater than 1. +decrease = 0.8 # Must be between 0 and 1. + +[parameters.chain.finalizationCommitteeParameters] +minFinalizers = 4 +maxFinalizers = 12 +finalizersRelativeStakeThreshold = 200 # parts per hundred thousand (n / 100000). + +[parameters.chain.timeParameters] +rewardPeriodLength = 4 # 4 epochs +mintPerPayday = 2.61157877e-4 + +[parameters.chain.poolParameters] +passiveFinalizationCommission = 1.0 +passiveBakingCommission = 0.12 +passiveTransactionCommission = 0.12 +finalizationCommissionRange = {max = 1.0, min = 1.0} +bakingCommissionRange = {max = 0.1, min = 0.1} +transactionCommissionRange = {max = 0.1, min = 0.1} +minimumEquityCapital = "1000" +capitalBound = 0.1 +leverageBound = {denominator = 1, numerator = 3} + +[parameters.chain.cooldownParameters] +poolOwnerCooldown = 800 # in seconds +delegatorCooldown = 1000 # in seconds + +[parameters.chain.rewardParameters] +mintDistribution = { bakingReward = 0.85, finalizationReward = 0.05 } +transactionFeeDistribution = { baker = 0.45, gasAccount = 0.45 } +gASRewards = { baker = 0.25, accountCreation = 0.02, chainUpdate = 0.005 } + +[parameters.chain.validatorScoreParameters] +maxMissedRounds = 10 \ No newline at end of file diff --git a/genesis-creator/src/config.rs b/genesis-creator/src/config.rs index e99c0b82..a909a641 100644 --- a/genesis-creator/src/config.rs +++ b/genesis-creator/src/config.rs @@ -1,5 +1,8 @@ //! Input configuration structures and parsing. -use crate::genesis::{GenesisParametersConfigV0, GenesisParametersConfigV1}; +use crate::{ + genesis::{GenesisParametersConfigV0, GenesisParametersConfigV1}, + GenesisParametersConfigV2, +}; use anyhow::ensure; use concordium_rust_sdk::{ @@ -254,6 +257,10 @@ pub enum ProtocolConfig { P7 { parameters: GenesisParametersConfigV1, }, + #[serde(rename = "8")] + P8 { + parameters: GenesisParametersConfigV2, + }, } impl ProtocolConfig { @@ -266,6 +273,7 @@ impl ProtocolConfig { ProtocolConfig::P5 { .. } => ProtocolVersion::P5, ProtocolConfig::P6 { .. } => ProtocolVersion::P6, ProtocolConfig::P7 { .. } => ProtocolVersion::P7, + ProtocolConfig::P8 { .. } => ProtocolVersion::P8, } } } diff --git a/genesis-creator/src/genesis.rs b/genesis-creator/src/genesis.rs index 1042f059..81afa4aa 100644 --- a/genesis-creator/src/genesis.rs +++ b/genesis-creator/src/genesis.rs @@ -5,8 +5,8 @@ use concordium_rust_sdk::{ types::{Amount, CredentialIndex, Ratio, Timestamp}, Buffer, SerdeDeserialize, SerdeSerialize, Serial, Serialize, Versioned, }, - id, id::{ + self, constants::{ArCurve, IpPairing}, types::{ AccCredentialInfo, AccountAddress, AccountCredentialWithoutProofs, AccountKeys, @@ -18,10 +18,11 @@ use concordium_rust_sdk::{ hashes::{BlockHash, LeadershipElectionNonce}, AccountIndex, AccountThreshold, BakerAggregationVerifyKey, BakerElectionVerifyKey, BakerId, BakerSignatureVerifyKey, BlockHeight, ChainParameterVersion0, ChainParameterVersion1, - ChainParameterVersion2, ChainParameters, ChainParametersV0, ChainParametersV1, - ChainParametersV2, CooldownParameters, ElectionDifficulty, Energy, Epoch, ExchangeRate, - PartsPerHundredThousands, PoolParameters, ProtocolVersion, RewardParameters, Slot, - SlotDuration, TimeParameters, TimeoutParameters, UpdateKeysCollection, + ChainParameterVersion2, ChainParameterVersion3, ChainParameters, ChainParametersV0, + ChainParametersV1, ChainParametersV2, ChainParametersV3, CooldownParameters, + ElectionDifficulty, Energy, Epoch, ExchangeRate, PartsPerHundredThousands, PoolParameters, + ProtocolVersion, RewardParameters, Slot, SlotDuration, TimeParameters, TimeoutParameters, + UpdateKeysCollection, ValidatorScoreParameters, }, }; use serde::de; @@ -243,6 +244,51 @@ impl GenesisChainParametersV2 { } } +/// Genesis chain parameters version 3. +#[derive(SerdeDeserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct GenesisChainParametersV3 { + /// Consensus protocol version 2 timeout parameters. + pub timeout_parameters: TimeoutParameters, + /// Minimum time interval between blocks. + pub min_block_time: Duration, + /// Maximum energy allowed per block. + pub block_energy_limit: Energy, + pub euro_per_energy: ExchangeRate, + #[serde(rename = "microCCDPerEuro")] + pub micro_ccd_per_euro: ExchangeRate, + pub account_creation_limit: u16, + pub reward_parameters: RewardParameters, + pub time_parameters: TimeParameters, + pub pool_parameters: PoolParameters, + pub cooldown_parameters: CooldownParameters, + pub finalization_committee_parameters: FinalizationCommitteeParametersConfig, + pub validator_score_parameters: ValidatorScoreParameters, +} + +impl GenesisChainParametersV3 { + pub fn chain_parameters( + self, + foundation_account_index: AccountIndex, + ) -> anyhow::Result { + Ok(ChainParametersV3 { + timeout_parameters: self.timeout_parameters, + min_block_time: self.min_block_time, + block_energy_limit: self.block_energy_limit, + euro_per_energy: self.euro_per_energy, + micro_ccd_per_euro: self.micro_ccd_per_euro, + time_parameters: self.time_parameters, + pool_parameters: self.pool_parameters, + cooldown_parameters: self.cooldown_parameters, + account_creation_limit: self.account_creation_limit.into(), + reward_parameters: self.reward_parameters, + foundation_account_index, + finalization_committee_parameters: self.finalization_committee_parameters.try_into()?, + validator_score_parameters: self.validator_score_parameters, + }) + } +} + #[derive(SerdeDeserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct FinalizationCommitteeParametersConfig { @@ -370,6 +416,20 @@ pub struct GenesisParametersConfigV1 { pub chain: GenesisChainParametersV2, } +/// The core genesis parameters, the leadership election nonce and the chain +/// parameters (except the foundation account index). +/// +/// Used to derive parsing for the genesis parameter section of the TOML config. +#[derive(SerdeDeserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct GenesisParametersConfigV2 { + /// Leadership election nonce. + pub leadership_election_nonce: LeadershipElectionNonce, + #[serde(flatten)] + pub core: CoreGenesisParametersConfigV1, + pub chain: GenesisChainParametersV3, +} + /// The core genesis parameters. This corresponds to the Haskell type in /// haskell-src/Concordium/Genesis/Data/BaseV1.hs in concordium-base. #[derive(Debug, SerdeDeserialize)] @@ -533,8 +593,8 @@ impl Serial for GenesisStateCPV1 { /// The genesis state in chain parameters version 2. This corresponds to the /// Haskell type `GenesisState` from haskell-src/Concordium/Genesis/Data/Base.hs -/// for those protocol versions having chain parameters version 2, currently -/// only P6. +/// for those protocol versions having chain parameters version 2, i.e. P6 and +/// P7. #[derive(Debug)] pub struct GenesisStateCPV2 { pub cryptographic_parameters: GlobalContext, @@ -567,6 +627,41 @@ impl Serial for GenesisStateCPV2 { } } +/// The genesis state in chain parameters version 3. This corresponds to the +/// Haskell type `GenesisState` from haskell-src/Concordium/Genesis/Data/Base.hs +/// for those protocol versions having chain parameters version 3, i.e. P8. +#[derive(Debug)] +pub struct GenesisStateCPV3 { + pub cryptographic_parameters: GlobalContext, + pub identity_providers: BTreeMap>, + pub anonymity_revokers: BTreeMap>, + pub update_keys: UpdateKeysCollection, + pub chain_parameters: ChainParameters, + pub leadership_election_nonce: LeadershipElectionNonce, + pub accounts: Vec, +} + +impl Serial for GenesisStateCPV3 { + fn serial(&self, out: &mut B) { + let mut tmp = Vec::new(); + serialize_with_length_header(&self.cryptographic_parameters, &mut tmp, out); + (self.identity_providers.len() as u32).serial(out); + for (k, v) in self.identity_providers.iter() { + k.serial(out); + serialize_with_length_header(v, &mut tmp, out); + } + (self.anonymity_revokers.len() as u32).serial(out); + for (k, v) in self.anonymity_revokers.iter() { + k.serial(out); + serialize_with_length_header(v, &mut tmp, out); + } + self.update_keys.serial(out); + self.chain_parameters.serial(out); + self.leadership_election_nonce.serial(out); + self.accounts.serial(out) + } +} + /// The genesis data containing the core genesis parameters and the initial /// genesis state. pub enum GenesisData { @@ -598,6 +693,10 @@ pub enum GenesisData { core: CoreGenesisParametersV1, initial_state: GenesisStateCPV2, }, + P8 { + core: CoreGenesisParametersV1, + initial_state: GenesisStateCPV3, + }, } impl GenesisData { @@ -675,6 +774,16 @@ impl GenesisData { core.serial(&mut hasher); initial_state.serial(&mut hasher); } + GenesisData::P8 { + core, + initial_state, + } => { + ProtocolVersion::P8.serial(&mut hasher); + // tag of initial genesis + 0u8.serial(&mut hasher); + core.serial(&mut hasher); + initial_state.serial(&mut hasher); + } } let bytes: [u8; 32] = hasher.finalize().into(); bytes.into() @@ -703,6 +812,7 @@ pub fn make_genesis_data_cpv0( ProtocolVersion::P5 => None, ProtocolVersion::P6 => None, ProtocolVersion::P7 => None, + ProtocolVersion::P8 => None, } } @@ -780,6 +890,16 @@ impl Serial for GenesisData { core.serial(out); initial_state.serial(out) } + GenesisData::P8 { + core, + initial_state, + } => { + 10u8.serial(out); + // tag of initial genesis + 0u8.serial(out); + core.serial(out); + initial_state.serial(out) + } } } } diff --git a/genesis-creator/src/lib.rs b/genesis-creator/src/lib.rs index 8f7ea13f..56ca2a02 100644 --- a/genesis-creator/src/lib.rs +++ b/genesis-creator/src/lib.rs @@ -994,6 +994,24 @@ pub fn handle_assemble(config_path: &Path, verbose: bool) -> anyhow::Result<()> _ => unreachable!("Already checked."), } } + ProtocolConfig::P8 { parameters } => { + let update_keys = read_json(&make_relative(config_path, &config.governance_keys)?)?; + + let initial_state = GenesisStateCPV3 { + cryptographic_parameters: global.value, + identity_providers: idps.value, + anonymity_revokers: ars.value, + update_keys, + chain_parameters: parameters.chain.chain_parameters(AccountIndex::from(idx))?, + leadership_election_nonce: parameters.leadership_election_nonce, + accounts, + }; + let core = parameters.core.try_into()?; + GenesisData::P8 { + core, + initial_state, + } + } }; write_genesis( @@ -1220,6 +1238,24 @@ pub fn handle_generate(config_path: &Path, verbose: bool) -> anyhow::Result<()> _ => unreachable!("Already checked."), } } + ProtocolConfig::P8 { parameters } => { + let update_keys = updates_v1(config.out.update_keys, config.updates)?; + + let initial_state = GenesisStateCPV3 { + cryptographic_parameters, + identity_providers, + anonymity_revokers, + update_keys, + chain_parameters: parameters.chain.chain_parameters(foundation_idx)?, + leadership_election_nonce: parameters.leadership_election_nonce, + accounts, + }; + let core = parameters.core.try_into()?; + GenesisData::P8 { + core, + initial_state, + } + } }; write_genesis( config.out.genesis.as_path(),