Skip to content

Commit

Permalink
Merge branch 'tiago/fix-eth-event-decoding' (#1852)
Browse files Browse the repository at this point in the history
  • Loading branch information
sug0 committed Aug 30, 2023
2 parents 5941b6b + 9a0320c commit b9cd7b3
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Fix the decoding of events observed by the Ethereum oracle
([\#1852](https://github.com/anoma/namada/pull/1852))
25 changes: 12 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ directories = "4.0.1"
ed25519-consensus = "1.2.0"
escargot = "0.5.7"
ethabi = "18.0.0"
ethbridge-bridge-contract = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.22.0"}
ethbridge-bridge-events = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.22.0"}
ethbridge-events = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.22.0"}
ethbridge-governance-contract = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.22.0"}
ethbridge-governance-events = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.22.0"}
ethbridge-structs = { git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.22.0" }
ethbridge-bridge-contract = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.23.0"}
ethbridge-bridge-events = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.23.0"}
ethbridge-events = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.23.0"}
ethbridge-governance-contract = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.23.0"}
ethbridge-governance-events = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.23.0"}
ethbridge-structs = { git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.23.0" }
ethers = "2.0.0"
expectrl = "0.7.0"
eyre = "0.6.5"
Expand Down
26 changes: 10 additions & 16 deletions apps/src/lib/node/ledger/ethereum_oracle/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,9 @@ pub mod eth_events {
TRANSFER_TO_ERC_CODEC, TRANSFER_TO_NAMADA_CODEC,
VALIDATOR_SET_UPDATE_CODEC,
};
use namada::eth_bridge::ethers::abi::AbiEncode;

use super::*;
use crate::node::ledger::ethereum_oracle::test_tools::event_log::GetLog;

/// Test that for Ethereum events for which a custom number of
/// confirmations may be specified, if a value lower than the
Expand All @@ -350,7 +350,7 @@ pub mod eth_events {
let pending_event = PendingEvent::decode(
codec,
arbitrary_block_height,
&get_log(event.encode()),
&event.get_log(),
min_confirmations.clone(),
)?;

Expand Down Expand Up @@ -397,7 +397,10 @@ pub mod eth_events {
];

let raw: TransferToNamadaFilter = TRANSFER_TO_NAMADA_CODEC
.decode(&get_log(data))
.decode(&ethabi::RawLog {
topics: vec![TransferToNamadaFilter::signature()],
data,
})
.expect("Test failed")
.try_into()
.expect("Test failed");
Expand Down Expand Up @@ -433,7 +436,7 @@ pub mod eth_events {
let pending_event = PendingEvent::decode(
codec,
arbitrary_block_height,
&get_log(event.encode()),
&event.get_log(),
min_confirmations,
)
.unwrap();
Expand Down Expand Up @@ -534,7 +537,7 @@ pub mod eth_events {
{
let decoded: TransferToNamadaFilter =
TRANSFER_TO_NAMADA_CODEC
.decode(&get_log(nam_transfers.clone().encode()))
.decode(&nam_transfers.clone().get_log())
.expect("Test failed")
.try_into()
.expect("Test failed");
Expand All @@ -545,7 +548,7 @@ pub mod eth_events {
assert_eq!(
{
let decoded: TransferToErcFilter = TRANSFER_TO_ERC_CODEC
.decode(&get_log(eth_transfers.clone().encode()))
.decode(&eth_transfers.clone().get_log())
.expect("Test failed")
.try_into()
.expect("Test failed");
Expand All @@ -557,7 +560,7 @@ pub mod eth_events {
{
let decoded: ValidatorSetUpdateFilter =
VALIDATOR_SET_UPDATE_CODEC
.decode(&get_log(update.clone().encode()))
.decode(&update.clone().get_log())
.expect("Test failed")
.try_into()
.expect("Test failed");
Expand All @@ -566,15 +569,6 @@ pub mod eth_events {
update
);
}

/// Return an Ethereum events log, from the given encoded event
/// data.
fn get_log(data: Vec<u8>) -> ethabi::RawLog {
ethabi::RawLog {
data,
topics: vec![],
}
}
}
}

Expand Down
18 changes: 9 additions & 9 deletions apps/src/lib/node/ledger/ethereum_oracle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,6 @@ mod test_oracle {
use ethbridge_bridge_events::{
TransferToErcFilter, TransferToNamadaFilter,
};
use namada::eth_bridge::ethers::abi::AbiEncode;
use namada::eth_bridge::ethers::types::H160;
use namada::eth_bridge::structs::Erc20Transfer;
use namada::types::address::testing::gen_established_address;
Expand All @@ -575,6 +574,7 @@ mod test_oracle {
use tokio::time::timeout;

use super::*;
use crate::node::ledger::ethereum_oracle::test_tools::event_log::GetLog;
use crate::node::ledger::ethereum_oracle::test_tools::mock_web3_client::{
event_signature, TestCmd, TestOracle, Web3Client, Web3Controller,
};
Expand Down Expand Up @@ -716,11 +716,11 @@ mod test_oracle {
valid_map: vec![],
confirmations: 100.into(),
}
.encode();
.get_log();
let (sender, _) = channel();
controller.apply_cmd(TestCmd::NewEvent {
event_type: event_signature::<TransferToNamadaFilter>(),
data: new_event,
log: new_event,
height: 101,
seen: sender,
});
Expand Down Expand Up @@ -766,11 +766,11 @@ mod test_oracle {
valid_map: vec![],
confirmations: 100.into(),
}
.encode();
.get_log();
let (sender, mut seen) = channel();
controller.apply_cmd(TestCmd::NewEvent {
event_type: event_signature::<TransferToNamadaFilter>(),
data: new_event,
log: new_event,
height: 150,
seen: sender,
});
Expand Down Expand Up @@ -821,7 +821,7 @@ mod test_oracle {
valid_map: vec![],
confirmations: 100.into(),
}
.encode();
.get_log();

// confirmed after 125 blocks
let gas_payer = gen_established_address();
Expand All @@ -836,20 +836,20 @@ mod test_oracle {
relayer_address: gas_payer.to_string(),
nonce: 0.into(),
}
.encode();
.get_log();

// send in the events to the logs
let (sender, seen_second) = channel();
controller.apply_cmd(TestCmd::NewEvent {
event_type: event_signature::<TransferToErcFilter>(),
data: second_event,
log: second_event,
height: 125,
seen: sender,
});
let (sender, _recv) = channel();
controller.apply_cmd(TestCmd::NewEvent {
event_type: event_signature::<TransferToNamadaFilter>(),
data: first_event,
log: first_event,
height: 100,
seen: sender,
});
Expand Down
76 changes: 66 additions & 10 deletions apps/src/lib/node/ledger/ethereum_oracle/test_tools/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,64 @@
pub mod events_endpoint;

#[cfg(test)]
pub mod event_log {
// praise be unto thee whom'st've read and understand this code
// p.s.: https://medium.com/mycrypto/understanding-event-logs-on-the-ethereum-blockchain-f4ae7ba50378

use ethbridge_bridge_events::{
TransferToErcFilter, TransferToNamadaFilter,
};
use ethbridge_governance_events::ValidatorSetUpdateFilter;
use namada::eth_bridge::ethers::abi::AbiEncode;
use namada::eth_bridge::ethers::contract::EthEvent;

/// Get an [`ethabi::RawLog`] from a given Ethereum event.
pub trait GetLog {
/// Return an [`ethabi::RawLog`].
fn get_log(self) -> ethabi::RawLog;
}

impl GetLog for TransferToNamadaFilter {
fn get_log(self) -> ethabi::RawLog {
ethabi::RawLog {
topics: vec![Self::signature()],
data: self.encode(),
}
}
}

impl GetLog for TransferToErcFilter {
fn get_log(self) -> ethabi::RawLog {
ethabi::RawLog {
topics: vec![Self::signature(), {
let mut buf = [0; 32];
self.nonce.to_big_endian(&mut buf);
ethabi::ethereum_types::H256(buf)
}],
data: (self.transfers, self.valid_map, self.relayer_address)
.encode(),
}
}
}

impl GetLog for ValidatorSetUpdateFilter {
fn get_log(self) -> ethabi::RawLog {
ethabi::RawLog {
topics: vec![Self::signature(), {
let mut buf = [0; 32];
self.validator_set_nonce.to_big_endian(&mut buf);
ethabi::ethereum_types::H256(buf)
}],
data: (
self.bridge_validator_set_hash,
self.governance_validator_set_hash,
)
.encode(),
}
}
}
}

#[cfg(test)]
pub mod mock_web3_client {
use std::borrow::Cow;
Expand Down Expand Up @@ -32,7 +91,7 @@ pub mod mock_web3_client {
NewHeight(Uint256),
NewEvent {
event_type: MockEventType,
data: Vec<u8>,
log: ethabi::RawLog,
height: u32,
seen: Sender<()>,
},
Expand Down Expand Up @@ -60,10 +119,10 @@ pub mod mock_web3_client {
}
TestCmd::NewEvent {
event_type: ty,
data,
log,
height,
seen,
} => oracle.events.push((ty, data, height, seen)),
} => oracle.events.push((ty, log, height, seen)),
}
}
}
Expand All @@ -82,7 +141,7 @@ pub mod mock_web3_client {
pub struct Web3ClientInner {
active: bool,
latest_block_height: Uint256,
events: Vec<(MockEventType, Vec<u8>, u32, Sender<()>)>,
events: Vec<(MockEventType, ethabi::RawLog, u32, Sender<()>)>,
blocks_processed: UnboundedSender<Uint256>,
last_block_processed: Option<Uint256>,
}
Expand Down Expand Up @@ -116,16 +175,13 @@ pub mod mock_web3_client {
let mut logs = vec![];
let mut events = vec![];
std::mem::swap(&mut client.events, &mut events);
for (event_ty, data, height, seen) in events.into_iter() {
for (event_ty, log, height, seen) in events.into_iter() {
if event_ty == ty && block_to_check >= Uint256::from(height)
{
seen.send(()).unwrap();
logs.push(ethabi::RawLog {
data,
topics: vec![],
});
logs.push(log);
} else {
client.events.push((event_ty, data, height, seen));
client.events.push((event_ty, log, height, seen));
}
}
if client.last_block_processed.as_ref() < Some(&block_to_check)
Expand Down
Loading

0 comments on commit b9cd7b3

Please sign in to comment.