From 3f1eaa8b2854815726315cd28233e03918b68e6c Mon Sep 17 00:00:00 2001 From: Amin Moghaddam Date: Mon, 20 May 2024 11:08:10 +0200 Subject: [PATCH 1/4] feat(fortuna): Utility command to check for unfulfilled requests with callback --- apps/fortuna/Cargo.lock | 91 ++++++++++++++++++---- apps/fortuna/Cargo.toml | 1 + apps/fortuna/src/command.rs | 2 + apps/fortuna/src/command/inspect.rs | 115 ++++++++++++++++++++++++++++ apps/fortuna/src/config.rs | 5 ++ apps/fortuna/src/config/inspect.rs | 26 +++++++ apps/fortuna/src/main.rs | 1 + 7 files changed, 228 insertions(+), 13 deletions(-) create mode 100644 apps/fortuna/src/command/inspect.rs create mode 100644 apps/fortuna/src/config/inspect.rs diff --git a/apps/fortuna/Cargo.lock b/apps/fortuna/Cargo.lock index b584a452bc..52b58a238d 100644 --- a/apps/fortuna/Cargo.lock +++ b/apps/fortuna/Cargo.lock @@ -552,15 +552,15 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "serde", - "windows-targets", + "windows-targets 0.52.5", ] [[package]] @@ -1497,6 +1497,7 @@ dependencies = [ "base64 0.21.4", "bincode", "byteorder", + "chrono", "clap", "ethabi", "ethers", @@ -2533,7 +2534,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -4448,7 +4449,7 @@ version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -4457,7 +4458,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -4466,13 +4467,29 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -4481,42 +4498,90 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + [[package]] name = "winnow" version = "0.5.16" diff --git a/apps/fortuna/Cargo.toml b/apps/fortuna/Cargo.toml index 145700587a..1c1501002d 100644 --- a/apps/fortuna/Cargo.toml +++ b/apps/fortuna/Cargo.toml @@ -34,6 +34,7 @@ utoipa-swagger-ui = { version = "3.1.4", features = ["axum"] } once_cell = "1.18.0" lazy_static = "1.4.0" url = "2.5.0" +chrono = { version = "0.4.38", features = ["clock", "std"] , default-features = false} [dev-dependencies] diff --git a/apps/fortuna/src/command.rs b/apps/fortuna/src/command.rs index a5170a8a52..f5285d6609 100644 --- a/apps/fortuna/src/command.rs +++ b/apps/fortuna/src/command.rs @@ -1,5 +1,6 @@ mod generate; mod get_request; +mod inspect; mod register_provider; mod request_randomness; mod run; @@ -8,6 +9,7 @@ mod setup_provider; pub use { generate::generate, get_request::get_request, + inspect::inspect, register_provider::register_provider, request_randomness::request_randomness, run::run, diff --git a/apps/fortuna/src/command/inspect.rs b/apps/fortuna/src/command/inspect.rs new file mode 100644 index 0000000000..22385c0e0f --- /dev/null +++ b/apps/fortuna/src/command/inspect.rs @@ -0,0 +1,115 @@ +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 contract = PythContract::from_config(chain_config)?; + + let rpc_provider = Provider::::try_from(&chain_config.geth_rpc_addr)?; + let entropy_provider = contract.get_default_provider().call().await?; + + let provider_info = contract.get_provider_info(entropy_provider).call().await?; + + let multicall_exists = rpc_provider + .get_code(ethers::contract::MULTICALL_ADDRESS, None) + .await + .expect("Failed to get code") + .len() + > 0; + 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 = 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, 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(()) +} diff --git a/apps/fortuna/src/config.rs b/apps/fortuna/src/config.rs index ead14c72d0..1a02bc92bc 100644 --- a/apps/fortuna/src/config.rs +++ b/apps/fortuna/src/config.rs @@ -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), + /// Generate a random number by running the entire protocol end-to-end Generate(GenerateOptions), diff --git a/apps/fortuna/src/config/inspect.rs b/apps/fortuna/src/config/inspect.rs new file mode 100644 index 0000000000..97e0e5859c --- /dev/null +++ b/apps/fortuna/src/config/inspect.rs @@ -0,0 +1,26 @@ +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")] + #[arg(env = "FORTUNA_CHAIN_ID")] + pub chain_id: Option, + + /// The number of requests to inspect starting from the most recent request. + /// Default: 1000 + #[arg(long = "num-requests", default_value = "1000")] + pub num_requests: u64, +} diff --git a/apps/fortuna/src/main.rs b/apps/fortuna/src/main.rs index 4cd2475043..65f9901ecc 100644 --- a/apps/fortuna/src/main.rs +++ b/apps/fortuna/src/main.rs @@ -42,5 +42,6 @@ async fn main() -> Result<()> { config::Options::RegisterProvider(opts) => command::register_provider(&opts).await, config::Options::SetupProvider(opts) => command::setup_provider(&opts).await, config::Options::RequestRandomness(opts) => command::request_randomness(&opts).await, + config::Options::Inspect(opts) => command::inspect(&opts).await, } } From 3cb060016973a66339ac55102e2dba04cc55b2ed Mon Sep 17 00:00:00 2001 From: Amin Moghaddam Date: Tue, 21 May 2024 12:31:36 +0200 Subject: [PATCH 2/4] feat(fortuna): utility scripts for debugging reveal issues --- .../scripts/entropy_debug_reveal.ts | 68 +++++++++++++++++++ contract_manager/src/contracts/evm.ts | 57 ++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 contract_manager/scripts/entropy_debug_reveal.ts diff --git a/contract_manager/scripts/entropy_debug_reveal.ts b/contract_manager/scripts/entropy_debug_reveal.ts new file mode 100644 index 0000000000..5102741465 --- /dev/null +++ b/contract_manager/scripts/entropy_debug_reveal.ts @@ -0,0 +1,68 @@ +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; +import { toPrivateKey } from "../src"; +import { + COMMON_DEPLOY_OPTIONS, + findEntropyContract, + findEvmChain, +} from "./common"; + +const parser = yargs(hideBin(process.argv)) + .usage( + "Tries to reveal an entropy request with callback using the provided private key.\n" + + "This can be used to manually debug why a callback was not triggered.\n" + + "Usage: $0 --chain --private-key --sequence-number " + ) + .options({ + chain: { + type: "string", + demandOption: true, + desc: "test latency for the contract on this chain", + }, + "private-key": COMMON_DEPLOY_OPTIONS["private-key"], + "sequence-number": { + type: "number", + demandOption: true, + desc: "sequence number of the request to reveal", + }, + }); + +async function main() { + const argv = await parser.argv; + const chain = findEvmChain(argv.chain); + const contract = findEntropyContract(chain); + const sequenceNumber = argv.sequenceNumber; + + const provider = await contract.getDefaultProvider(); + const providerInfo = await contract.getProviderInfo(provider); + const privateKey = toPrivateKey(argv.privateKey); + const request = await contract.getRequest(provider, sequenceNumber); + if (request.sequenceNumber === "0") { + console.log("Request not found"); + return; + } + console.log("Request block number: ", request.blockNumber); + const userRandomNumber = await contract.getUserRandomNumber( + provider, + sequenceNumber, + parseInt(request.blockNumber) + ); + console.log("User random number: ", userRandomNumber); + const revealUrl = providerInfo.uri + `/revelations/${sequenceNumber}`; + const fortunaResponse = await fetch(revealUrl); + if (fortunaResponse.status !== 200) { + console.log("Fortuna response status: ", fortunaResponse.status); + return; + } + const payload = await fortunaResponse.json(); + const providerRevelation = "0x" + payload.value.data; + await contract.revealWithCallback( + userRandomNumber, + providerRevelation, + provider, + sequenceNumber, + privateKey + ); +} + +main(); diff --git a/contract_manager/src/contracts/evm.ts b/contract_manager/src/contracts/evm.ts index d3810454ae..e6c7676936 100644 --- a/contract_manager/src/contracts/evm.ts +++ b/contract_manager/src/contracts/evm.ts @@ -489,6 +489,17 @@ interface EntropyProviderInfo { currentCommitmentSequenceNumber: string; } +interface EntropyRequest { + provider: string; + sequenceNumber: string; + numHashes: string; + commitment: string; + blockNumber: string; + requester: string; + useBlockhash: boolean; + isRequestWithCallback: boolean; +} + export class EvmEntropyContract extends Storable { static type = "EvmEntropyContract"; @@ -622,6 +633,52 @@ export class EvmEntropyContract extends Storable { }; } + async getRequest( + provider: string, + sequenceNumber: number + ): Promise { + const contract = this.getContract(); + return contract.methods.getRequest(provider, sequenceNumber).call(); + } + + async getUserRandomNumber( + provider: string, + sequenceNumber: number, + block: number + ): Promise { + const contract = this.getContract(); + const result = await contract.getPastEvents("RequestedWithCallback", { + fromBlock: block, + toBlock: block, + filter: { + provider, + sequenceNumber: sequenceNumber, + }, + }); + return result[0].returnValues.userRandomNumber; + } + + async revealWithCallback( + userRandomNumber: string, + providerRevelation: string, + provider: string, + sequenceNumber: number, + senderPrivateKey: PrivateKey + ) { + const web3 = new Web3(this.chain.getRpcUrl()); + const contract = this.getContract(); + const { address } = web3.eth.accounts.wallet.add(senderPrivateKey); + const transactionObject = contract.methods.revealWithCallback( + provider, + sequenceNumber, + userRandomNumber, + providerRevelation + ); + return this.chain.estiamteAndSendTransaction(transactionObject, { + from: address, + }); + } + generateUserRandomNumber() { const web3 = new Web3(this.chain.getRpcUrl()); return web3.utils.randomHex(32); From 343aa633ca3425d5abe6ac1a798642d9f2e0ca14 Mon Sep 17 00:00:00 2001 From: Amin Moghaddam Date: Tue, 21 May 2024 14:04:29 +0200 Subject: [PATCH 3/4] Small fixes --- apps/fortuna/src/command/inspect.rs | 10 ++++------ apps/fortuna/src/config/inspect.rs | 2 -- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/apps/fortuna/src/command/inspect.rs b/apps/fortuna/src/command/inspect.rs index 22385c0e0f..a99a331566 100644 --- a/apps/fortuna/src/command/inspect.rs +++ b/apps/fortuna/src/command/inspect.rs @@ -39,19 +39,17 @@ pub async fn inspect(opts: &InspectOptions) -> Result<()> { } async fn inspect_chain(chain_config: &EthereumConfig, num_requests: u64) -> Result<()> { - let contract = PythContract::from_config(chain_config)?; - let rpc_provider = Provider::::try_from(&chain_config.geth_rpc_addr)?; - let entropy_provider = contract.get_default_provider().call().await?; - - let provider_info = contract.get_provider_info(entropy_provider).call().await?; - 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); diff --git a/apps/fortuna/src/config/inspect.rs b/apps/fortuna/src/config/inspect.rs index 97e0e5859c..04534c8f98 100644 --- a/apps/fortuna/src/config/inspect.rs +++ b/apps/fortuna/src/config/inspect.rs @@ -16,11 +16,9 @@ pub struct InspectOptions { /// Check the requests on this chain, or all chains if not specified. #[arg(long = "chain-id")] - #[arg(env = "FORTUNA_CHAIN_ID")] pub chain_id: Option, /// The number of requests to inspect starting from the most recent request. - /// Default: 1000 #[arg(long = "num-requests", default_value = "1000")] pub num_requests: u64, } From fa2c5dade3d25410993284726e9ec20d4d7dc9be Mon Sep 17 00:00:00 2001 From: Amin Moghaddam Date: Wed, 22 May 2024 11:26:37 +0200 Subject: [PATCH 4/4] Address comments --- apps/fortuna/src/command/inspect.rs | 13 ++++++++----- apps/fortuna/src/config/inspect.rs | 4 ++++ contract_manager/src/contracts/evm.ts | 23 +++++++++++++++++++++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/apps/fortuna/src/command/inspect.rs b/apps/fortuna/src/command/inspect.rs index a99a331566..fc4caa04e0 100644 --- a/apps/fortuna/src/command/inspect.rs +++ b/apps/fortuna/src/command/inspect.rs @@ -25,20 +25,24 @@ 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?; + inspect_chain(chain_config, opts.num_requests, opts.multicall_batch_size).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?; + inspect_chain(chain_config, opts.num_requests, opts.multicall_batch_size).await?; } } } Ok(()) } -async fn inspect_chain(chain_config: &EthereumConfig, num_requests: u64) -> Result<()> { +async fn inspect_chain( + chain_config: &EthereumConfig, + num_requests: u64, + multicall_batch_size: u64, +) -> Result<()> { let rpc_provider = Provider::::try_from(&chain_config.geth_rpc_addr)?; let multicall_exists = rpc_provider .get_code(ethers::contract::MULTICALL_ADDRESS, None) @@ -60,10 +64,9 @@ async fn inspect_chain(chain_config: &EthereumConfig, num_requests: u64) -> Resu 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 { + for _ in 0..multicall_batch_size { if current_request_number == 0 { break; } diff --git a/apps/fortuna/src/config/inspect.rs b/apps/fortuna/src/config/inspect.rs index 04534c8f98..4b06895be1 100644 --- a/apps/fortuna/src/config/inspect.rs +++ b/apps/fortuna/src/config/inspect.rs @@ -21,4 +21,8 @@ pub struct InspectOptions { /// The number of requests to inspect starting from the most recent request. #[arg(long = "num-requests", default_value = "1000")] pub num_requests: u64, + + /// The number of calls to make in each batch when using multicall. + #[arg(long = "multicall-batch-size", default_value = "100")] + pub multicall_batch_size: u64, } diff --git a/contract_manager/src/contracts/evm.ts b/contract_manager/src/contracts/evm.ts index e6c7676936..f509872c8f 100644 --- a/contract_manager/src/contracts/evm.ts +++ b/contract_manager/src/contracts/evm.ts @@ -633,6 +633,12 @@ export class EvmEntropyContract extends Storable { }; } + /** + * Returns the request for the given provider and sequence number + * This will return a EntropyRequest object with sequenceNumber "0" if the request does not exist + * @param provider The entropy provider address + * @param sequenceNumber The sequence number of the request for the provider + */ async getRequest( provider: string, sequenceNumber: number @@ -641,6 +647,15 @@ export class EvmEntropyContract extends Storable { return contract.methods.getRequest(provider, sequenceNumber).call(); } + /** + * Returns the user random number for the request with the given provider and sequence number + * This method assumes the request was made with a callback option and fetches the user random number + * by finding the `RequestedWithCallback` log. The block number at which the request was made is required + * to find the log. + * @param provider The entropy provider address + * @param sequenceNumber The sequence number of the request for the provider + * @param block The block number at which the request was made, you can find this using the `getRequest` method + */ async getUserRandomNumber( provider: string, sequenceNumber: number, @@ -658,6 +673,14 @@ export class EvmEntropyContract extends Storable { return result[0].returnValues.userRandomNumber; } + /** + * Submits a transaction to the entropy contract to reveal the random number and call the callback function + * @param userRandomNumber The random number generated by the user, you can find this using the `getUserRandomNumber` method + * @param providerRevelation The random number generated by the provider, you can find this via the provider server + * @param provider The entropy provider address + * @param sequenceNumber The sequence number of the request for the provider + * @param senderPrivateKey The private key to use for submitting the transaction on-chain + */ async revealWithCallback( userRandomNumber: string, providerRevelation: string,