-
Notifications
You must be signed in to change notification settings - Fork 632
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add integration tests and get shard_uid with runtime adapter
- Loading branch information
Showing
9 changed files
with
166 additions
and
91 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,4 @@ mod runtimes; | |
#[cfg(feature = "sandbox")] | ||
mod sandbox; | ||
mod sharding_upgrade; | ||
mod undo_block; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
use near_chain::{ | ||
ChainGenesis, ChainStore, ChainStoreAccess, Provenance, RuntimeWithEpochManagerAdapter, | ||
}; | ||
use near_chain_configs::Genesis; | ||
use near_client::test_utils::TestEnv; | ||
use near_o11y::testonly::init_test_logger; | ||
use near_store::test_utils::create_test_store; | ||
use near_store::Store; | ||
use near_undo_block::undo_block; | ||
use nearcore::config::GenesisExt; | ||
use std::path::Path; | ||
use std::sync::Arc; | ||
|
||
/// Setup environment with one Near client for testing. | ||
fn setup_env(genesis: &Genesis, store: Store) -> (TestEnv, Arc<dyn RuntimeWithEpochManagerAdapter>) { | ||
let chain_genesis = ChainGenesis::new(genesis); | ||
let runtimes: Vec<Arc<dyn RuntimeWithEpochManagerAdapter>> = | ||
vec![nearcore::NightshadeRuntime::test(Path::new("../../../.."), store, genesis)]; | ||
(TestEnv::builder(chain_genesis).runtime_adapters(runtimes.clone()).build(), runtimes[0].clone()) | ||
} | ||
|
||
fn test_undo_block(epoch_length: u64, stop_height: u64) { | ||
init_test_logger(); | ||
|
||
let save_trie_changes = true; | ||
|
||
let mut genesis = Genesis::test(vec!["test0".parse().unwrap(), "test1".parse().unwrap()], 1); | ||
genesis.config.epoch_length = epoch_length; | ||
|
||
let store = create_test_store(); | ||
let (mut env, runtime) = setup_env(&genesis, store.clone()); | ||
|
||
for i in 1..stop_height + 1 { | ||
let block = env.clients[0].produce_block(i).unwrap().unwrap(); | ||
// blocks.push(block.clone()); | ||
env.process_block(0, block, Provenance::PRODUCED); | ||
} | ||
|
||
let mut chain_store = | ||
ChainStore::new(store.clone(), genesis.config.genesis_height, save_trie_changes); | ||
|
||
let current_head = chain_store.head().unwrap(); | ||
let prev_block_hash = current_head.prev_block_hash; | ||
|
||
undo_block(&mut chain_store, &*runtime).unwrap(); | ||
|
||
// after undo, the current head should be the prev_block_hash | ||
assert_eq!(chain_store.head().unwrap().last_block_hash.as_bytes(), prev_block_hash.as_bytes()); | ||
assert_eq!(chain_store.head().unwrap().height, stop_height - 1); | ||
|
||
// set up an environment again with the same store | ||
let (mut env, _) = setup_env(&genesis, store.clone()); | ||
// the new env should be able to produce block normally | ||
let block = env.clients[0].produce_block(stop_height).unwrap().unwrap(); | ||
env.process_block(0, block, Provenance::PRODUCED); | ||
|
||
// after processing the new block, the head should now be at stop_height | ||
assert_eq!(chain_store.head().unwrap().height, stop_height); | ||
} | ||
|
||
#[test] | ||
fn test_undo_block_middle_of_epoch() { | ||
test_undo_block(5, 3) | ||
} | ||
|
||
#[test] | ||
fn test_undo_block_end_of_epoch() { | ||
test_undo_block(5, 5) | ||
} | ||
|
||
#[test] | ||
fn test_undo_block_start_of_epoch() { | ||
test_undo_block(5, 6) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
use nearcore::NightshadeRuntime; | ||
use near_chain::ChainStore; | ||
use near_chain_configs::GenesisValidationMode; | ||
use near_store::{Mode, NodeStorage}; | ||
use nearcore::load_config; | ||
use std::path::Path; | ||
|
||
#[derive(clap::Parser)] | ||
pub struct UndoBlockCommand {} | ||
|
||
impl UndoBlockCommand { | ||
pub fn run( | ||
self, | ||
home_dir: &Path, | ||
genesis_validation: GenesisValidationMode, | ||
) -> anyhow::Result<()> { | ||
let near_config = load_config(home_dir, genesis_validation) | ||
.unwrap_or_else(|e| panic!("Error loading config: {:#}", e)); | ||
|
||
let store_opener = NodeStorage::opener( | ||
home_dir, | ||
near_config.config.archive, | ||
&near_config.config.store, | ||
None, | ||
); | ||
|
||
let storage = store_opener.open_in_mode(Mode::ReadWrite).unwrap(); | ||
let store = storage.get_hot_store(); | ||
|
||
let runtime = NightshadeRuntime::from_config(home_dir, store.clone(), &near_config); | ||
|
||
let mut chain_store = ChainStore::new( | ||
store, | ||
near_config.genesis.config.genesis_height, | ||
near_config.client_config.save_trie_changes, | ||
); | ||
|
||
crate::undo_block(&mut chain_store, &*runtime) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,78 +1,46 @@ | ||
use chrono::Utc; | ||
use near_chain::RuntimeWithEpochManagerAdapter; | ||
use near_chain::types::LatestKnown; | ||
use near_chain::{ChainStore, ChainStoreAccess, ChainStoreUpdate}; | ||
use near_chain_configs::GenesisValidationMode; | ||
use near_primitives::block::Tip; | ||
use near_primitives::utils::to_timestamp; | ||
use near_store::{Mode, NodeStorage}; | ||
use nearcore::load_config; | ||
use std::path::Path; | ||
|
||
#[derive(clap::Parser)] | ||
pub struct UndoBlockCommand {} | ||
pub mod cli; | ||
|
||
impl UndoBlockCommand { | ||
pub fn run( | ||
self, | ||
home_dir: &Path, | ||
genesis_validation: GenesisValidationMode, | ||
) -> anyhow::Result<()> { | ||
let near_config = load_config(home_dir, genesis_validation) | ||
.unwrap_or_else(|e| panic!("Error loading config: {:#}", e)); | ||
pub fn undo_block(chain_store: &mut ChainStore, runtime: &dyn RuntimeWithEpochManagerAdapter) -> anyhow::Result<()> { | ||
let current_head = chain_store.head()?; | ||
let current_head_hash = current_head.last_block_hash; | ||
let prev_block_hash = current_head.prev_block_hash; | ||
let prev_header = chain_store.get_block_header(&prev_block_hash)?; | ||
let prev_tip = Tip::from_header(&prev_header); | ||
let current_head_height = current_head.height; | ||
let prev_block_height = prev_tip.height; | ||
|
||
let store_opener = NodeStorage::opener( | ||
home_dir, | ||
near_config.config.archive, | ||
&near_config.config.store, | ||
None, | ||
); | ||
tracing::info!(target: "neard", ?prev_block_hash, ?current_head_hash, ?prev_block_height, ?current_head_height, "Trying to update head"); | ||
|
||
let storage = store_opener.open_in_mode(Mode::ReadWrite).unwrap(); | ||
let store = storage.get_hot_store(); | ||
|
||
let mut chain_store = ChainStore::new( | ||
store, | ||
near_config.genesis.config.genesis_height, | ||
near_config.client_config.save_trie_changes, | ||
); | ||
|
||
let current_head = chain_store.head()?; | ||
let current_head_hash = current_head.last_block_hash; | ||
let prev_block_hash = current_head.prev_block_hash; | ||
let prev_header = chain_store.get_block_header(&prev_block_hash)?; | ||
let prev_tip = Tip::from_header(&prev_header); | ||
let current_head_height = current_head.height; | ||
let prev_block_height = prev_tip.height; | ||
|
||
tracing::info!(target: "neard", ?prev_block_hash, ?current_head_hash, "Trying to update head"); | ||
tracing::info!(target: "neard", ?prev_block_height, ?current_head_height, "Trying to update head"); | ||
|
||
// stop if it's already the final block | ||
if chain_store.final_head()?.height >= current_head.height { | ||
return Err(anyhow::anyhow!("Cannot revert past final block")); | ||
} | ||
// stop if it's already the final block | ||
if chain_store.final_head()?.height >= current_head.height { | ||
return Err(anyhow::anyhow!("Cannot revert past final block")); | ||
} | ||
|
||
let mut chain_store_update = ChainStoreUpdate::new(&mut chain_store); | ||
let mut chain_store_update = ChainStoreUpdate::new(chain_store); | ||
|
||
// clear block data for current head | ||
chain_store_update.clear_block_data_undo_block(current_head_hash)?; | ||
chain_store_update.clear_head_block_data(runtime)?; | ||
|
||
chain_store_update.save_head(&prev_tip)?; | ||
chain_store_update.save_head(&prev_tip)?; | ||
|
||
chain_store_update.commit()?; | ||
chain_store_update.commit()?; | ||
|
||
chain_store.save_latest_known(LatestKnown { | ||
height: prev_tip.height, | ||
seen: to_timestamp(Utc::now()), | ||
})?; | ||
chain_store.save_latest_known(LatestKnown { | ||
height: prev_tip.height, | ||
seen: to_timestamp(Utc::now()), | ||
})?; | ||
|
||
let new_chain_store_head = chain_store.head()?; | ||
let new_chain_store_header_head = chain_store.header_head()?; | ||
let new_head_height = new_chain_store_head.height; | ||
let new_header_height = new_chain_store_header_head.height; | ||
let new_chain_store_head = chain_store.head()?; | ||
let new_chain_store_header_head = chain_store.header_head()?; | ||
let new_head_height = new_chain_store_head.height; | ||
let new_header_height = new_chain_store_header_head.height; | ||
|
||
tracing::info!(target: "neard", ?new_head_height, ?new_header_height, "The current chain store shows"); | ||
tracing::info!(target: "neard", ?new_header_height, "The current chain store shows header head height"); | ||
Ok(()) | ||
} | ||
tracing::info!(target: "neard", ?new_head_height, ?new_header_height, "The current chain store shows"); | ||
Ok(()) | ||
} |