Improve Rpc inflation tooling (#10309)

automerge
This commit is contained in:
Tyera Eulberg 2020-05-29 12:50:25 -06:00 committed by GitHub
parent 75924bd232
commit b563b49ed5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 217 additions and 58 deletions

1
Cargo.lock generated
View File

@ -3971,6 +3971,7 @@ dependencies = [
"solana-clap-utils", "solana-clap-utils",
"solana-client", "solana-client",
"solana-faucet", "solana-faucet",
"solana-genesis-programs",
"solana-ledger", "solana-ledger",
"solana-logger", "solana-logger",
"solana-measure", "solana-measure",

View File

@ -22,7 +22,6 @@ use solana_sdk::{
epoch_schedule::EpochSchedule, epoch_schedule::EpochSchedule,
fee_calculator::{FeeCalculator, FeeRateGovernor}, fee_calculator::{FeeCalculator, FeeRateGovernor},
hash::Hash, hash::Hash,
inflation::Inflation,
pubkey::Pubkey, pubkey::Pubkey,
signature::Signature, signature::Signature,
signers::Signers, signers::Signers,
@ -346,8 +345,12 @@ impl RpcClient {
}) })
} }
pub fn get_inflation(&self) -> ClientResult<Inflation> { pub fn get_inflation_governor(&self) -> ClientResult<RpcInflationGovernor> {
self.send(RpcRequest::GetInflation, Value::Null) self.send(RpcRequest::GetInflationGovernor, Value::Null)
}
pub fn get_inflation_rate(&self) -> ClientResult<RpcInflationRate> {
self.send(RpcRequest::GetInflationRate, Value::Null)
} }
pub fn get_version(&self) -> ClientResult<RpcVersionInfo> { pub fn get_version(&self) -> ClientResult<RpcVersionInfo> {

View File

@ -1,4 +1,4 @@
use solana_sdk::commitment_config::CommitmentConfig; use solana_sdk::{clock::Epoch, commitment_config::CommitmentConfig};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@ -26,3 +26,11 @@ pub struct RpcLargestAccountsConfig {
pub commitment: Option<CommitmentConfig>, pub commitment: Option<CommitmentConfig>,
pub filter: Option<RpcLargestAccountsFilter>, pub filter: Option<RpcLargestAccountsFilter>,
} }
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcInflationConfig {
pub epoch: Option<Epoch>,
#[serde(flatten)]
pub commitment: Option<CommitmentConfig>,
}

View File

@ -21,7 +21,8 @@ pub enum RpcRequest {
GetFees, GetFees,
GetGenesisHash, GetGenesisHash,
GetIdentity, GetIdentity,
GetInflation, GetInflationGovernor,
GetInflationRate,
GetLargestAccounts, GetLargestAccounts,
GetLeaderSchedule, GetLeaderSchedule,
GetMinimumBalanceForRentExemption, GetMinimumBalanceForRentExemption,
@ -67,7 +68,8 @@ impl fmt::Display for RpcRequest {
RpcRequest::GetFees => "getFees", RpcRequest::GetFees => "getFees",
RpcRequest::GetGenesisHash => "getGenesisHash", RpcRequest::GetGenesisHash => "getGenesisHash",
RpcRequest::GetIdentity => "getIdentity", RpcRequest::GetIdentity => "getIdentity",
RpcRequest::GetInflation => "getInflation", RpcRequest::GetInflationGovernor => "getInflationGovernor",
RpcRequest::GetInflationRate => "getInflationRate",
RpcRequest::GetLargestAccounts => "getLargestAccounts", RpcRequest::GetLargestAccounts => "getLargestAccounts",
RpcRequest::GetLeaderSchedule => "getLeaderSchedule", RpcRequest::GetLeaderSchedule => "getLeaderSchedule",
RpcRequest::GetMinimumBalanceForRentExemption => "getMinimumBalanceForRentExemption", RpcRequest::GetMinimumBalanceForRentExemption => "getMinimumBalanceForRentExemption",
@ -146,10 +148,6 @@ mod tests {
let request = test_request.build_request_json(1, Value::Null); let request = test_request.build_request_json(1, Value::Null);
assert_eq!(request["method"], "getEpochInfo"); assert_eq!(request["method"], "getEpochInfo");
let test_request = RpcRequest::GetInflation;
let request = test_request.build_request_json(1, Value::Null);
assert_eq!(request["method"], "getInflation");
let test_request = RpcRequest::GetRecentBlockhash; let test_request = RpcRequest::GetRecentBlockhash;
let request = test_request.build_request_json(1, Value::Null); let request = test_request.build_request_json(1, Value::Null);
assert_eq!(request["method"], "getRecentBlockhash"); assert_eq!(request["method"], "getRecentBlockhash");

View File

@ -3,6 +3,7 @@ use solana_sdk::{
account::Account, account::Account,
clock::{Epoch, Slot}, clock::{Epoch, Slot},
fee_calculator::{FeeCalculator, FeeRateGovernor}, fee_calculator::{FeeCalculator, FeeRateGovernor},
inflation::Inflation,
pubkey::Pubkey, pubkey::Pubkey,
transaction::{Result, TransactionError}, transaction::{Result, TransactionError},
}; };
@ -55,6 +56,37 @@ pub struct RpcFeeRateGovernor {
pub fee_rate_governor: FeeRateGovernor, pub fee_rate_governor: FeeRateGovernor,
} }
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RpcInflationGovernor {
pub initial: f64,
pub terminal: f64,
pub taper: f64,
pub foundation: f64,
pub foundation_term: f64,
}
impl From<Inflation> for RpcInflationGovernor {
fn from(inflation: Inflation) -> Self {
Self {
initial: inflation.initial,
terminal: inflation.terminal,
taper: inflation.taper,
foundation: inflation.foundation,
foundation_term: inflation.foundation_term,
}
}
}
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RpcInflationRate {
pub total: f64,
pub validator: f64,
pub foundation: f64,
pub epoch: Epoch,
}
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RpcKeyedAccount { pub struct RpcKeyedAccount {

View File

@ -21,6 +21,7 @@ byteorder = "1.3.4"
chrono = { version = "0.4.11", features = ["serde"] } chrono = { version = "0.4.11", features = ["serde"] }
core_affinity = "0.5.10" core_affinity = "0.5.10"
crossbeam-channel = "0.4" crossbeam-channel = "0.4"
ed25519-dalek = "=1.0.0-pre.3"
fs_extra = "1.1.0" fs_extra = "1.1.0"
flate2 = "1.0" flate2 = "1.0"
indexmap = "1.3" indexmap = "1.3"
@ -47,7 +48,7 @@ solana-clap-utils = { path = "../clap-utils", version = "1.3.0" }
solana-client = { path = "../client", version = "1.3.0" } solana-client = { path = "../client", version = "1.3.0" }
solana-transaction-status = { path = "../transaction-status", version = "1.3.0" } solana-transaction-status = { path = "../transaction-status", version = "1.3.0" }
solana-faucet = { path = "../faucet", version = "1.3.0" } solana-faucet = { path = "../faucet", version = "1.3.0" }
ed25519-dalek = "=1.0.0-pre.3" solana-genesis-programs = { path = "../genesis-programs", version = "1.3.0" }
solana-ledger = { path = "../ledger", version = "1.3.0" } solana-ledger = { path = "../ledger", version = "1.3.0" }
solana-logger = { path = "../logger", version = "1.3.0" } solana-logger = { path = "../logger", version = "1.3.0" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.3.0" } solana-merkle-tree = { path = "../merkle-tree", version = "1.3.0" }

View File

@ -26,12 +26,11 @@ use solana_ledger::{
use solana_perf::packet::PACKET_DATA_SIZE; use solana_perf::packet::PACKET_DATA_SIZE;
use solana_runtime::{accounts::AccountAddressFilter, bank::Bank}; use solana_runtime::{accounts::AccountAddressFilter, bank::Bank};
use solana_sdk::{ use solana_sdk::{
clock::{Slot, UnixTimestamp}, clock::{Epoch, Slot, UnixTimestamp},
commitment_config::{CommitmentConfig, CommitmentLevel}, commitment_config::{CommitmentConfig, CommitmentLevel},
epoch_info::EpochInfo, epoch_info::EpochInfo,
epoch_schedule::EpochSchedule, epoch_schedule::EpochSchedule,
hash::Hash, hash::Hash,
inflation::Inflation,
pubkey::Pubkey, pubkey::Pubkey,
signature::Signature, signature::Signature,
timing::slot_duration_from_slots_per_year, timing::slot_duration_from_slots_per_year,
@ -173,8 +172,27 @@ impl JsonRpcRequestProcessor {
.collect()) .collect())
} }
pub fn get_inflation(&self, commitment: Option<CommitmentConfig>) -> Result<Inflation> { pub fn get_inflation_governor(
Ok(self.bank(commitment)?.inflation()) &self,
commitment: Option<CommitmentConfig>,
) -> Result<RpcInflationGovernor> {
Ok(self.bank(commitment)?.inflation().into())
}
pub fn get_inflation_rate(&self, epoch: Option<Epoch>) -> Result<RpcInflationRate> {
let bank = self.bank(None)?;
let operating_mode = bank.operating_mode();
let epoch = epoch.unwrap_or_else(|| bank.epoch());
let inflation = solana_genesis_programs::get_inflation_for_epoch(operating_mode, epoch);
let year =
(bank.epoch_schedule().get_last_slot_in_epoch(epoch)) as f64 / bank.slots_per_year();
Ok(RpcInflationRate {
total: inflation.total(year),
validator: inflation.validator(year),
foundation: inflation.foundation(year),
epoch,
})
} }
pub fn get_epoch_schedule(&self) -> Result<EpochSchedule> { pub fn get_epoch_schedule(&self) -> Result<EpochSchedule> {
@ -757,12 +775,19 @@ pub trait RpcSol {
commitment: Option<CommitmentConfig>, commitment: Option<CommitmentConfig>,
) -> Result<u64>; ) -> Result<u64>;
#[rpc(meta, name = "getInflation")] #[rpc(meta, name = "getInflationGovernor")]
fn get_inflation( fn get_inflation_governor(
&self, &self,
meta: Self::Metadata, meta: Self::Metadata,
commitment: Option<CommitmentConfig>, commitment: Option<CommitmentConfig>,
) -> Result<Inflation>; ) -> Result<RpcInflationGovernor>;
#[rpc(meta, name = "getInflationRate")]
fn get_inflation_rate(
&self,
meta: Self::Metadata,
epoch: Option<Epoch>,
) -> Result<RpcInflationRate>;
#[rpc(meta, name = "getEpochSchedule")] #[rpc(meta, name = "getEpochSchedule")]
fn get_epoch_schedule(&self, meta: Self::Metadata) -> Result<EpochSchedule>; fn get_epoch_schedule(&self, meta: Self::Metadata) -> Result<EpochSchedule>;
@ -1022,16 +1047,28 @@ impl RpcSol for RpcSolImpl {
.get_program_accounts(&program_id, commitment) .get_program_accounts(&program_id, commitment)
} }
fn get_inflation( fn get_inflation_governor(
&self, &self,
meta: Self::Metadata, meta: Self::Metadata,
commitment: Option<CommitmentConfig>, commitment: Option<CommitmentConfig>,
) -> Result<Inflation> { ) -> Result<RpcInflationGovernor> {
debug!("get_inflation rpc request received"); debug!("get_inflation_governor rpc request received");
meta.request_processor meta.request_processor
.read() .read()
.unwrap() .unwrap()
.get_inflation(commitment) .get_inflation_governor(commitment)
}
fn get_inflation_rate(
&self,
meta: Self::Metadata,
epoch: Option<Epoch>,
) -> Result<RpcInflationRate> {
debug!("get_inflation_rate rpc request received");
meta.request_processor
.read()
.unwrap()
.get_inflation_rate(epoch)
} }
fn get_epoch_schedule(&self, meta: Self::Metadata) -> Result<EpochSchedule> { fn get_epoch_schedule(&self, meta: Self::Metadata) -> Result<EpochSchedule> {
@ -2066,11 +2103,11 @@ pub mod tests {
let bob_pubkey = Pubkey::new_rand(); let bob_pubkey = Pubkey::new_rand();
let RpcHandler { io, meta, bank, .. } = start_rpc_handler_with_tx(&bob_pubkey); let RpcHandler { io, meta, bank, .. } = start_rpc_handler_with_tx(&bob_pubkey);
let req = r#"{"jsonrpc":"2.0","id":1,"method":"getInflation"}"#; let req = r#"{"jsonrpc":"2.0","id":1,"method":"getInflationGovernor"}"#;
let rep = io.handle_request_sync(&req, meta); let rep = io.handle_request_sync(&req, meta.clone());
let res: Response = serde_json::from_str(&rep.expect("actual response")) let res: Response = serde_json::from_str(&rep.expect("actual response"))
.expect("actual response deserialization"); .expect("actual response deserialization");
let inflation: Inflation = if let Response::Single(res) = res { let inflation_governor: RpcInflationGovernor = if let Response::Single(res) = res {
if let Output::Success(res) = res { if let Output::Success(res) = res {
serde_json::from_value(res.result).unwrap() serde_json::from_value(res.result).unwrap()
} else { } else {
@ -2079,7 +2116,57 @@ pub mod tests {
} else { } else {
panic!("Expected single response"); panic!("Expected single response");
}; };
assert_eq!(inflation, bank.inflation()); let expected_inflation_governor: RpcInflationGovernor = bank.inflation().into();
assert_eq!(inflation_governor, expected_inflation_governor);
let req = r#"{"jsonrpc":"2.0","id":1,"method":"getInflationRate"}"#; // Queries current epoch by default
let rep = io.handle_request_sync(&req, meta.clone());
let res: Response = serde_json::from_str(&rep.expect("actual response"))
.expect("actual response deserialization");
let inflation_rate: RpcInflationRate = if let Response::Single(res) = res {
if let Output::Success(res) = res {
serde_json::from_value(res.result).unwrap()
} else {
panic!("Expected success");
}
} else {
panic!("Expected single response");
};
let operating_mode = bank.operating_mode();
let inflation = solana_genesis_programs::get_inflation_for_epoch(operating_mode, 0);
let year = (bank.epoch_schedule().get_last_slot_in_epoch(0)) as f64 / bank.slots_per_year();
let expected_inflation_rate = RpcInflationRate {
total: inflation.total(year),
validator: inflation.validator(year),
foundation: inflation.foundation(year),
epoch: 0,
};
assert_eq!(inflation_rate, expected_inflation_rate);
let epoch = 40_000_000; // After default foundation term
let req = format!(
r#"{{"jsonrpc":"2.0","id":1,"method":"getInflationRate","params":[{}]}}"#,
epoch
); // Queries current epoch by default
let rep = io.handle_request_sync(&req, meta);
let res: Response = serde_json::from_str(&rep.expect("actual response"))
.expect("actual response deserialization");
let inflation_rate: RpcInflationRate = if let Response::Single(res) = res {
if let Output::Success(res) = res {
serde_json::from_value(res.result).unwrap()
} else {
panic!("Expected success");
}
} else {
panic!("Expected single response");
};
let expected_inflation_rate = RpcInflationRate {
total: 0.015,
validator: 0.015,
foundation: 0.0,
epoch,
};
assert_eq!(inflation_rate, expected_inflation_rate);
} }
#[test] #[test]

View File

@ -31,7 +31,8 @@ To interact with a Solana node inside a JavaScript application, use the [solana-
* [getFirstAvailableBlock](jsonrpc-api.md#getfirstavailableblock) * [getFirstAvailableBlock](jsonrpc-api.md#getfirstavailableblock)
* [getGenesisHash](jsonrpc-api.md#getgenesishash) * [getGenesisHash](jsonrpc-api.md#getgenesishash)
* [getIdentity](jsonrpc-api.md#getidentity) * [getIdentity](jsonrpc-api.md#getidentity)
* [getInflation](jsonrpc-api.md#getinflation) * [getInflationGovernor](jsonrpc-api.md#getinflationgovernor)
* [getInflationRate](jsonrpc-api.md#getinflationrate)
* [getLargestAccounts](jsonrpc-api.md#getlargestaccounts) * [getLargestAccounts](jsonrpc-api.md#getlargestaccounts)
* [getLeaderSchedule](jsonrpc-api.md#getleaderschedule) * [getLeaderSchedule](jsonrpc-api.md#getleaderschedule)
* [getMinimumBalanceForRentExemption](jsonrpc-api.md#getminimumbalanceforrentexemption) * [getMinimumBalanceForRentExemption](jsonrpc-api.md#getminimumbalanceforrentexemption)
@ -635,33 +636,59 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "m
{"jsonrpc":"2.0","result":{"identity": "2r1F4iWqVcb8M1DbAjQuFpebkQHY9hcVU4WuW2DJBppN"},"id":1} {"jsonrpc":"2.0","result":{"identity": "2r1F4iWqVcb8M1DbAjQuFpebkQHY9hcVU4WuW2DJBppN"},"id":1}
``` ```
### getInflation ### getInflationGovernor
Returns the inflation configuration of the cluster Returns the current inflation governor
#### Parameters: #### Parameters:
None * `<object>` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
#### Results: #### Results:
The result field will be an Inflation object with the following fields: The result field will be a JSON object with the following fields:
* `initial: <f64>`, the initial inflation percentage from time 0 * `initial: <f64>`, the initial inflation percentage from time 0
* `terminal: <f64>`, terminal inflation percentage * `terminal: <f64>`, terminal inflation percentage
* `taper: <f64>`, rate per year at which inflation is lowered * `taper: <f64>`, rate per year at which inflation is lowered
* `foundation: <f64>`, percentage of total inflation allocated to the foundation * `foundation: <f64>`, percentage of total inflation allocated to the foundation
* `foundationTerm: <f64>`, duration of foundation pool inflation in years * `foundationTerm: <f64>`, duration of foundation pool inflation in years
* `storage: <f64>`, percentage of total inflation allocated to storage rewards
#### Example: #### Example:
```bash ```bash
// Request // Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getInflation"}' http://localhost:8899 curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getInflationGovernor"}' http://localhost:8899
// Result // Result
{"jsonrpc":"2.0","result":{"foundation":0.05,"foundationTerm":7.0,"initial":0.15,"storage":0.1,"taper":0.15,"terminal":0.015},"id":1} {"jsonrpc":"2.0","result":{"foundation":0.05,"foundationTerm":7.0,"initial":0.15,"taper":0.15,"terminal":0.015},"id":1}
```
### getInflationRate
Returns the specific inflation values for a particular epoch
#### Parameters:
* `<u64>` - (optional) Epoch, default is the current epoch
#### Results:
The result field will be a JSON object with the following fields:
* `total: <f64>`, total inflation
* `validator: <f64>`, inflation allocated to validators
* `foundation: <f64>`, inflation allocated to the foundation
* `epoch: <f64>`, epoch for which these values are valid
#### Example:
```bash
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getInflationRate"}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":{"epoch":100,"foundation":0.001,"total":0.149,"validator":0.148},"id":1}
``` ```
### getLargestAccounts ### getLargestAccounts

View File

@ -16,26 +16,28 @@ use log::*;
use solana_runtime::bank::{Bank, EnteredEpochCallback}; use solana_runtime::bank::{Bank, EnteredEpochCallback};
pub fn get_inflation(operating_mode: OperatingMode, epoch: Epoch) -> Option<Inflation> { pub fn get_inflation(operating_mode: OperatingMode, epoch: Epoch) -> Option<Inflation> {
let past_epoch_inflation = get_inflation_for_epoch(operating_mode, epoch.saturating_sub(1));
let epoch_inflation = get_inflation_for_epoch(operating_mode, epoch);
if epoch_inflation != past_epoch_inflation || epoch == 0 {
Some(epoch_inflation)
} else {
None
}
}
pub fn get_inflation_for_epoch(operating_mode: OperatingMode, epoch: Epoch) -> Inflation {
match operating_mode { match operating_mode {
OperatingMode::Development => { OperatingMode::Development => Inflation::default(),
if epoch == 0 {
Some(Inflation::default())
} else {
None
}
}
OperatingMode::Stable | OperatingMode::Preview => { OperatingMode::Stable | OperatingMode::Preview => {
if epoch == 0 { if epoch == std::u64::MAX {
// No inflation at epoch 0
Some(Inflation::new_disabled())
} else if epoch == std::u64::MAX {
// Inflation starts // Inflation starts
// // The epoch of std::u64::MAX is a placeholder and is expected to be reduced in
// The epoch of std::u64::MAX - 1 is a placeholder and is expected to be reduced in
// a future hard fork. // a future hard fork.
Some(Inflation::default()) Inflation::default()
} else { } else {
None // No inflation from epoch 0
Inflation::new_disabled()
} }
} }
} }

View File

@ -1917,7 +1917,7 @@ impl Bank {
self.get_slots_in_epoch(self.first_normal_epoch()) self.get_slots_in_epoch(self.first_normal_epoch())
} }
fn operating_mode(&self) -> OperatingMode { pub fn operating_mode(&self) -> OperatingMode {
// unwrap is safe; self.operating_mode is ensured to be Some() always... // unwrap is safe; self.operating_mode is ensured to be Some() always...
// we only using Option here for ABI compatibility... // we only using Option here for ABI compatibility...
self.operating_mode.unwrap() self.operating_mode.unwrap()
@ -6891,25 +6891,25 @@ mod tests {
if bank.slot == 0 { if bank.slot == 0 {
assert_eq!( assert_eq!(
bank.hash().to_string(), bank.hash().to_string(),
"7MKHH6P7J5aQNN29Cr6aZQbEpQcXe8KTgchd4Suk9NCG" "DX3Jk7ae6VdogRb73iC1zdyrYN5UzinLcSFES2FQx8dY"
); );
} }
if bank.slot == 32 { if bank.slot == 32 {
assert_eq!( assert_eq!(
bank.hash().to_string(), bank.hash().to_string(),
"3AxuV6GGcoqRi6pksN6btNEmeJCTesLbjgA88QZt9a8Q" "FqLpq1gmTdzEmdEPa2JttEFDqRtuKwkKFKuLuqNSiYwH"
); );
} }
if bank.slot == 64 { if bank.slot == 64 {
assert_eq!( assert_eq!(
bank.hash().to_string(), bank.hash().to_string(),
"B32ZLAzeCW5FueeauiGYnujh8Efmxvpeac74W9JU68oB" "rBbDCyHuCBWQrLY37zjj2zwsEnzNERWHwoH3W2NpRYe"
); );
} }
if bank.slot == 128 { if bank.slot == 128 {
assert_eq!( assert_eq!(
bank.hash().to_string(), bank.hash().to_string(),
"A2tCz2EqryRZ7tHpw9H2918RZLCbqnSGzRWUqbnnESGz" "E9DThiAPbheGeLWBDsts8uzuwF3bJQzDWh5uo8ovtYiy"
); );
break; break;
} }

View File

@ -18,7 +18,7 @@ pub struct Inflation {
/// Duration of foundation pool inflation, in years /// Duration of foundation pool inflation, in years
pub foundation_term: f64, pub foundation_term: f64,
/// Percentage of total inflation allocated to storage rewards /// DEPRECATED, this field is currently unused
pub storage: f64, pub storage: f64,
} }
@ -27,7 +27,7 @@ const DEFAULT_TERMINAL: f64 = 0.015;
const DEFAULT_TAPER: f64 = 0.15; const DEFAULT_TAPER: f64 = 0.15;
const DEFAULT_FOUNDATION: f64 = 0.05; const DEFAULT_FOUNDATION: f64 = 0.05;
const DEFAULT_FOUNDATION_TERM: f64 = 7.0; const DEFAULT_FOUNDATION_TERM: f64 = 7.0;
const DEFAULT_STORAGE: f64 = 0.10; const DEFAULT_STORAGE: f64 = 0.0;
impl Default for Inflation { impl Default for Inflation {
fn default() -> Self { fn default() -> Self {
@ -69,8 +69,8 @@ impl Inflation {
self.total(year) - self.storage(year) - self.foundation(year) self.total(year) - self.storage(year) - self.foundation(year)
} }
/// portion of total that goes to storage mining /// DEPRECATED
pub fn storage(&self, year: f64) -> f64 { fn storage(&self, year: f64) -> f64 {
self.total(year) * self.storage self.total(year) * self.storage
} }