Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix next epoch #3756

Merged
merged 3 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions crates/node/src/shell/testing/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,29 +363,28 @@ impl MockNode {
}

pub fn next_epoch(&mut self) -> Epoch {
#[allow(clippy::disallowed_methods)]
let header_time = DateTimeUtc::now();
{
let mut locked = self.shell.lock().unwrap();

let next_epoch_height =
locked.state.in_mem().get_last_block_height() + 1;
locked.state.in_mem_mut().next_epoch_min_start_height =
next_epoch_height;
locked.state.in_mem_mut().next_epoch_min_start_time = {
#[allow(clippy::disallowed_methods)]
DateTimeUtc::now()
};
let next_epoch_min_start_height =
locked.state.in_mem().next_epoch_min_start_height;
locked.state.in_mem_mut().next_epoch_min_start_time = header_time;
if let Some(LastBlock { height, .. }) =
locked.state.in_mem_mut().last_block.as_mut()
{
*height = next_epoch_min_start_height;
*height = next_epoch_height;
}
}
self.finalize_and_commit();
// Use the same timestamp as `next_epoch_min_start_time` to ensure a new
// epoch is started on this block
self.finalize_and_commit(Some(header_time));

for _ in 0..EPOCH_SWITCH_BLOCKS_DELAY {
self.finalize_and_commit();
self.finalize_and_commit(None);
}
self.shell
.lock()
Expand Down Expand Up @@ -459,7 +458,7 @@ impl MockNode {

/// Simultaneously call the `FinalizeBlock` and
/// `Commit` handlers.
pub fn finalize_and_commit(&self) {
pub fn finalize_and_commit(&self, header_time: Option<DateTimeUtc>) {
let (proposer_address, votes) = self.prepare_request();

let mut locked = self.shell.lock().unwrap();
Expand Down Expand Up @@ -490,7 +489,7 @@ impl MockNode {
header: BlockHeader {
hash: Hash([0; 32]),
#[allow(clippy::disallowed_methods)]
time: DateTimeUtc::now(),
time: header_time.unwrap_or_else(DateTimeUtc::now),
next_validators_hash: Hash([0; 32]),
},
block_hash: Hash([0; 32]),
Expand Down Expand Up @@ -570,7 +569,7 @@ impl MockNode {
/// Send a tx through Process Proposal and Finalize Block
/// and register the results.
pub fn submit_txs(&self, txs: Vec<Vec<u8>>) {
self.finalize_and_commit();
self.finalize_and_commit(None);
let (proposer_address, votes) = self.prepare_request();

#[allow(clippy::disallowed_methods)]
Expand Down Expand Up @@ -605,11 +604,20 @@ impl MockNode {
}

// process proposal succeeded, now run finalize block

let time = {
#[allow(clippy::disallowed_methods)]
let time = DateTimeUtc::now();
// Set the block time in the past to avoid non-deterministically
// starting new epochs
let dur = namada_sdk::time::Duration::minutes(10);
time - dur
};
let req = FinalizeBlock {
header: BlockHeader {
hash: Hash([0; 32]),
#[allow(clippy::disallowed_methods)]
time: DateTimeUtc::now(),
time,
next_validators_hash: Hash([0; 32]),
},
block_hash: Hash([0; 32]),
Expand Down
108 changes: 104 additions & 4 deletions crates/tests/src/integration/ledger_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ fn invalid_transactions() -> Result<()> {
assert_matches!(captured.result, Ok(_));
assert!(captured.contains(TX_REJECTED));

node.finalize_and_commit();
node.finalize_and_commit(None);
// There should be state now
{
let locked = node.shell.lock().unwrap();
Expand Down Expand Up @@ -953,6 +953,106 @@ fn proposal_submission() -> Result<()> {
Ok(())
}

#[test]
fn inflation() -> Result<()> {
// This address doesn't matter for tests. But an argument is required.
let validator_one_rpc = "http://127.0.0.1:26567";
// 1. start the ledger node
let (mut node, _services) = setup::initialize_genesis(|mut genesis| {
genesis.parameters.pos_params.max_inflation_rate =
Dec::from_str("0.1").unwrap();
genesis.parameters.pgf_params.stewards_inflation_rate =
Dec::from_str("0.1").unwrap();
genesis.parameters.pgf_params.pgf_inflation_rate =
Dec::from_str("0.1").unwrap();
genesis.parameters.pgf_params.stewards =
BTreeSet::from_iter([defaults::albert_address()]);
genesis
})?;

let pos_inflation = [
114400000.785983,
114400001.632333,
114400002.53905,
114400003.506134,
114400004.533585,
];
let steward_inflation = [
1980000.36276,
1980000.72552,
1980001.08828,
1980001.45104,
1980001.8138,
];
let pgf_inflation = [0.399038, 0.792006, 1.200066, 1.623217, 2.06146];

for epoch in 0..5 {
node.next_epoch();

let query_total_supply_args = vec![
"total-supply",
"--token",
NAM,
"--ledger-address",
&validator_one_rpc,
];
let captured = CapturedOutput::of(|| {
run(&node, Bin::Client, query_total_supply_args)
});
assert_matches!(captured.result, Ok(_));
assert!(captured.contains(&format!(
"token tnam1q9kn74xfzytqkqyycfrhycr8ajam8ny935cge0z5: {}",
pos_inflation[epoch]
)));

let query_balance_args = vec![
"balance",
"--owner",
PGF_ADDRESS,
"--token",
NAM,
"--ledger-address",
&validator_one_rpc,
];
let captured =
CapturedOutput::of(|| run(&node, Bin::Client, query_balance_args));
assert_matches!(captured.result, Ok(_));
assert!(captured.contains(&format!("nam: {}", pgf_inflation[epoch])));

let query_balance_args = vec![
"balance",
"--owner",
ALBERT,
"--token",
NAM,
"--ledger-address",
&validator_one_rpc,
];
let captured =
CapturedOutput::of(|| run(&node, Bin::Client, query_balance_args));
assert_matches!(captured.result, Ok(_));
assert!(
captured.contains(&format!("nam: {}", steward_inflation[epoch]))
);

let query_balance_args = vec![
"balance",
"--owner",
BERTHA,
"--token",
NAM,
"--ledger-address",
&validator_one_rpc,
];
let captured =
CapturedOutput::of(|| run(&node, Bin::Client, query_balance_args));
assert_matches!(captured.result, Ok(_));
assert!(captured.contains(&format!("nam: {}", 2000000)));
}

Ok(())
}

/// Test submission and vote of a PGF proposal
///
/// 1. Submit proposal
Expand Down Expand Up @@ -1719,7 +1819,7 @@ fn enforce_fee_payment() -> Result<()> {
}
// Finalize the next block to execute the txs
node.clear_results();
node.finalize_and_commit();
node.finalize_and_commit(None);
{
let results = node.results.lock().unwrap();
for result in results.iter() {
Expand Down Expand Up @@ -2028,7 +2128,7 @@ fn scheduled_migration() -> Result<()> {
}

while node.block_height().0 != 4 {
node.finalize_and_commit()
node.finalize_and_commit(None)
}
// check that the key doesn't exist before the scheduled block
let rt = tokio::runtime::Runtime::new().unwrap();
Expand All @@ -2045,7 +2145,7 @@ fn scheduled_migration() -> Result<()> {
assert!(bytes.is_empty());

// check that the key now exists and has the expected value
node.finalize_and_commit();
node.finalize_and_commit(None);
let rt = tokio::runtime::Runtime::new().unwrap();
let bytes = rt
.block_on(RPC.shell().storage_value(
Expand Down
2 changes: 1 addition & 1 deletion crates/tests/src/integration/masp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1527,7 +1527,7 @@ fn multiple_unfetched_txs_same_block() -> Result<()> {
}
// Finalize the next block to actually execute the decrypted txs
node.clear_results();
node.finalize_and_commit();
node.finalize_and_commit(None);
{
let results = node.results.lock().unwrap();
for result in results.iter() {
Expand Down
Loading