Skip to content

Commit fd63c03

Browse files
authored
Merge pull request #1213 from input-output-hk/allow-setting-treasury
Allow setting treasury in the genesis file
2 parents 190c37e + b2a2616 commit fd63c03

File tree

4 files changed

+159
-9
lines changed

4 files changed

+159
-9
lines changed

jormungandr-lib/src/interfaces/block0_configuration/DOCUMENTED_EXAMPLE.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,27 @@ blockchain_configuration:
8282
# default value: {default_kes_update_speed}
8383
kes_update_speed: {default_kes_update_speed}
8484

85+
# initial value the treasury will start with, if not set the treasury
86+
# starts at 0
87+
treasury: 1000000000000
88+
89+
# set the treasury parameters, this is the tax type, just as in stake pool
90+
# registration certificate parameters.
91+
#
92+
# When distributing the rewards, the treasury will be first serve as per
93+
# the incentive specification document
94+
#
95+
# if not set, the treasury will not grow
96+
treasury_parameters:
97+
# the fix value the treasury will take from the total reward pot of the epoch
98+
fixed: 1000
99+
# the extra percentage the the treasury will take from the reward pot of the epoch
100+
ratio: "1/10"
101+
# It is possible to add a max bound to the total value the treasury takes
102+
# at each reward distribution. For example, one could cap the treasury tax
103+
# to 10000. Uncomment the following line to apply a max limit:
104+
# max_limit: 10000
105+
85106
# Initial state of the ledger. Each item is applied in order of this list
86107
initial:
87108
# Initial deposits present in the blockchain

jormungandr-lib/src/interfaces/block0_configuration/initial_config.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
interfaces::{
33
ActiveSlotCoefficient, BFTSlotsRatio, ConsensusLeaderId, KESUpdateSpeed, LinearFeeDef,
4-
NumberOfSlotsPerEpoch, SlotDuration,
4+
NumberOfSlotsPerEpoch, SlotDuration, TaxType, Value,
55
},
66
time::SecondsSinceUnixEpoch,
77
};
@@ -11,7 +11,6 @@ use chain_impl_mockchain::{
1111
config::{Block0Date, ConfigParam},
1212
fee::LinearFee,
1313
fragment::config::ConfigParams,
14-
value,
1514
};
1615
use serde::{Deserialize, Serialize};
1716
use std::convert::TryFrom;
@@ -108,11 +107,16 @@ pub struct BlockchainConfiguration {
108107

109108
/// Set the default value in the treasury. if omitted then the treasury starts with the value of 0
110109
#[serde(default)]
111-
pub treasury: Option<u64>,
110+
pub treasury: Option<Value>,
111+
112+
/// set the treasure parameters, i.e. the first value the treasury will take from the
113+
/// rewards pot and fees.
114+
#[serde(default)]
115+
pub treasury_parameters: Option<TaxType>,
112116

113117
/// Set the value of the reward pot. if omitted then the reward pot is empty
114118
#[serde(default)]
115-
pub rewards: Option<u64>,
119+
pub rewards: Option<Value>,
116120
}
117121

118122
impl From<BlockchainConfiguration> for ConfigParams {
@@ -161,6 +165,7 @@ impl BlockchainConfiguration {
161165
max_number_of_transactions_per_block: None,
162166
epoch_stability_depth: None,
163167
treasury: None,
168+
treasury_parameters: None,
164169
rewards: None,
165170
}
166171
}
@@ -183,6 +188,7 @@ impl BlockchainConfiguration {
183188
let mut linear_fees = None;
184189
let mut kes_update_speed = None;
185190
let mut treasury = None;
191+
let mut treasury_parameters = None;
186192
let mut rewards = None;
187193
let mut per_certificate_fees = None;
188194

@@ -232,9 +238,15 @@ impl BlockchainConfiguration {
232238
ConfigParam::EpochStabilityDepth(param) => epoch_stability_depth
233239
.replace(param)
234240
.map(|_| "epoch_stability_depth"),
235-
ConfigParam::TreasuryAdd(param) => treasury.replace(param.0).map(|_| "treasury"),
236-
ConfigParam::TreasuryParams(_) => unimplemented!(),
237-
ConfigParam::RewardPot(param) => rewards.replace(param.0).map(|_| "reward-pot"),
241+
ConfigParam::TreasuryAdd(param) => {
242+
treasury.replace(param.into()).map(|_| "treasury")
243+
}
244+
ConfigParam::TreasuryParams(param) => treasury_parameters
245+
.replace(param.into())
246+
.map(|_| "treasury_parameters"),
247+
ConfigParam::RewardPot(param) => {
248+
rewards.replace(param.into()).map(|_| "reward-pot")
249+
}
238250
ConfigParam::RewardParams(_) => unimplemented!(),
239251
ConfigParam::PerCertificateFees(param) => per_certificate_fees
240252
.replace(param)
@@ -267,6 +279,7 @@ impl BlockchainConfiguration {
267279
consensus_leader_ids,
268280
max_number_of_transactions_per_block,
269281
treasury,
282+
treasury_parameters,
270283
rewards,
271284
})
272285
}
@@ -286,6 +299,7 @@ impl BlockchainConfiguration {
286299
max_number_of_transactions_per_block,
287300
epoch_stability_depth,
288301
treasury,
302+
treasury_parameters,
289303
rewards,
290304
} = self;
291305

@@ -315,10 +329,15 @@ impl BlockchainConfiguration {
315329
}
316330

317331
if let Some(treasury) = treasury {
318-
params.push(ConfigParam::TreasuryAdd(value::Value(treasury)));
332+
params.push(ConfigParam::TreasuryAdd(treasury.into()));
319333
}
334+
335+
if let Some(treasury_parameters) = treasury_parameters {
336+
params.push(ConfigParam::TreasuryParams(treasury_parameters.into()));
337+
}
338+
320339
if let Some(rewards) = rewards {
321-
params.push(ConfigParam::RewardPot(value::Value(rewards)));
340+
params.push(ConfigParam::RewardPot(rewards.into()));
322341
}
323342

324343
consensus_leader_ids
@@ -384,6 +403,7 @@ mod test {
384403
max_number_of_transactions_per_block: Arbitrary::arbitrary(g),
385404
epoch_stability_depth: Arbitrary::arbitrary(g),
386405
treasury: Arbitrary::arbitrary(g),
406+
treasury_parameters: Arbitrary::arbitrary(g),
387407
rewards: Arbitrary::arbitrary(g),
388408
}
389409
}

jormungandr-lib/src/interfaces/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod old_address;
1212
mod ratio;
1313
mod settings;
1414
mod stats;
15+
mod tax_type;
1516
mod transaction_input;
1617
mod transaction_output;
1718
mod transaction_witness;
@@ -37,6 +38,7 @@ pub use self::old_address::OldAddress;
3738
pub use self::ratio::{ParseRatioError, Ratio};
3839
pub use self::settings::*;
3940
pub use self::stats::{NodeState, Stats};
41+
pub use self::tax_type::TaxType;
4042
pub use self::transaction_input::{TransactionInput, TransactionInputType};
4143
pub use self::transaction_output::TransactionOutput;
4244
pub use self::transaction_witness::TransactionWitness;
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
use crate::interfaces::{Ratio, Value};
2+
use chain_impl_mockchain::rewards;
3+
use serde::{Deserialize, Serialize};
4+
use std::num::NonZeroU64;
5+
6+
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
7+
#[serde(deny_unknown_fields, rename_all = "snake_case")]
8+
pub struct TaxType {
9+
pub fixed: Value,
10+
11+
pub ratio: Ratio,
12+
13+
#[serde(default, skip_serializing_if = "Option::is_none")]
14+
pub max_limit: Option<NonZeroU64>,
15+
}
16+
17+
/* ************** Conversion *********************************** */
18+
19+
impl From<TaxType> for rewards::TaxType {
20+
fn from(tax_type: TaxType) -> Self {
21+
rewards::TaxType {
22+
fixed: tax_type.fixed.into(),
23+
ratio: tax_type.ratio.into(),
24+
max_limit: tax_type.max_limit,
25+
}
26+
}
27+
}
28+
29+
impl From<rewards::TaxType> for TaxType {
30+
fn from(tax_type: rewards::TaxType) -> Self {
31+
TaxType {
32+
fixed: tax_type.fixed.into(),
33+
ratio: tax_type.ratio.into(),
34+
max_limit: tax_type.max_limit,
35+
}
36+
}
37+
}
38+
39+
#[cfg(test)]
40+
mod test {
41+
use super::*;
42+
use quickcheck::{Arbitrary, Gen, TestResult};
43+
use std::num::NonZeroU64;
44+
45+
impl Arbitrary for TaxType {
46+
fn arbitrary<G>(g: &mut G) -> Self
47+
where
48+
G: Gen,
49+
{
50+
TaxType {
51+
fixed: Value::arbitrary(g),
52+
ratio: Ratio::arbitrary(g),
53+
max_limit: NonZeroU64::new(Arbitrary::arbitrary(g)),
54+
}
55+
}
56+
}
57+
58+
#[test]
59+
fn value_serde_yaml() {
60+
const FIXED: u64 = 8170;
61+
const NUMERATOR: u64 = 192;
62+
const DENOMINATOR: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(1291) };
63+
let tax_type = TaxType {
64+
fixed: FIXED.into(),
65+
ratio: Ratio::new(NUMERATOR, DENOMINATOR),
66+
max_limit: None,
67+
};
68+
69+
assert_eq!(
70+
serde_yaml::to_string(&tax_type).unwrap(),
71+
format!(
72+
"---\nfixed: {}\nratio: {}/{}",
73+
FIXED, NUMERATOR, DENOMINATOR
74+
)
75+
);
76+
}
77+
78+
#[test]
79+
fn value_serde_yaml_with_max_limit() {
80+
const FIXED: u64 = 8170;
81+
const NUMERATOR: u64 = 192;
82+
const DENOMINATOR: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(1291) };
83+
const MAX_LIMIT: u64 = 2028;
84+
let tax_type = TaxType {
85+
fixed: FIXED.into(),
86+
ratio: Ratio::new(NUMERATOR, DENOMINATOR),
87+
max_limit: NonZeroU64::new(MAX_LIMIT),
88+
};
89+
90+
assert_eq!(
91+
serde_yaml::to_string(&tax_type).unwrap(),
92+
format!(
93+
"---\nfixed: {}\nratio: {}/{}\nmax_limit: {}",
94+
FIXED, NUMERATOR, DENOMINATOR, MAX_LIMIT
95+
)
96+
);
97+
}
98+
99+
quickcheck! {
100+
fn value_serde_human_readable_encode_decode(value: TaxType) -> TestResult {
101+
let s = serde_yaml::to_string(&value).unwrap();
102+
let value_dec: TaxType = serde_yaml::from_str(&s).unwrap();
103+
104+
TestResult::from_bool(value_dec == value)
105+
}
106+
}
107+
}

0 commit comments

Comments
 (0)