Skip to content

Commit

Permalink
fix(bridge): prevent ignoring data requests
Browse files Browse the repository at this point in the history
fix #2388
  • Loading branch information
aesedepece committed Aug 14, 2023
1 parent bd6c130 commit 35b797d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 22 deletions.
9 changes: 2 additions & 7 deletions bridges/centralized-ethereum/src/actors/dr_database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ pub struct DrInfoBridge {
}

/// Data request state
#[derive(Serialize, Deserialize, Clone)]
#[derive(Clone, Default, Serialize, Deserialize)]
pub enum DrState {
/// New: the data request has just been posted to the smart contract.
#[default]
New,
/// Pending: the data request has been created and broadcast to witnet, but it has not been
/// included in a witnet block yet.
Expand All @@ -77,12 +78,6 @@ impl fmt::Display for DrState {
}
}

impl Default for DrState {
fn default() -> Self {
Self::New
}
}

/// Data request states in Witnet Request Board contract
#[derive(Serialize, Deserialize, Clone)]
pub enum WitnetQueryStatus {
Expand Down
46 changes: 31 additions & 15 deletions bridges/centralized-ethereum/src/actors/eth_poller.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
actors::dr_database::{
DrDatabase, DrInfoBridge, DrState, GetLastDrId, SetDrInfoBridge, WitnetQueryStatus,
DrDatabase, DrInfoBridge, GetLastDrId, SetDrInfoBridge, WitnetQueryStatus,
},
config::Config,
};
Expand Down Expand Up @@ -127,18 +127,22 @@ impl EthPoller {
}
WitnetQueryStatus::Posted => {
log::info!("[{}] new dr in wrb", i);
if let Some(set_dr_info_bridge) =
if let Ok(set_dr_info_bridge) =
process_posted_request(i.into(), &wrb_contract).await
{
dr_database_addr.do_send(set_dr_info_bridge);
} else {
break;
}
}
WitnetQueryStatus::Reported => {
log::debug!("[{}] already reported", i);
if let Some(set_dr_info_bridge) =
if let Ok(set_dr_info_bridge) =
process_posted_request(i.into(), &wrb_contract).await
{
dr_database_addr.do_send(set_dr_info_bridge);
} else {
break;
}
}
WitnetQueryStatus::Deleted => {
Expand Down Expand Up @@ -175,7 +179,7 @@ impl EthPoller {
async fn process_posted_request(
query_id: U256,
wrb_contract: &Contract<web3::transports::Http>,
) -> Option<SetDrInfoBridge> {
) -> Result<SetDrInfoBridge, web3::contract::Error> {
let dr_bytes: Result<Bytes, web3::contract::Error> = wrb_contract
.query(
"readRequestBytecode",
Expand All @@ -186,20 +190,32 @@ async fn process_posted_request(
)
.await;

// Re-route some errors as success (explanation below)
match dr_bytes {
Ok(dr_bytes) => Some(SetDrInfoBridge(
query_id,
DrInfoBridge {
dr_bytes,
dr_state: DrState::New,
dr_tx_hash: None,
dr_tx_creation_timestamp: None,
},
)),
Ok(dr_bytes) => Ok(dr_bytes),
Err(err) => {
log::error!("Fail to read dr bytes from contract: {}", err.to_string());

None
// In some versions of the bridge contracts (those based on
// `WitnetRequestBoardTrustableBase`), we may get a revert when trying to fetch the dr
// bytes for a deleted query.
// If that's the case, we can return a success here, with empty bytes, so that the
// request can locally marked as complete, and we can move on.
if err.to_string().contains("WitnetRequestBoardTrustableBase") {
log::error!("Wait! This is an instance of `WitnetRequestBoardTrustableBase`. Let's assume we got a revert because the dr bytes were deleted, and simply move on.");

Ok(Default::default())
// Otherwise, handle the error normally
} else {
Err(err)
}
}
}
// Wrap the dr bytes in a `SetDrInfoBridge` structure
}.map(|dr_bytes| SetDrInfoBridge(
query_id,
DrInfoBridge {
dr_bytes,
..Default::default()
},
))
}

0 comments on commit 35b797d

Please sign in to comment.