-
Notifications
You must be signed in to change notification settings - Fork 192
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
feat(entropy): Entropy inspection #1588
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
use { | ||
crate::{ | ||
chain::ethereum::{ | ||
PythContract, | ||
Request, | ||
}, | ||
config::{ | ||
Config, | ||
EthereumConfig, | ||
InspectOptions, | ||
}, | ||
}, | ||
anyhow::Result, | ||
ethers::{ | ||
contract::Multicall, | ||
middleware::Middleware, | ||
prelude::{ | ||
Http, | ||
Provider, | ||
}, | ||
}, | ||
}; | ||
|
||
pub async fn inspect(opts: &InspectOptions) -> Result<()> { | ||
match opts.chain_id.clone() { | ||
Some(chain_id) => { | ||
let chain_config = &Config::load(&opts.config.config)?.get_chain_config(&chain_id)?; | ||
inspect_chain(chain_config, opts.num_requests).await?; | ||
} | ||
None => { | ||
let config = Config::load(&opts.config.config)?; | ||
for (chain_id, chain_config) in config.chains.iter() { | ||
println!("Inspecting chain: {}", chain_id); | ||
inspect_chain(chain_config, opts.num_requests).await?; | ||
} | ||
} | ||
} | ||
Ok(()) | ||
} | ||
|
||
async fn inspect_chain(chain_config: &EthereumConfig, num_requests: u64) -> Result<()> { | ||
let rpc_provider = Provider::<Http>::try_from(&chain_config.geth_rpc_addr)?; | ||
let multicall_exists = rpc_provider | ||
.get_code(ethers::contract::MULTICALL_ADDRESS, None) | ||
.await | ||
.expect("Failed to get code") | ||
.len() | ||
> 0; | ||
|
||
let contract = PythContract::from_config(chain_config)?; | ||
let entropy_provider = contract.get_default_provider().call().await?; | ||
let provider_info = contract.get_provider_info(entropy_provider).call().await?; | ||
let mut current_request_number = provider_info.sequence_number; | ||
println!("Initial request number: {}", current_request_number); | ||
let last_request_number = current_request_number.saturating_sub(num_requests); | ||
if multicall_exists { | ||
println!("Using multicall"); | ||
let mut multicall = Multicall::new( | ||
rpc_provider.clone(), | ||
Some(ethers::contract::MULTICALL_ADDRESS), | ||
) | ||
.await?; | ||
let batch_size = 100; | ||
while current_request_number > last_request_number { | ||
multicall.clear_calls(); | ||
for _ in 0..batch_size { | ||
if current_request_number == 0 { | ||
break; | ||
} | ||
multicall.add_call( | ||
contract.get_request(entropy_provider, current_request_number), | ||
false, | ||
); | ||
current_request_number -= 1; | ||
} | ||
let return_data: Vec<Request> = multicall.call_array().await?; | ||
for request in return_data { | ||
process_request(rpc_provider.clone(), request).await?; | ||
} | ||
println!("Current request number: {}", current_request_number); | ||
} | ||
} else { | ||
println!("Multicall not deployed in this chain, fetching requests one by one"); | ||
while current_request_number > last_request_number { | ||
let request = contract | ||
.get_request(entropy_provider, current_request_number) | ||
.call() | ||
.await?; | ||
process_request(rpc_provider.clone(), request).await?; | ||
current_request_number -= 1; | ||
if current_request_number % 100 == 0 { | ||
println!("Current request number: {}", current_request_number); | ||
} | ||
} | ||
} | ||
Ok(()) | ||
} | ||
|
||
async fn process_request(rpc_provider: Provider<Http>, request: Request) -> Result<()> { | ||
if request.sequence_number != 0 && request.is_request_with_callback { | ||
let block = rpc_provider | ||
.get_block(request.block_number) | ||
.await? | ||
.expect("Block not found"); | ||
let datetime = chrono::DateTime::from_timestamp(block.timestamp.as_u64() as i64, 0) | ||
.expect("Invalid timestamp"); | ||
println!( | ||
"{} sequence_number:{} block_number:{} requester:{}", | ||
datetime, request.sequence_number, request.block_number, request.requester | ||
); | ||
} | ||
Ok(()) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,7 @@ use { | |
pub use { | ||
generate::GenerateOptions, | ||
get_request::GetRequestOptions, | ||
inspect::InspectOptions, | ||
register_provider::RegisterProviderOptions, | ||
request_randomness::RequestRandomnessOptions, | ||
run::RunOptions, | ||
|
@@ -38,6 +39,7 @@ pub use { | |
|
||
mod generate; | ||
mod get_request; | ||
mod inspect; | ||
mod register_provider; | ||
mod request_randomness; | ||
mod run; | ||
|
@@ -66,6 +68,9 @@ pub enum Options { | |
/// Request a random number from the contract. | ||
RequestRandomness(RequestRandomnessOptions), | ||
|
||
/// Inspect recent requests and find unfulfilled requests with callback. | ||
Inspect(InspectOptions), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question about this: how do I tell that the request didn't get a callback from the result? It seems like the output simply prints out all of the requests that have happened. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. any request still stored in the contract is not fulfilled yet. We just iterate through the requests and find the ones where the callback flag is also true and print them out. |
||
|
||
/// Generate a random number by running the entire protocol end-to-end | ||
Generate(GenerateOptions), | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
use { | ||
crate::{ | ||
api::ChainId, | ||
config::ConfigOptions, | ||
}, | ||
clap::Args, | ||
}; | ||
|
||
|
||
#[derive(Args, Clone, Debug)] | ||
#[command(next_help_heading = "Inspect Options")] | ||
#[group(id = "Inspect")] | ||
pub struct InspectOptions { | ||
#[command(flatten)] | ||
pub config: ConfigOptions, | ||
|
||
/// Check the requests on this chain, or all chains if not specified. | ||
#[arg(long = "chain-id")] | ||
pub chain_id: Option<ChainId>, | ||
|
||
/// The number of requests to inspect starting from the most recent request. | ||
#[arg(long = "num-requests", default_value = "1000")] | ||
pub num_requests: u64, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggest putting this in InspectOptions with a default value, just in case it needs to be changed later.