Skip to content

Commit 449b4c2

Browse files
authored
fix(entropy): Use the block number of event instead of request data for revelation api (#2607)
* Use the block number of event instead of request data for revelation api if provided
1 parent ad3ee4c commit 449b4c2

File tree

7 files changed

+93
-39
lines changed

7 files changed

+93
-39
lines changed

apps/entropy-debugger/src/lib/revelation.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ export async function requestCallback(
1010
chain: keyof typeof EntropyDeployments,
1111
): Promise<string> {
1212
const deployment = EntropyDeployments[chain];
13-
const { provider, sequenceNumber, userRandomNumber } = await fetchInfoFromTx(
14-
txHash,
15-
deployment,
13+
const { provider, sequenceNumber, userRandomNumber, blockNumber } =
14+
await fetchInfoFromTx(txHash, deployment);
15+
const revelation = await getRevelation(
16+
chain,
17+
blockNumber,
18+
Number(sequenceNumber),
1619
);
17-
const revelation = await getRevelation(chain, Number(sequenceNumber));
1820

1921
return `cast send ${deployment.address} 'revealWithCallback(address, uint64, bytes32, bytes32)' ${provider} ${sequenceNumber.toString()} ${userRandomNumber} ${revelation.value.data} -r ${deployment.rpc} --private-key <YOUR_PRIVATE_KEY>`;
2022
}
@@ -40,7 +42,12 @@ export async function fetchInfoFromTx(
4042
const firstLog = logs[0];
4143
if (firstLog) {
4244
const { provider, sequenceNumber, userRandomNumber } = firstLog.args;
43-
return { provider, sequenceNumber, userRandomNumber };
45+
return {
46+
provider,
47+
sequenceNumber,
48+
userRandomNumber,
49+
blockNumber: receipt.blockNumber,
50+
};
4451
} else {
4552
throw new Error(
4653
`No logs found for ${txHash}. Are you sure you send the requestCallback Transaction?`,
@@ -50,11 +57,12 @@ export async function fetchInfoFromTx(
5057

5158
export async function getRevelation(
5259
chain: keyof typeof EntropyDeployments,
60+
blockNumber: bigint,
5361
sequenceNumber: number,
5462
) {
5563
const deployment = EntropyDeployments[chain];
5664
const url = new URL(
57-
`/v1/chains/${chain}/revelations/${sequenceNumber.toString()}`,
65+
`/v1/chains/${chain}/revelations/${sequenceNumber.toString()}?block_number=${blockNumber.toString()}`,
5866
deployment.network === "mainnet"
5967
? "https://fortuna.dourolabs.app"
6068
: "https://fortuna-staging.dourolabs.app",

apps/fortuna/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/fortuna/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "fortuna"
3-
version = "7.4.10"
3+
version = "7.5.0"
44
edition = "2021"
55

66
[lib]

apps/fortuna/src/api/revelation.rs

Lines changed: 63 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::chain::reader::BlockNumber;
12
use {
23
crate::api::{ChainId, RequestLabel, RestError},
34
anyhow::Result,
@@ -30,7 +31,10 @@ params(RevelationPathParams, RevelationQueryParams)
3031
pub async fn revelation(
3132
State(state): State<crate::api::ApiState>,
3233
Path(RevelationPathParams { chain_id, sequence }): Path<RevelationPathParams>,
33-
Query(RevelationQueryParams { encoding }): Query<RevelationQueryParams>,
34+
Query(RevelationQueryParams {
35+
encoding,
36+
block_number,
37+
}): Query<RevelationQueryParams>,
3438
) -> Result<Json<GetRandomValueResponse>, RestError> {
3539
state
3640
.metrics
@@ -45,40 +49,68 @@ pub async fn revelation(
4549
.get(&chain_id)
4650
.ok_or(RestError::InvalidChainId)?;
4751

48-
let maybe_request_fut = state.contract.get_request(state.provider_address, sequence);
49-
5052
let current_block_number_fut = state
5153
.contract
5254
.get_block_number(state.confirmed_block_status);
5355

54-
let (maybe_request, current_block_number) =
55-
try_join!(maybe_request_fut, current_block_number_fut).map_err(|e| {
56-
tracing::error!(chain_id = chain_id, "RPC request failed {}", e);
57-
RestError::TemporarilyUnavailable
58-
})?;
59-
60-
match maybe_request {
61-
Some(r)
62-
if current_block_number.saturating_sub(state.reveal_delay_blocks) >= r.block_number =>
63-
{
64-
let value = &state.state.reveal(sequence).map_err(|e| {
65-
tracing::error!(
66-
chain_id = chain_id,
67-
sequence = sequence,
68-
"Reveal failed {}",
69-
e
70-
);
71-
RestError::Unknown
72-
})?;
73-
let encoded_value = Blob::new(encoding.unwrap_or(BinaryEncoding::Hex), *value);
74-
75-
Ok(Json(GetRandomValueResponse {
76-
value: encoded_value,
77-
}))
56+
match block_number {
57+
Some(block_number) => {
58+
let maybe_request_fut = state.contract.get_request_with_callback_events(
59+
block_number,
60+
block_number,
61+
state.provider_address,
62+
);
63+
64+
let (maybe_request, current_block_number) =
65+
try_join!(maybe_request_fut, current_block_number_fut).map_err(|e| {
66+
tracing::error!(chain_id = chain_id, "RPC request failed {}", e);
67+
RestError::TemporarilyUnavailable
68+
})?;
69+
70+
if current_block_number.saturating_sub(state.reveal_delay_blocks) < block_number {
71+
return Err(RestError::PendingConfirmation);
72+
}
73+
74+
maybe_request
75+
.iter()
76+
.find(|r| r.sequence_number == sequence)
77+
.ok_or(RestError::NoPendingRequest)?;
78+
}
79+
None => {
80+
let maybe_request_fut = state.contract.get_request(state.provider_address, sequence);
81+
let (maybe_request, current_block_number) =
82+
try_join!(maybe_request_fut, current_block_number_fut).map_err(|e| {
83+
tracing::error!(chain_id = chain_id, "RPC request failed {}", e);
84+
RestError::TemporarilyUnavailable
85+
})?;
86+
87+
match maybe_request {
88+
Some(r)
89+
if current_block_number.saturating_sub(state.reveal_delay_blocks)
90+
>= r.block_number =>
91+
{
92+
Ok(())
93+
}
94+
Some(_) => Err(RestError::PendingConfirmation),
95+
None => Err(RestError::NoPendingRequest),
96+
}?;
7897
}
79-
Some(_) => Err(RestError::PendingConfirmation),
80-
None => Err(RestError::NoPendingRequest),
8198
}
99+
100+
let value = &state.state.reveal(sequence).map_err(|e| {
101+
tracing::error!(
102+
chain_id = chain_id,
103+
sequence = sequence,
104+
"Reveal failed {}",
105+
e
106+
);
107+
RestError::Unknown
108+
})?;
109+
let encoded_value = Blob::new(encoding.unwrap_or(BinaryEncoding::Hex), *value);
110+
111+
Ok(Json(GetRandomValueResponse {
112+
value: encoded_value,
113+
}))
82114
}
83115

84116
#[derive(Debug, serde::Serialize, serde::Deserialize, IntoParams)]
@@ -93,6 +125,8 @@ pub struct RevelationPathParams {
93125
#[into_params(parameter_in=Query)]
94126
pub struct RevelationQueryParams {
95127
pub encoding: Option<BinaryEncoding>,
128+
#[param(value_type = u64)]
129+
pub block_number: Option<BlockNumber>,
96130
}
97131

98132
#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema)]

apps/fortuna/src/chain/ethereum.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,14 @@ impl<T: JsonRpcClient + 'static> EntropyReader for PythRandom<Provider<T>> {
276276
&self,
277277
from_block: BlockNumber,
278278
to_block: BlockNumber,
279+
provider: Address,
279280
) -> Result<Vec<RequestedWithCallbackEvent>> {
280281
let mut event = self.requested_with_callback_filter();
281-
event.filter = event.filter.from_block(from_block).to_block(to_block);
282+
event.filter = event
283+
.filter
284+
.from_block(from_block)
285+
.to_block(to_block)
286+
.topic1(provider);
282287

283288
let res: Vec<RequestedWithCallbackFilter> = event.query().await?;
284289

@@ -289,6 +294,7 @@ impl<T: JsonRpcClient + 'static> EntropyReader for PythRandom<Provider<T>> {
289294
user_random_number: r.user_random_number,
290295
provider_address: r.request.provider,
291296
})
297+
.filter(|r| r.provider_address == provider)
292298
.collect())
293299
}
294300

apps/fortuna/src/chain/reader.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ pub trait EntropyReader: Send + Sync {
5151
&self,
5252
from_block: BlockNumber,
5353
to_block: BlockNumber,
54+
provider: Address,
5455
) -> Result<Vec<RequestedWithCallbackEvent>>;
5556

5657
/// Estimate the gas required to reveal a random number with a callback.
@@ -166,6 +167,7 @@ pub mod mock {
166167
&self,
167168
_from_block: BlockNumber,
168169
_to_block: BlockNumber,
170+
_provider: Address,
169171
) -> Result<Vec<super::RequestedWithCallbackEvent>> {
170172
Ok(vec![])
171173
}

apps/fortuna/src/keeper/block.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,11 @@ pub async fn process_single_block_batch(
122122
loop {
123123
let events_res = chain_state
124124
.contract
125-
.get_request_with_callback_events(block_range.from, block_range.to)
125+
.get_request_with_callback_events(
126+
block_range.from,
127+
block_range.to,
128+
chain_state.provider_address,
129+
)
126130
.await;
127131

128132
match events_res {

0 commit comments

Comments
 (0)