diff --git a/sdk/src/types/block/mana/mod.rs b/sdk/src/types/block/mana/mod.rs index 1c3007aec1..80320ac623 100644 --- a/sdk/src/types/block/mana/mod.rs +++ b/sdk/src/types/block/mana/mod.rs @@ -2,7 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 mod allotment; -mod protocol; +mod rewards; +mod structure; use alloc::{boxed::Box, collections::BTreeSet, vec::Vec}; use core::ops::RangeInclusive; @@ -13,7 +14,7 @@ use packable::{bounded::BoundedU16, prefix::BoxedSlicePrefix, Packable}; #[cfg(feature = "serde")] pub use self::allotment::dto::ManaAllotmentDto; -pub use self::{allotment::ManaAllotment, protocol::ManaStructure}; +pub use self::{allotment::ManaAllotment, rewards::RewardsParameters, structure::ManaStructure}; use super::{output::AccountId, protocol::ProtocolParameters, Error}; pub(crate) type ManaAllotmentCount = diff --git a/sdk/src/types/block/mana/rewards.rs b/sdk/src/types/block/mana/rewards.rs new file mode 100644 index 0000000000..ae87db2ec6 --- /dev/null +++ b/sdk/src/types/block/mana/rewards.rs @@ -0,0 +1,49 @@ +// Copyright 2023 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use getset::CopyGetters; +use packable::Packable; + +use crate::types::block::{slot::EpochIndex, Error}; + +#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Packable, CopyGetters)] +#[cfg_attr( + feature = "serde", + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "camelCase") +)] +#[packable(unpack_error = Error)] +#[getset(get_copy = "pub")] +pub struct RewardsParameters { + /// The number of validation blocks that should be issued by a selected validator per slot during its epoch duties. + validator_blocks_per_slot: u8, + /// Used for shift operation during calculation of profit margin. + profit_margin_exponent: u8, + /// The length of the bootstrapping phase in epochs. + bootstrapping_duration: EpochIndex, + /// The coefficient used for calculation of initial rewards. + #[cfg_attr(feature = "serde", serde(with = "crate::utils::serde::string"))] + mana_share_coefficient: u64, + /// The exponent used for calculation of the initial reward. + decay_balancing_constant_exponent: u8, + /// An integer approximation which is calculated using the `decay_balancing_constant_exponent`. + #[cfg_attr(feature = "serde", serde(with = "crate::utils::serde::string"))] + decay_balancing_constant: u64, + /// The exponent used for shifting operation during the pool rewards calculations. + pool_coefficient_exponent: u8, +} + +impl Default for RewardsParameters { + fn default() -> Self { + // TODO: use actual values + Self { + validator_blocks_per_slot: Default::default(), + profit_margin_exponent: Default::default(), + bootstrapping_duration: Default::default(), + mana_share_coefficient: Default::default(), + decay_balancing_constant_exponent: Default::default(), + decay_balancing_constant: Default::default(), + pool_coefficient_exponent: Default::default(), + } + } +} diff --git a/sdk/src/types/block/mana/protocol.rs b/sdk/src/types/block/mana/structure.rs similarity index 100% rename from sdk/src/types/block/mana/protocol.rs rename to sdk/src/types/block/mana/structure.rs diff --git a/sdk/src/types/block/protocol.rs b/sdk/src/types/block/protocol.rs index 5a972efb30..32d882a839 100644 --- a/sdk/src/types/block/protocol.rs +++ b/sdk/src/types/block/protocol.rs @@ -10,7 +10,7 @@ use packable::{prefix::StringPrefix, Packable, PackableExt}; use super::{ address::Hrp, - mana::ManaStructure, + mana::{ManaStructure, RewardsParameters}, slot::{EpochIndex, SlotIndex}, }; use crate::types::block::{helper::network_name_to_id, output::RentStructure, ConvertTo, Error, PROTOCOL_VERSION}; @@ -76,6 +76,8 @@ pub struct ProtocolParameters { pub(crate) congestion_control_parameters: CongestionControlParameters, /// Defines the parameters used to signal a protocol parameters upgrade. pub(crate) version_signaling: VersionSignalingParameters, + /// Defines the parameters used for reward calculation. + pub(crate) rewards_parameters: RewardsParameters, } // This implementation is required to make [`ProtocolParameters`] a [`Packable`] visitor. @@ -109,6 +111,7 @@ impl Default for ProtocolParameters { max_committable_age: 20.into(), congestion_control_parameters: Default::default(), version_signaling: Default::default(), + rewards_parameters: Default::default(), } } } diff --git a/sdk/src/types/block/slot/epoch.rs b/sdk/src/types/block/slot/epoch.rs index e6afa3bd54..0e47f94f78 100644 --- a/sdk/src/types/block/slot/epoch.rs +++ b/sdk/src/types/block/slot/epoch.rs @@ -32,7 +32,7 @@ use crate::types::block::Error; /// | 2 | 16 | 24 | // ... #[derive( - Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, From, Deref, Display, FromStr, packable::Packable, + Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash, From, Deref, Display, FromStr, packable::Packable, )] #[repr(transparent)] pub struct EpochIndex(u64); diff --git a/sdk/tests/types/protocol.rs b/sdk/tests/types/protocol.rs index f7df7919c0..1034190026 100644 --- a/sdk/tests/types/protocol.rs +++ b/sdk/tests/types/protocol.rs @@ -11,54 +11,54 @@ fn params_serde_hash() { { "type":0, "version":3, - "networkName":"xxxNetwork", - "bech32Hrp":"xxx", - "rentStructure": { - "vByteCost":6, - "vByteFactorData":7, - "vByteFactorKey":8, - "vByteFactorBlockIssuerKey":9, - "vByteFactorStakingFeature":10, - "vByteFactorDelegation":10 + "networkName":"TestJungle", + "bech32Hrp":"tgl", + "rentStructure":{ + "vByteCost":0, + "vByteFactorData":0, + "vByteFactorKey":0, + "vByteFactorBlockIssuerKey":0, + "vByteFactorStakingFeature":0, + "vByteFactorDelegation":0 }, "workScoreStructure":{ - "dataByte":1, - "block":2, - "missingParent":3, - "input":4, - "contextInput":5, - "output":6, - "nativeToken":7, - "staking":8, - "blockIssuer":9, - "allotment":10, - "signatureEd25519":11, - "minStrongParentsThreshold":12 + "dataByte":0, + "block":1, + "missingParent":0, + "input":0, + "contextInput":0, + "output":0, + "nativeToken":0, + "staking":0, + "blockIssuer":0, + "allotment":0, + "signatureEd25519":0, + "minStrongParentsThreshold":0 }, - "tokenSupply":"1234567890987654321", - "genesisUnixTimestamp":"1681373293", + "tokenSupply":"2779530283277761", + "genesisUnixTimestamp":"1695275822", "slotDurationInSeconds":10, "slotsPerEpochExponent":13, - "manaStructure": { - "bitsCount":1, + "manaStructure":{ + "bitsCount":63, "generationRate":1, - "generationRateExponent":27, + "generationRateExponent":17, "decayFactors":[10,20], "decayFactorsExponent":32, - "decayFactorEpochsSum":1337, - "decayFactorEpochsSumExponent":20 + "decayFactorEpochsSum":2420916375u32, + "decayFactorEpochsSumExponent":21 }, - "stakingUnbondingPeriod":"11", + "stakingUnbondingPeriod":"10", "validationBlocksPerSlot":10, - "punishmentEpochs":"9", + "punishmentEpochs":"10", "livenessThreshold":"3", "minCommittableAge":"10", "maxCommittableAge":"20", "epochNearingThreshold":"24", - "congestionControlParameters": { - "minReferenceManaCost":"500", - "increase":"500", - "decrease":"500", + "congestionControlParameters":{ + "minReferenceManaCost":"1", + "increase":"0", + "decrease":"0", "increaseThreshold":800000, "decreaseThreshold":500000, "schedulerRate":100000, @@ -66,10 +66,19 @@ fn params_serde_hash() { "maxBufferSize":1000, "maxValidationBufferSize":100 }, - "versionSignaling": { - "windowSize":3, - "windowTargetRatio":4, - "activationOffset":1 + "versionSignaling":{ + "windowSize":7, + "windowTargetRatio":5, + "activationOffset":7 + }, + "rewardsParameters":{ + "validatorBlocksPerSlot":10, + "profitMarginExponent":8, + "bootstrappingDuration":"1154", + "manaShareCoefficient":"2", + "decayBalancingConstantExponent":8, + "decayBalancingConstant":"1", + "poolCoefficientExponent":31 } } ); @@ -79,13 +88,14 @@ fn params_serde_hash() { assert_eq!( protocol_params_bytes, [ - 0, 3, 10, 120, 120, 120, 78, 101, 116, 119, 111, 114, 107, 3, 120, 120, 120, 6, 0, 0, 0, 7, 8, 9, 10, 10, - 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, - 10, 0, 0, 0, 11, 0, 0, 0, 12, 177, 28, 108, 177, 244, 16, 34, 17, 109, 184, 55, 100, 0, 0, 0, 0, 10, 13, 1, - 1, 27, 2, 0, 10, 0, 0, 0, 20, 0, 0, 0, 32, 57, 5, 0, 0, 20, 11, 0, 0, 0, 0, 0, 0, 0, 10, 0, 9, 0, 0, 0, 0, + 0, 3, 10, 84, 101, 115, 116, 74, 117, 110, 103, 108, 101, 3, 116, 103, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 193, 93, 45, 211, 247, 223, 9, 0, 46, 219, 11, 101, 0, 0, 0, 0, 10, 13, 63, 1, 17, + 2, 0, 10, 0, 0, 0, 20, 0, 0, 0, 32, 151, 64, 76, 144, 21, 10, 0, 0, 0, 0, 0, 0, 0, 10, 0, 10, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, - 244, 1, 0, 0, 0, 0, 0, 0, 244, 1, 0, 0, 0, 0, 0, 0, 244, 1, 0, 0, 0, 0, 0, 0, 0, 53, 12, 0, 32, 161, 7, 0, - 160, 134, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 232, 3, 0, 0, 100, 0, 0, 0, 3, 4, 1 + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 12, 0, 32, 161, 7, 0, 160, + 134, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 232, 3, 0, 0, 100, 0, 0, 0, 7, 5, 7, 10, 8, 130, 4, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 0, 0, 0, 31 ] ); @@ -93,6 +103,6 @@ fn params_serde_hash() { assert_eq!( hash.to_string(), - "0x9d3e39699e38db1d6e6777a40f82b1b5030e645cffb08dba3a157105bd6bfac8" + "0xc82143973a4a4c93dce9fe99d26d4cdc68d44b7688abcbdf6ba8ab405de2b63b" ); }