-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* implement state comparison job * rename to validate_state * Panic if state is invalid * extract validator to its own binary * fix query * undo imprter changes * improve config * fix seed * Implement get_slots_sample for inmemory * fix pg seed * make inmemory get_slots_sample behave like postgres' * refactor * validate concurrently * fmt * rename get_slots_sample * is_contract * fmt
- Loading branch information
1 parent
72e53f9
commit 595428d
Showing
14 changed files
with
368 additions
and
3 deletions.
There are no files selected for viewing
43 changes: 43 additions & 0 deletions
43
.sqlx/query-13a8805112acd60f7a2cda1f468f9cb51ea244b95a376ef962c5c2932e9b15a4.json
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
use std::sync::Arc; | ||
use std::time::Duration; | ||
|
||
use rand::Rng; | ||
use stratus::config::StateValidatorConfig; | ||
use stratus::config::ValidatorMethodConfig; | ||
use stratus::eth::primitives::BlockNumber; | ||
use stratus::eth::storage::StratusStorage; | ||
use stratus::infra::BlockchainClient; | ||
use stratus::init_global_services; | ||
use tokio::task::JoinSet; | ||
|
||
const RPC_TIMEOUT: Duration = Duration::from_secs(2); | ||
|
||
#[tokio::main(flavor = "current_thread")] | ||
async fn main() -> anyhow::Result<()> { | ||
// init services | ||
let config: StateValidatorConfig = init_global_services(); | ||
let storage = config.init_storage().await?; | ||
|
||
let interval = BlockNumber::from(config.interval); | ||
|
||
let mut latest_compared_block = BlockNumber::ZERO; | ||
|
||
let mut futures = JoinSet::new(); | ||
loop { | ||
let current_block = storage.read_current_block_number().await?; | ||
if current_block - latest_compared_block >= interval && futures.len() < config.concurrent_tasks as usize { | ||
let future = validate_state( | ||
config.method.clone(), | ||
Arc::clone(&storage), | ||
latest_compared_block, | ||
latest_compared_block + interval, | ||
config.sample_size, | ||
config.seed, | ||
); | ||
|
||
futures.spawn(future); | ||
|
||
latest_compared_block = latest_compared_block + interval; | ||
} else if let Some(res) = futures.join_next().await { | ||
res??; | ||
} | ||
} | ||
} | ||
|
||
async fn validate_state( | ||
method: ValidatorMethodConfig, | ||
storage: Arc<StratusStorage>, | ||
start: BlockNumber, | ||
end: BlockNumber, | ||
max_sample_size: u64, | ||
seed: u64, | ||
) -> anyhow::Result<()> { | ||
match method { | ||
ValidatorMethodConfig::Rpc { url } => { | ||
let chain = BlockchainClient::new(&url, RPC_TIMEOUT)?; | ||
validate_state_rpc(&chain, storage, start, end, max_sample_size, seed).await | ||
} | ||
_ => todo!(), | ||
} | ||
} | ||
|
||
async fn validate_state_rpc( | ||
chain: &BlockchainClient, | ||
storage: Arc<StratusStorage>, | ||
start: BlockNumber, | ||
end: BlockNumber, | ||
max_sample_size: u64, | ||
seed: u64, | ||
) -> anyhow::Result<()> { | ||
tracing::debug!("Validating state {:?}, {:?}", start, end); | ||
let seed = match seed { | ||
0 => { | ||
let mut rng = rand::thread_rng(); | ||
rng.gen() | ||
} | ||
n => n, | ||
}; | ||
let slots = storage.read_slots_sample(start, end, max_sample_size, seed).await?; | ||
for sampled_slot in slots { | ||
let expected_value = chain | ||
.get_storage_at( | ||
&sampled_slot.address, | ||
&sampled_slot.index, | ||
stratus::eth::primitives::StoragePointInTime::Past(sampled_slot.block_number), | ||
) | ||
.await?; | ||
|
||
if sampled_slot.value != expected_value { | ||
return Err(anyhow::anyhow!( | ||
"State mismatch on slot {:?}, expected value: {:?}, found: {:?}", | ||
sampled_slot, | ||
expected_value, | ||
sampled_slot.value | ||
)); | ||
} | ||
} | ||
Ok(()) | ||
} |
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
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
Oops, something went wrong.