diff --git a/.github/workflows/scripts/e2e.json b/.github/workflows/scripts/e2e.json index d28f9d75de..8e5abce2ad 100644 --- a/.github/workflows/scripts/e2e.json +++ b/.github/workflows/scripts/e2e.json @@ -14,6 +14,7 @@ "e2e::ledger_tests::implicit_account_reveal_pk": 30, "e2e::ledger_tests::pos_init_validator": 40, "e2e::ledger_tests::proposal_offline": 21, + "e2e::ledger_tests::rollback": 21, "e2e::ledger_tests::pgf_governance_proposal": 320, "e2e::ledger_tests::proposal_submission": 200, "e2e::ledger_tests::proposal_change_shielded_reward": 200, diff --git a/crates/apps/src/lib/node/ledger/storage/rocksdb.rs b/crates/apps/src/lib/node/ledger/storage/rocksdb.rs index 549a844d30..7cc9cafd78 100644 --- a/crates/apps/src/lib/node/ledger/storage/rocksdb.rs +++ b/crates/apps/src/lib/node/ledger/storage/rocksdb.rs @@ -12,11 +12,13 @@ //! epoch can start //! - `next_epoch_min_start_time`: minimum block time from which the next //! epoch can start -//! - `replay_protection`: hashes of the processed transactions +//! - `update_epoch_blocks_delay`: number of missing blocks before updating +//! PoS with CometBFT //! - `pred`: predecessor values of the top-level keys of the same name //! - `tx_queue` //! - `next_epoch_min_start_height` //! - `next_epoch_min_start_time` +//! - `update_epoch_blocks_delay` //! - `conversion_state`: MASP conversion state //! - `subspace`: accounts sub-spaces //! - `{address}/{dyn}`: any byte data associated with accounts @@ -518,6 +520,7 @@ impl RocksDB { for metadata_key in [ "next_epoch_min_start_height", "next_epoch_min_start_time", + "update_epoch_blocks_delay", "tx_queue", ] { let previous_key = format!("pred/{}", metadata_key); @@ -531,7 +534,7 @@ impl RocksDB { // NOTE: we cannot restore the "pred/" keys themselves since we // don't have their predecessors in storage, but there's no need to // since we cannot do more than one rollback anyway because of - // Tendermint. + // CometBFT. } // Revert conversion state if the epoch had been changed diff --git a/crates/tests/src/e2e/ledger_tests.rs b/crates/tests/src/e2e/ledger_tests.rs index 4273f180ee..d14cfa7ef2 100644 --- a/crates/tests/src/e2e/ledger_tests.rs +++ b/crates/tests/src/e2e/ledger_tests.rs @@ -4231,3 +4231,92 @@ where Ok(result) } + +#[test] +fn rollback() -> Result<()> { + let test = setup::network( + |genesis, base_dir| { + setup::set_validators(1, genesis, base_dir, default_port_offset) + }, + // slow block production rate + Some("5s"), + )?; + set_ethereum_bridge_mode( + &test, + &test.net.chain_id, + Who::Validator(0), + ethereum_bridge::ledger::Mode::Off, + None, + ); + + // 1. Run the ledger node once + let mut ledger = + start_namada_ledger_node_wait_wasm(&test, Some(0), Some(40))?; + + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); + + // wait for a commited block + ledger.exp_regex("Committed block hash: .*,")?; + + let ledger = ledger.background(); + + // send a few transactions + let txs_args = vec![vec![ + "transfer", + "--source", + BERTHA, + "--target", + ALBERT, + "--token", + NAM, + "--amount", + "10.1", + "--signing-keys", + BERTHA_KEY, + "--node", + &validator_one_rpc, + ]]; + + for tx_args in &txs_args { + let mut client = run!(test, Bin::Client, tx_args, Some(40))?; + client.exp_string(TX_APPLIED_SUCCESS)?; + client.assert_success(); + } + + // shut the ledger down + let mut ledger = ledger.foreground(); + ledger.interrupt()?; + drop(ledger); + + // restart and take the app hash + height + // TODO: check that the height matches the one at which the last transaction + // was applied + let mut ledger = start_namada_ledger_node(&test, Some(0), Some(40))?; + let (_, matched_one) = + ledger.exp_regex("Last state root hash: .*, height: .*")?; + + // wait for a block and stop the ledger + ledger.exp_regex("Committed block hash: .*,")?; + ledger.interrupt()?; + drop(ledger); + + // run rollback + let mut rollback = run_as!( + test, + Who::Validator(0), + Bin::Node, + &["ledger", "rollback"], + Some(40) + )?; + rollback.exp_eof().unwrap(); + + // restart ledger and check that the app hash is the same as before the + // rollback + let mut ledger = start_namada_ledger_node(&test, Some(0), Some(40))?; + let (_, matched_two) = + ledger.exp_regex("Last state root hash: .*, height: .*")?; + + assert_eq!(matched_one, matched_two); + + Ok(()) +} diff --git a/wasm/checksums.json b/wasm/checksums.json index 976b6b08dd..d1460cd2be 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,26 +1,26 @@ { - "tx_become_validator.wasm": "tx_become_validator.9e1581a717be270c9b336e8e4a05902b545656bd4bb2ef7e4b076ba7799df881.wasm", - "tx_bond.wasm": "tx_bond.e4aef7917fdc861b395bdf794940936c6b3475bd3fb7b19ebc6739d21496dbc8.wasm", - "tx_bridge_pool.wasm": "tx_bridge_pool.aee3981b50e51d53ca77dcb7e1804f561172a4a6be988d2c4b582cae68f880fa.wasm", - "tx_change_consensus_key.wasm": "tx_change_consensus_key.4c91bd00e96ba51f0eb544a22bc633af42a50cf6b80f9250a2a53c59c570ffb6.wasm", - "tx_change_validator_commission.wasm": "tx_change_validator_commission.657b039436f54c0c909eb8b9ad89597aaf97d8a3f7db0815adb4ec7783cb276f.wasm", - "tx_change_validator_metadata.wasm": "tx_change_validator_metadata.35e648a95ad6d08d505c359d1f2448ebfe0853564e7f4504df1df7ac31037d0f.wasm", - "tx_claim_rewards.wasm": "tx_claim_rewards.8435a4c9c5d4f4ac934f1bbc002adaf97dd6ec484caa04d8324497bf11787812.wasm", - "tx_deactivate_validator.wasm": "tx_deactivate_validator.41370c15473827b391ecd2c12bef3fedd461dc12e1e5e81914113d032ea3fc3a.wasm", - "tx_ibc.wasm": "tx_ibc.331fc15363137fb5f5c2236be928c50d7240ea5b31311b4accafffd3adb5fb96.wasm", - "tx_init_account.wasm": "tx_init_account.bff39a666b66bdabb89e2a26717e0e044254e27603df4909256e42ace1cd2531.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.bd852c9a30b71570ffb3a58e3d4e37b749c793bc1def46501b8b71a2ae6740bd.wasm", - "tx_reactivate_validator.wasm": "tx_reactivate_validator.3aad7fdfcdaea68e7f67e3e02b0a211caa3694f8782342d13afb00e86a8a7663.wasm", - "tx_redelegate.wasm": "tx_redelegate.13c9f7a4290dec2821fc7e23cd74926c6cc4a3adfef36e084aed41f262f2cb12.wasm", - "tx_resign_steward.wasm": "tx_resign_steward.3b3172994453feb494506af62567368bdb3619192ceaed0c73cf39418dc68e1e.wasm", - "tx_reveal_pk.wasm": "tx_reveal_pk.b540eaeff830b227d126e5ff246d978e87f50fcdb0e2fc22155563875a2fec91.wasm", - "tx_transfer.wasm": "tx_transfer.0ec5f718c7f695937402b25452b59b174021f42567b6e4cb22bec4427b913d08.wasm", - "tx_unbond.wasm": "tx_unbond.1afd1145d1c43a093882d9cc2518986e7f46a0192b006c17fd997c19ab405a43.wasm", - "tx_unjail_validator.wasm": "tx_unjail_validator.7efdc35af561c5846d73b83e8f8dac4cadf803e134361083658f8b96caaa2ffa.wasm", - "tx_update_account.wasm": "tx_update_account.99da4d1cc91b1819a93c97e647bfecbefc34bcc153bc6ee31e09311c4239ce37.wasm", - "tx_update_steward_commission.wasm": "tx_update_steward_commission.c197b2c43016adff69c41ca5e33c938971c648777e42afdf2bef688a2c827685.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.1ffc6aed4848972a1cdec9f3188ae1e6737ca824183f217396ded631efe7baaa.wasm", - "tx_withdraw.wasm": "tx_withdraw.cd0cfdbc9d7454864eb1ff12ae971b995b9deb04df4b450f1364c5081853cefb.wasm", - "vp_implicit.wasm": "vp_implicit.64511b9db10869a77342071a58129695ed55ccab12383602b5002d333972b8a5.wasm", - "vp_user.wasm": "vp_user.3497e62040090bf6e39fb8b9a2dc7478abb95d0201ab5dd58bc66119c84565ce.wasm" + "tx_become_validator.wasm": "tx_become_validator.48fe3e03530d5491b157c1887b2b277bd925ba8e5f95ae316451300fde12319e.wasm", + "tx_bond.wasm": "tx_bond.94d9920fba3789158900425d0ea778dfd9bcfc9a17a2848b251f2f35f07db136.wasm", + "tx_bridge_pool.wasm": "tx_bridge_pool.5d29a4c5095d3769391df24e04f1b8820faa1e85ce0f4ba4fd401609f3a968d3.wasm", + "tx_change_consensus_key.wasm": "tx_change_consensus_key.edb63363ca6bd5ca86d0dd7d7fd71f1975d624e3a219b0c403e49fa855900b16.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.43d8ea26e377ae8af98dafaa5758077b204a3d81ebbcc55113f092001050acee.wasm", + "tx_change_validator_metadata.wasm": "tx_change_validator_metadata.b548320f4500ae2653d45ed3789c7ddc97c3d96d30d7359642a45caa8acb9f6c.wasm", + "tx_claim_rewards.wasm": "tx_claim_rewards.70cd2e086d3a5dfaa287a14d7679e8e174ef3b4f5951752e3f9751c826c85934.wasm", + "tx_deactivate_validator.wasm": "tx_deactivate_validator.06093d25fa11ae8e21183d7d6e746f8ffeb71e952978d247e206f1ea74987008.wasm", + "tx_ibc.wasm": "tx_ibc.537f4d0604a1fd3845bcb184f92054c89420094944707f60ddd3accc7e086807.wasm", + "tx_init_account.wasm": "tx_init_account.712dae9b52f2c88704fa7b3d9b0f382375c7c96d5a664c091cf2c2a155ae449b.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.21d9ef56bfec09928c27997bbab727bcded9b5f23d7b3b1d92b207dcfb339b80.wasm", + "tx_reactivate_validator.wasm": "tx_reactivate_validator.1e1bb1f90e6d2b37571d2632f6b04e558edeadba43bb116e17fcca609d97adf7.wasm", + "tx_redelegate.wasm": "tx_redelegate.9c41750435db5dbcf327099e8163ff03afdbdb4d6a31a1724314f52c69c6387a.wasm", + "tx_resign_steward.wasm": "tx_resign_steward.89aef0322689b36ad615b81d2f17662f8cf8f42200a7694920188f6c7697c11a.wasm", + "tx_reveal_pk.wasm": "tx_reveal_pk.e67e1a1e8139783675aabc8959703472b8e50f8705c7539298cbddbda274d11a.wasm", + "tx_transfer.wasm": "tx_transfer.c4d6a2724918f3d92c55a9025a605863daad04ebc92c1b1aadcdf87756e5b2a7.wasm", + "tx_unbond.wasm": "tx_unbond.d7255b1ee52208bfd37f052e13766fad743b1ab2bcab704bd945df486dc4af01.wasm", + "tx_unjail_validator.wasm": "tx_unjail_validator.aa946d1eecdaa8c0789ba0b86392688af43d510202c0beed34093d9846e66587.wasm", + "tx_update_account.wasm": "tx_update_account.39226e2856466ee79d12be4c36320af0a6625ec53fed9fd4be597f40dca4ec89.wasm", + "tx_update_steward_commission.wasm": "tx_update_steward_commission.ec1b7213f686e4c038552b6a8ffd646316c34f92b0afbf6fd8c0373bdc53ae44.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.58d27b1e4728165c8719431adc1f82b4920a34ebe24ac5721a76242cb3277ea5.wasm", + "tx_withdraw.wasm": "tx_withdraw.8809b5f3428a7b18656bed66a02dbc8a6a3a58111676921fd759efd6f69b5b22.wasm", + "vp_implicit.wasm": "vp_implicit.53c564192f3b53c51107519843c78f76b5a27111509d78201a7b2037e4e5dd90.wasm", + "vp_user.wasm": "vp_user.33a6d043bc34186cde8b79f815892bd71f26ff4b6afe38a546e1cf9c5dec42ce.wasm" } \ No newline at end of file