Skip to content

Commit a4333da

Browse files
authored
fix(entropy): Fix Event definitions to maintain backward compatibility (#2616)
* duplicating structs and old events * fix signatures? * fix event signatures * cleanup * forgot a file * generate ABI * add missing abi * fix ABI stuff in fortuna * CLI for testing * hmm * cleanup * minor fixes
1 parent 3e39dda commit a4333da

File tree

18 files changed

+319
-207
lines changed

18 files changed

+319
-207
lines changed

apps/fortuna/src/chain/ethereum.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,38 @@ impl<T: JsonRpcClient + 'static + Clone> SignablePythContractInner<T> {
9393
}
9494
}
9595

96+
/// Submit a request for a random number to the contract.
97+
///
98+
/// This method is a version of the autogenned `request` method that parses the emitted logs
99+
/// to return the sequence number of the created Request.
100+
pub async fn request_with_callback_wrapper(
101+
&self,
102+
provider: &Address,
103+
user_randomness: &[u8; 32],
104+
) -> Result<u64> {
105+
let fee = self.get_fee(*provider).call().await?;
106+
107+
if let Some(r) = self
108+
.request_with_callback(*provider, *user_randomness)
109+
.value(fee)
110+
.send()
111+
.await?
112+
.await?
113+
{
114+
// Extract Log from TransactionReceipt.
115+
let l: RawLog = r.logs[0].clone().into();
116+
if let PythRandomEvents::RequestedWithCallbackFilter(r) =
117+
PythRandomEvents::decode_log(&l)?
118+
{
119+
Ok(r.request.sequence_number)
120+
} else {
121+
Err(anyhow!("No log with sequence number"))
122+
}
123+
} else {
124+
Err(anyhow!("Request failed"))
125+
}
126+
}
127+
96128
/// Reveal the generated random number to the contract.
97129
///
98130
/// This method is a version of the autogenned `reveal` method that parses the emitted logs

apps/fortuna/src/command/generate.rs

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use {
22
crate::{
3-
api::GetRandomValueResponse,
4-
chain::ethereum::SignablePythContract,
3+
chain::ethereum::{RevealedWithCallbackFilter, SignablePythContract},
54
config::{Config, GenerateOptions},
65
},
76
anyhow::Result,
87
base64::{engine::general_purpose::STANDARD as base64_standard_engine, Engine as _},
8+
ethers::providers::Middleware,
99
std::sync::Arc,
10+
tokio::time::{self, Duration},
1011
};
1112

1213
/// Run the entire random number generation protocol to produce a random number.
@@ -22,42 +23,54 @@ pub async fn generate(opts: &GenerateOptions) -> Result<()> {
2223
let user_randomness = rand::random::<[u8; 32]>();
2324
let provider = opts.provider;
2425

26+
let mut last_block_number = contract.provider().get_block_number().await?;
27+
tracing::info!(block_number = last_block_number.as_u64(), "block number");
28+
29+
tracing::info!("Requesting random number...");
30+
2531
// Request a random number on the contract
2632
let sequence_number = contract
27-
.request_wrapper(&provider, &user_randomness, opts.blockhash)
33+
.request_with_callback_wrapper(&provider, &user_randomness)
2834
.await?;
2935

30-
tracing::info!(sequence_number = sequence_number, "random number requested",);
36+
tracing::info!(sequence_number = sequence_number, "Random number requested",);
3137

32-
// Get the committed value from the provider
33-
let resp = reqwest::get(opts.url.join(&format!(
34-
"/v1/chains/{}/revelations/{}",
35-
opts.chain_id, sequence_number
36-
))?)
37-
.await?
38-
.json::<GetRandomValueResponse>()
39-
.await?;
38+
let mut num_retries = 0;
39+
let mut found_request = false;
40+
while !found_request && num_retries < 10 {
41+
let current_block_number = contract.provider().get_block_number().await?;
42+
tracing::info!(
43+
start_block = last_block_number.as_u64(),
44+
end_block = current_block_number.as_u64(),
45+
"Checking events between blocks."
46+
);
4047

41-
tracing::info!(
42-
response = base64_standard_engine.encode(resp.value.data()),
43-
"Retrieved the provider's random value.",
44-
);
45-
let provider_randomness = resp.value.data();
46-
47-
// Submit the provider's and our values to the contract to reveal the random number.
48-
let random_value = contract
49-
.reveal_wrapper(
50-
&provider,
51-
sequence_number,
52-
&user_randomness,
53-
provider_randomness,
54-
)
55-
.await?;
48+
let mut event = contract.revealed_with_callback_filter();
49+
event.filter = event
50+
.filter
51+
.from_block(last_block_number)
52+
.to_block(current_block_number);
5653

57-
tracing::info!(
58-
number = base64_standard_engine.encode(random_value),
59-
"Random number generated."
60-
);
54+
let res: Vec<RevealedWithCallbackFilter> = event.query().await?;
55+
56+
for r in res.iter() {
57+
if r.request.sequence_number == sequence_number && r.request.provider == provider {
58+
tracing::info!(
59+
number = base64_standard_engine.encode(r.random_number),
60+
"Random number generated."
61+
);
62+
found_request = true;
63+
}
64+
}
65+
66+
last_block_number = current_block_number;
67+
num_retries += 1;
68+
time::sleep(Duration::from_secs(1)).await;
69+
}
70+
71+
if !found_request {
72+
tracing::info!("Failed to receive a callback with the random number.");
73+
}
6174

6275
Ok(())
6376
}

apps/fortuna/src/command/inspect.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use {
22
crate::{
3-
chain::ethereum::{PythContract, Request},
3+
chain::ethereum::{EntropyStructsV2Request, PythContract},
44
config::{Config, EthereumConfig, InspectOptions},
55
},
66
anyhow::Result,
@@ -66,7 +66,7 @@ async fn inspect_chain(
6666
);
6767
current_request_number -= 1;
6868
}
69-
let return_data: Vec<Request> = multicall.call_array().await?;
69+
let return_data: Vec<EntropyStructsV2Request> = multicall.call_array().await?;
7070
for request in return_data {
7171
process_request(rpc_provider.clone(), request).await?;
7272
}
@@ -89,7 +89,10 @@ async fn inspect_chain(
8989
Ok(())
9090
}
9191

92-
async fn process_request(rpc_provider: Provider<Http>, request: Request) -> Result<()> {
92+
async fn process_request(
93+
rpc_provider: Provider<Http>,
94+
request: EntropyStructsV2Request,
95+
) -> Result<()> {
9396
if request.sequence_number != 0 && request.callback_status != 0 {
9497
let block = rpc_provider
9598
.get_block(request.block_number)

apps/fortuna/src/command/setup_provider.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use {
22
crate::{
33
api::{get_register_uri, ChainId},
4-
chain::ethereum::{ProviderInfo, SignablePythContract},
4+
chain::ethereum::{EntropyStructsV2ProviderInfo, SignablePythContract},
55
command::register_provider::{register_provider_from_config, CommitmentMetadata},
66
config::{Config, EthereumConfig, SetupProviderOptions},
77
state::{HashChainState, PebbleHashChain},
@@ -178,7 +178,7 @@ async fn setup_chain_provider(
178178

179179
async fn sync_uri(
180180
contract: &Arc<SignablePythContract>,
181-
provider_info: &ProviderInfo,
181+
provider_info: &EntropyStructsV2ProviderInfo,
182182
uri: String,
183183
) -> Result<()> {
184184
let uri_as_bytes: Bytes = AbiBytes::from(uri.as_str()).into();
@@ -198,7 +198,7 @@ async fn sync_uri(
198198

199199
async fn sync_fee(
200200
contract: &Arc<SignablePythContract>,
201-
provider_info: &ProviderInfo,
201+
provider_info: &EntropyStructsV2ProviderInfo,
202202
provider_fee: u128,
203203
) -> Result<()> {
204204
if provider_info.fee_in_wei != provider_fee {
@@ -217,7 +217,7 @@ async fn sync_fee(
217217

218218
async fn sync_fee_manager(
219219
contract: &Arc<SignablePythContract>,
220-
provider_info: &ProviderInfo,
220+
provider_info: &EntropyStructsV2ProviderInfo,
221221
fee_manager: Address,
222222
) -> Result<()> {
223223
if provider_info.fee_manager != fee_manager {
@@ -231,7 +231,7 @@ async fn sync_fee_manager(
231231

232232
async fn sync_max_num_hashes(
233233
contract: &Arc<SignablePythContract>,
234-
provider_info: &ProviderInfo,
234+
provider_info: &EntropyStructsV2ProviderInfo,
235235
max_num_hashes: u32,
236236
) -> Result<()> {
237237
if provider_info.max_num_hashes != max_num_hashes {

apps/fortuna/src/config.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ mod setup_provider;
2525
mod withdraw_fees;
2626

2727
const DEFAULT_RPC_ADDR: &str = "127.0.0.1:34000";
28-
const DEFAULT_HTTP_ADDR: &str = "http://127.0.0.1:34000";
2928

3029
#[derive(Parser, Debug)]
3130
#[command(name = crate_name!())]

apps/fortuna/src/config/generate.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use {
22
crate::{api::ChainId, config::ConfigOptions},
33
clap::Args,
44
ethers::types::Address,
5-
reqwest::Url,
65
};
76

87
#[derive(Args, Clone, Debug)]
@@ -27,11 +26,4 @@ pub struct GenerateOptions {
2726
/// Submit a randomness request to this provider
2827
#[arg(long = "provider")]
2928
pub provider: Address,
30-
31-
#[arg(long = "url")]
32-
#[arg(default_value = super::DEFAULT_HTTP_ADDR)]
33-
pub url: Url,
34-
35-
#[arg(short = 'b')]
36-
pub blockhash: bool,
3729
}

0 commit comments

Comments
 (0)