Skip to content

Commit

Permalink
Merge branch 'brent/tune-storage-past-epochs' (#1944)
Browse files Browse the repository at this point in the history
* brent/tune-storage-past-epochs:
  move protocol keys into epoched PoS data
  keep `total_deltas` for same period of time as `validator_deltas`
  clear old enqueued slashes when processing slashes
  keep validator eth keys for max proposal period
  fixup! pos/types: configure number of past epochs kept for PoS data
  fixed `epoched` tests and `test_validator_sets`
  [ci] wasm checksums update
  changelog: add #1944
  PoS: refactor usages of `Epoch::checked_sub`
  core/types/storage:m ore flexible fn checked_sub param
  fixup! replace direct storage read of PosParams with an RPC fn
  replace direct storage read of PosParams with an RPC fn
  fix PoS crate standalone build
  fixup! Apply suggestions from code review
  Apply suggestions from code review
  docstring cleanup
  new impl for purging old validator sets
  pos/types: configure number of past epochs kept for PoS data
  add PosParams type with added gov param
  WIP want to pass `max_proposal_period` from gov params into PoS
  • Loading branch information
brentstone committed Oct 16, 2023
2 parents 891ade1 + 64e817b commit 334b44c
Show file tree
Hide file tree
Showing 35 changed files with 967 additions and 369 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- New implementation and parameters for purging old epochs for Epoched validator
data in storage. ([\#1944](https://github.com/anoma/namada/pull/1944))
8 changes: 1 addition & 7 deletions apps/src/lib/client/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ use namada::core::ledger::governance::cli::offline::{
use namada::core::ledger::governance::cli::onchain::{
DefaultProposal, PgfFundingProposal, PgfStewardProposal, ProposalVote,
};
use namada::ledger::pos;
use namada::proof_of_stake::parameters::PosParams;
use namada::proto::Tx;
use namada::types::address::{Address, ImplicitAddress};
use namada::types::dec::Dec;
Expand Down Expand Up @@ -469,11 +467,7 @@ pub async fn submit_init_validator<'a>(
)
.unwrap();

let key = pos::params_key();
let pos_params: PosParams =
rpc::query_storage_value(namada.client(), &key)
.await
.expect("Pos parameter should be defined.");
let pos_params = rpc::query_pos_parameters(namada.client()).await;

display_line!(namada.io(), "");
display_line!(
Expand Down
29 changes: 13 additions & 16 deletions apps/src/lib/config/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use derivative::Derivative;
use namada::core::ledger::governance::parameters::GovernanceParameters;
use namada::core::ledger::pgf::parameters::PgfParameters;
use namada::ledger::parameters::EpochDuration;
use namada::ledger::pos::{Dec, GenesisValidator, PosParams};
use namada::ledger::pos::{Dec, GenesisValidator, OwnedPosParams};
use namada::types::address::Address;
use namada::types::chain::ProposalBytes;
use namada::types::key::dkg_session_keys::DkgPublicKey;
Expand All @@ -31,7 +31,7 @@ pub mod genesis_config {
use namada::core::ledger::governance::parameters::GovernanceParameters;
use namada::core::ledger::pgf::parameters::PgfParameters;
use namada::ledger::parameters::EpochDuration;
use namada::ledger::pos::{Dec, GenesisValidator, PosParams};
use namada::ledger::pos::{Dec, GenesisValidator, OwnedPosParams};
use namada::types::address::Address;
use namada::types::chain::ProposalBytes;
use namada::types::key::dkg_session_keys::DkgPublicKey;
Expand Down Expand Up @@ -338,6 +338,12 @@ pub mod genesis_config {
.unwrap()
.to_public_key()
.unwrap(),
protocol_key: config
.protocol_public_key
.as_ref()
.unwrap()
.to_public_key()
.unwrap(),
eth_cold_key: config
.eth_cold_key
.as_ref()
Expand Down Expand Up @@ -372,12 +378,6 @@ pub mod genesis_config {
.unwrap()
.to_public_key()
.unwrap(),
protocol_key: config
.protocol_public_key
.as_ref()
.unwrap()
.to_public_key()
.unwrap(),
dkg_public_key: config
.dkg_public_key
.as_ref()
Expand Down Expand Up @@ -665,7 +665,7 @@ pub mod genesis_config {
validator_stake_threshold,
} = pos_params;

let pos_params = PosParams {
let pos_params = OwnedPosParams {
max_validator_slots,
pipeline_len,
unbonding_len,
Expand Down Expand Up @@ -738,7 +738,7 @@ pub struct Genesis {
pub established_accounts: Vec<EstablishedAccount>,
pub implicit_accounts: Vec<ImplicitAccount>,
pub parameters: Parameters,
pub pos_params: PosParams,
pub pos_params: OwnedPosParams,
pub gov_params: GovernanceParameters,
pub pgf_params: PgfParameters,
// Ethereum bridge config
Expand Down Expand Up @@ -774,9 +774,6 @@ pub struct Validator {
/// this key on a transaction signature.
/// Note that this is distinct from consensus key used in the PoS system.
pub account_key: common::PublicKey,
/// Public key associated with validator account used for signing protocol
/// transactions
pub protocol_key: common::PublicKey,
/// The public DKG session key used during the DKG protocol
pub dkg_public_key: DkgPublicKey,
/// These tokens are not staked and hence do not contribute to the
Expand Down Expand Up @@ -938,14 +935,14 @@ pub fn genesis(num_validators: u64) -> Genesis {
address,
tokens: token::Amount::native_whole(200_000),
consensus_key: consensus_keypair.ref_to(),
protocol_key: protocol_keypair.ref_to(),
commission_rate: Dec::new(5, 2).expect("This can't fail"),
max_commission_rate_change: Dec::new(1, 2)
.expect("This can't fail"),
eth_cold_key: eth_cold_keypair.ref_to(),
eth_hot_key: eth_bridge_keypair.ref_to(),
},
account_key: account_keypair.ref_to(),
protocol_key: protocol_keypair.ref_to(),
dkg_public_key: dkg_keypair.public(),
non_staked_balance: token::Amount::native_whole(100_000),
// TODO replace with https://github.com/anoma/namada/issues/25)
Expand All @@ -971,14 +968,14 @@ pub fn genesis(num_validators: u64) -> Genesis {
address,
tokens: token::Amount::native_whole(200_000),
consensus_key: consensus_keypair.ref_to(),
protocol_key: protocol_keypair.ref_to(),
commission_rate: Dec::new(5, 2).expect("This can't fail"),
max_commission_rate_change: Dec::new(1, 2)
.expect("This can't fail"),
eth_cold_key: eth_cold_keypair.ref_to(),
eth_hot_key: eth_bridge_keypair.ref_to(),
},
account_key: account_keypair.ref_to(),
protocol_key: protocol_keypair.ref_to(),
dkg_public_key: dkg_keypair.public(),
non_staked_balance: token::Amount::native_whole(100_000),
// TODO replace with https://github.com/anoma/namada/issues/25)
Expand Down Expand Up @@ -1109,7 +1106,7 @@ pub fn genesis(num_validators: u64) -> Genesis {
implicit_accounts,
token_accounts,
parameters,
pos_params: PosParams::default(),
pos_params: OwnedPosParams::default(),
gov_params: GovernanceParameters::default(),
pgf_params: PgfParameters::default(),
ethereum_bridge_params: Some(EthereumBridgeConfig {
Expand Down
189 changes: 180 additions & 9 deletions apps/src/lib/node/ledger/shell/finalize_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,14 @@ where
namada_proof_of_stake::read_pos_params(&self.wl_storage)?;
namada_proof_of_stake::copy_validator_sets_and_positions(
&mut self.wl_storage,
&pos_params,
current_epoch,
current_epoch + pos_params.pipeline_len,
)?;
namada_proof_of_stake::store_total_consensus_stake(
&mut self.wl_storage,
current_epoch,
)?;
namada_proof_of_stake::purge_validator_sets_for_old_epoch(
&mut self.wl_storage,
current_epoch,
)?;
}

// Invariant: Has to be applied before `record_slashes_from_evidence`
Expand Down Expand Up @@ -2639,8 +2636,8 @@ mod test_finalize_block {
..Default::default()
});
let mut params = read_pos_params(&shell.wl_storage).unwrap();
params.unbonding_len = 4;
write_pos_params(&mut shell.wl_storage, params.clone())?;
params.owned.unbonding_len = 4;
write_pos_params(&mut shell.wl_storage, &params.owned)?;

let validator_set: Vec<WeightedValidator> =
read_consensus_validator_set_addresses_with_stake(
Expand Down Expand Up @@ -3029,9 +3026,9 @@ mod test_finalize_block {
..Default::default()
});
let mut params = read_pos_params(&shell.wl_storage).unwrap();
params.unbonding_len = 4;
params.max_validator_slots = 4;
write_pos_params(&mut shell.wl_storage, params.clone())?;
params.owned.unbonding_len = 4;
params.owned.max_validator_slots = 4;
write_pos_params(&mut shell.wl_storage, &params.owned)?;

// Slash pool balance
let nam_address = shell.wl_storage.storage.native_token.clone();
Expand Down Expand Up @@ -3830,6 +3827,180 @@ mod test_finalize_block {
Ok(())
}

#[test]
fn test_purge_validator_information() -> storage_api::Result<()> {
// Setup the network with pipeline_len = 2, unbonding_len = 4
let num_validators = 4_u64;
let (mut shell, _recv, _, _) = setup_with_cfg(SetupCfg {
last_height: 0,
num_validators,
..Default::default()
});
let mut params = read_pos_params(&shell.wl_storage).unwrap();
params.owned.unbonding_len = 4;
// params.owned.max_validator_slots = 3;
// params.owned.validator_stake_threshold = token::Amount::zero();
write_pos_params(&mut shell.wl_storage, &params.owned)?;

let max_proposal_period = params.max_proposal_period;
let default_past_epochs = 2;
let consensus_val_set_len = max_proposal_period + default_past_epochs;

let consensus_val_set =
namada_proof_of_stake::consensus_validator_set_handle();
// let below_cap_val_set =
// namada_proof_of_stake::below_capacity_validator_set_handle();
let validator_positions =
namada_proof_of_stake::validator_set_positions_handle();
let all_validator_addresses =
namada_proof_of_stake::validator_addresses_handle();

let consensus_set: Vec<WeightedValidator> =
read_consensus_validator_set_addresses_with_stake(
&shell.wl_storage,
Epoch::default(),
)
.unwrap()
.into_iter()
.collect();
let val1 = consensus_set[0].clone();
let pkh1 = get_pkh_from_address(
&shell.wl_storage,
&params,
val1.address,
Epoch::default(),
);

// Finalize block 1
next_block_for_inflation(&mut shell, pkh1.clone(), vec![], None);

let votes = get_default_true_votes(&shell.wl_storage, Epoch::default());
assert!(!votes.is_empty());

let check_is_data = |storage: &WlStorage<_, _>,
start: Epoch,
end: Epoch| {
for ep in Epoch::iter_bounds_inclusive(start, end) {
assert!(!consensus_val_set.at(&ep).is_empty(storage).unwrap());
// assert!(!below_cap_val_set.at(&ep).is_empty(storage).
// unwrap());
assert!(
!validator_positions.at(&ep).is_empty(storage).unwrap()
);
assert!(
!all_validator_addresses.at(&ep).is_empty(storage).unwrap()
);
}
};

// Check that there is validator data for epochs 0 - pipeline_len
check_is_data(&shell.wl_storage, Epoch(0), Epoch(params.pipeline_len));

// Advance to epoch `default_past_epochs`
let mut current_epoch = Epoch(0);
for _ in 0..default_past_epochs {
let votes = get_default_true_votes(
&shell.wl_storage,
shell.wl_storage.storage.block.epoch,
);
current_epoch = advance_epoch(&mut shell, &pkh1, &votes, None);
}
assert_eq!(shell.wl_storage.storage.block.epoch.0, default_past_epochs);
assert_eq!(current_epoch.0, default_past_epochs);

check_is_data(
&shell.wl_storage,
Epoch(0),
Epoch(params.pipeline_len + default_past_epochs),
);

// Advance one more epoch, which should purge the data for epoch 0 in
// everything except the consensus validator set
let votes = get_default_true_votes(
&shell.wl_storage,
shell.wl_storage.storage.block.epoch,
);
current_epoch = advance_epoch(&mut shell, &pkh1, &votes, None);
assert_eq!(current_epoch.0, default_past_epochs + 1);

check_is_data(
&shell.wl_storage,
Epoch(1),
Epoch(params.pipeline_len + default_past_epochs + 1),
);
assert!(
!consensus_val_set
.at(&Epoch(0))
.is_empty(&shell.wl_storage)
.unwrap()
);
assert!(
validator_positions
.at(&Epoch(0))
.is_empty(&shell.wl_storage)
.unwrap()
);
assert!(
all_validator_addresses
.at(&Epoch(0))
.is_empty(&shell.wl_storage)
.unwrap()
);

// Advance to the epoch `consensus_val_set_len` + 1
loop {
assert!(
!consensus_val_set
.at(&Epoch(0))
.is_empty(&shell.wl_storage)
.unwrap()
);
let votes = get_default_true_votes(
&shell.wl_storage,
shell.wl_storage.storage.block.epoch,
);
current_epoch = advance_epoch(&mut shell, &pkh1, &votes, None);
if current_epoch.0 == consensus_val_set_len + 1 {
break;
}
}

assert!(
consensus_val_set
.at(&Epoch(0))
.is_empty(&shell.wl_storage)
.unwrap()
);

// Advance one more epoch
let votes = get_default_true_votes(
&shell.wl_storage,
shell.wl_storage.storage.block.epoch,
);
current_epoch = advance_epoch(&mut shell, &pkh1, &votes, None);
for ep in Epoch::default().iter_range(2) {
assert!(
consensus_val_set
.at(&ep)
.is_empty(&shell.wl_storage)
.unwrap()
);
}
for ep in Epoch::iter_bounds_inclusive(
Epoch(2),
current_epoch + params.pipeline_len,
) {
assert!(
!consensus_val_set
.at(&ep)
.is_empty(&shell.wl_storage)
.unwrap()
);
}

Ok(())
}

fn get_default_true_votes<S>(storage: &S, epoch: Epoch) -> Vec<VoteInfo>
where
S: StorageRead,
Expand Down
8 changes: 2 additions & 6 deletions apps/src/lib/node/ledger/shell/init_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::collections::HashMap;
use std::hash::Hash;

use namada::ledger::parameters::{self, Parameters};
use namada::ledger::pos::{staking_token_address, PosParams};
use namada::ledger::pos::{staking_token_address, OwnedPosParams};
use namada::ledger::storage::traits::StorageHasher;
use namada::ledger::storage::{DBIter, DB};
use namada::ledger::storage_api::token::{
Expand Down Expand Up @@ -394,10 +394,6 @@ where
)
.unwrap();

self.wl_storage
.write(&protocol_pk_key(addr), &validator.protocol_key)
.expect("Unable to set genesis user protocol public key");

self.wl_storage
.write(
&dkg_session_keys::dkg_pk_key(addr),
Expand All @@ -412,7 +408,7 @@ where
&mut self,
staking_token: &Address,
validators: Vec<genesis::Validator>,
pos_params: &PosParams,
pos_params: &OwnedPosParams,
) -> Result<response::InitChain> {
let mut response = response::InitChain::default();
// PoS system depends on epoch being initialized. Write the total
Expand Down
Loading

0 comments on commit 334b44c

Please sign in to comment.