diff --git a/Cargo.lock b/Cargo.lock index 1cd447fb26..8b8d027fd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1499,7 +1499,7 @@ dependencies = [ "eyre", "indenter", "once_cell", - "owo-colors", + "owo-colors 1.3.0", "tracing-error", ] @@ -1510,7 +1510,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6eee477a4a8a72f4addd4de416eb56d54bc307b284d6601bafdee1f4ea462d1" dependencies = [ "once_cell", - "owo-colors", + "owo-colors 1.3.0", "tracing-core 0.1.30", "tracing-error", ] @@ -2423,8 +2423,8 @@ dependencies = [ [[package]] name = "ethbridge-bridge-contract" -version = "0.17.0" -source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.17.0#da943c4723fb41fcae650e3fc4c0a8888f36e647" +version = "0.18.0" +source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.18.0#d49a0d110bb726c526896ff440d542585ced12f2" dependencies = [ "ethbridge-bridge-events", "ethbridge-structs", @@ -2434,8 +2434,8 @@ dependencies = [ [[package]] name = "ethbridge-bridge-events" -version = "0.17.0" -source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.17.0#da943c4723fb41fcae650e3fc4c0a8888f36e647" +version = "0.18.0" +source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.18.0#d49a0d110bb726c526896ff440d542585ced12f2" dependencies = [ "ethabi", "ethbridge-structs", @@ -2445,8 +2445,8 @@ dependencies = [ [[package]] name = "ethbridge-events" -version = "0.17.0" -source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.17.0#da943c4723fb41fcae650e3fc4c0a8888f36e647" +version = "0.18.0" +source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.18.0#d49a0d110bb726c526896ff440d542585ced12f2" dependencies = [ "ethbridge-bridge-events", "ethbridge-governance-events", @@ -2456,8 +2456,8 @@ dependencies = [ [[package]] name = "ethbridge-governance-contract" -version = "0.17.0" -source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.17.0#da943c4723fb41fcae650e3fc4c0a8888f36e647" +version = "0.18.0" +source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.18.0#d49a0d110bb726c526896ff440d542585ced12f2" dependencies = [ "ethbridge-governance-events", "ethbridge-structs", @@ -2467,8 +2467,8 @@ dependencies = [ [[package]] name = "ethbridge-governance-events" -version = "0.17.0" -source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.17.0#da943c4723fb41fcae650e3fc4c0a8888f36e647" +version = "0.18.0" +source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.18.0#d49a0d110bb726c526896ff440d542585ced12f2" dependencies = [ "ethabi", "ethbridge-structs", @@ -2478,8 +2478,8 @@ dependencies = [ [[package]] name = "ethbridge-structs" -version = "0.17.0" -source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.17.0#da943c4723fb41fcae650e3fc4c0a8888f36e647" +version = "0.18.0" +source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.18.0#d49a0d110bb726c526896ff440d542585ced12f2" dependencies = [ "ethabi", "ethers", @@ -4815,6 +4815,7 @@ dependencies = [ "num_cpus", "once_cell", "orion", + "owo-colors 3.5.0", "parse_duration", "proptest", "prost", @@ -5582,6 +5583,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2386b4ebe91c2f7f51082d4cefa145d030e33a1842a96b12e4885cc3c01f7a55" +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + [[package]] name = "pairing" version = "0.21.0" diff --git a/apps/Cargo.toml b/apps/Cargo.toml index 9b13c39bee..0ab36b01a0 100644 --- a/apps/Cargo.toml +++ b/apps/Cargo.toml @@ -98,11 +98,11 @@ data-encoding = "2.3.2" derivative = "2.2.0" ed25519-consensus = "1.2.0" ethabi = "18.0.0" -ethbridge-bridge-contract = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.17.0"} -ethbridge-bridge-events = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.17.0"} -ethbridge-events = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.17.0"} -ethbridge-governance-contract = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.17.0"} -ethbridge-governance-events = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.17.0"} +ethbridge-bridge-contract = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.18.0"} +ethbridge-bridge-events = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.18.0"} +ethbridge-events = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.18.0"} +ethbridge-governance-contract = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.18.0"} +ethbridge-governance-events = {git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.18.0"} ferveo = {git = "https://github.com/anoma/ferveo", rev = "9e5e91c954158e7cff45c483fd06cd649a81553f"} ferveo-common = {git = "https://github.com/anoma/ferveo", rev = "9e5e91c954158e7cff45c483fd06cd649a81553f"} eyre = "0.6.5" @@ -120,6 +120,7 @@ num-traits = "0.2.14" num_cpus = "1.13.0" once_cell = "1.8.0" orion = "0.16.0" +owo-colors = "3.5.0" parse_duration = "2.1.1" prost = "0.9.0" prost-types = "0.9.0" diff --git a/apps/src/lib/client/eth_bridge/bridge_pool.rs b/apps/src/lib/client/eth_bridge/bridge_pool.rs index 430b9126c8..92e72819df 100644 --- a/apps/src/lib/client/eth_bridge/bridge_pool.rs +++ b/apps/src/lib/client/eth_bridge/bridge_pool.rs @@ -16,6 +16,8 @@ use namada::types::eth_bridge_pool::{ }; use namada::types::keccak::KeccakHash; use namada::types::token::Amount; +use namada::types::voting_power::FractionalVotingPower; +use owo_colors::OwoColorize; use serde::{Deserialize, Serialize}; use tokio::time::{Duration, Instant}; @@ -159,20 +161,27 @@ async fn construct_bridge_pool_proof( .unwrap(); let warnings: Vec<_> = in_progress - .keys() - .filter_map(|k| { - let hash = PendingTransfer::from(k).keccak256(); - transfers.contains(&hash).then_some(hash) + .into_iter() + .filter_map(|(ref transfer, voting_power)| { + if voting_power > FractionalVotingPower::ONE_THIRD { + let hash = PendingTransfer::from(transfer).keccak256(); + transfers.contains(&hash).then_some(hash) + } else { + None + } }) .collect(); if !warnings.is_empty() { + let warning = "Warning".on_yellow(); + let warning = warning.bold(); + let warning = warning.blink(); println!( - "\x1b[93mWarning: The following hashes correspond to transfers \ - \nthat have been relayed but do not yet have a quorum of \ - \nvalidator signatures; thus they are still in the bridge \ - pool:\n\x1b[0m{:?}", - warnings + "{warning}: The following hashes correspond to transfers that \ + have surpassed the security threshold in Namada, therefore have \ + likely been relayed, but do not yet have a quorum of validator \ + signatures behind them; thus they are still in the Bridge \ + pool:\n{warnings:?}", ); print!("\nDo you wish to proceed? (y/n): "); std::io::stdout().flush().unwrap(); @@ -278,12 +287,15 @@ pub async fn relay_bridge_pool_proof(args: args::RelayBridgePoolProof) { .await { Ok(address) => Bridge::new(address.address, eth_client), - error => { + Err(err_msg) => { + let error = "Error".on_red(); + let error = error.bold(); + let error = error.blink(); println!( - "Failed to retreive the Ethereum Bridge smart contract \ - address from storage with reason:\n{:?}\n\nPerhaps the \ - Ethereum bridge is not active.", - error + "{error}: Failed to retrieve the Ethereum Bridge smart \ + contract address from storage with \ + reason:\n{err_msg}\n\nPerhaps the Ethereum bridge is not \ + active.", ); safe_exit(1) } @@ -297,6 +309,24 @@ pub async fn relay_bridge_pool_proof(args: args::RelayBridgePoolProof) { } }; + // NOTE: this operation costs no gas on Ethereum + let contract_nonce = + bridge.transfer_to_erc_20_nonce().call().await.unwrap(); + + if contract_nonce != bp_proof.batch_nonce { + let warning = "Warning".on_yellow(); + let warning = warning.bold(); + let warning = warning.blink(); + println!( + "{warning}: The Bridge pool nonce in the smart contract is \ + {contract_nonce}, while the nonce in Namada is still {}. A relay \ + of the former one has already happened, but a proof has yet to \ + be crafted in Namada.", + bp_proof.batch_nonce + ); + safe_exit(1) + } + let mut relay_op = bridge.transfer_to_erc(bp_proof); if let Some(gas) = args.gas { relay_op.tx.set_gas(gas); @@ -325,7 +355,6 @@ mod recommendations { use namada::types::vote_extensions::validator_set_update::{ EthAddrBook, VotingPowersMap, VotingPowersMapExt, }; - use namada::types::voting_power::FractionalVotingPower; use super::*; const TRANSFER_FEE: i64 = 37_500; diff --git a/core/Cargo.toml b/core/Cargo.toml index 18553c3235..c3e2e342c8 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -74,7 +74,7 @@ data-encoding = "2.3.2" derivative = "2.2.0" ed25519-consensus = "1.2.0" ethabi = "18.0.0" -ethbridge-structs = { git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.17.0" } +ethbridge-structs = { git = "https://github.com/heliaxdev/ethbridge-rs", tag = "v0.18.0" } eyre = "0.6.8" ferveo = {optional = true, git = "https://github.com/anoma/ferveo", rev = "9e5e91c954158e7cff45c483fd06cd649a81553f"} ferveo-common = {git = "https://github.com/anoma/ferveo", rev = "9e5e91c954158e7cff45c483fd06cd649a81553f"} diff --git a/shared/src/ledger/queries/shell/eth_bridge.rs b/shared/src/ledger/queries/shell/eth_bridge.rs index 80fbd56d45..5bd3187756 100644 --- a/shared/src/ledger/queries/shell/eth_bridge.rs +++ b/shared/src/ledger/queries/shell/eth_bridge.rs @@ -365,8 +365,8 @@ where ..Default::default() }) } + Ok(_) => unreachable!(), Err(e) => Err(storage_api::Error::new(e)), - _ => unreachable!(), } } else { Err(storage_api::Error::SimpleMessage( @@ -404,10 +404,25 @@ where } }) { + // we checked above that key is not empty, so this write is fine + *key.segments.last_mut().unwrap() = + DbKeySeg::StringSeg(Keys::segments().seen.into()); + // check if the event has been seen + let is_seen = ctx + .wl_storage + .read::(&key) + .into_storage_result()? + .expect( + "Iterating over storage should not yield keys without values.", + ); + if is_seen { + continue; + } + if let Ok(EthereumEvent::TransfersToEthereum { transfers, .. }) = EthereumEvent::try_from_slice(&value) { - // We checked above that key is not empty + // read the voting power behind the event *key.segments.last_mut().unwrap() = DbKeySeg::StringSeg(Keys::segments().voting_power.into()); let voting_power = ctx @@ -1206,6 +1221,10 @@ mod test_ethbridge_router { .expect("Test failed"), ) .expect("Test failed"); + client + .wl_storage + .write(ð_msg_key.seen(), false) + .expect("Test failed"); // commit the changes and increase block height client .wl_storage diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index a15075ca56..6db214aac6 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -1746,8 +1746,8 @@ dependencies = [ [[package]] name = "ethbridge-structs" -version = "0.17.0" -source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.17.0#da943c4723fb41fcae650e3fc4c0a8888f36e647" +version = "0.18.0" +source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.18.0#d49a0d110bb726c526896ff440d542585ced12f2" dependencies = [ "ethabi", "ethers", diff --git a/wasm_for_tests/wasm_source/Cargo.lock b/wasm_for_tests/wasm_source/Cargo.lock index bed689705a..bfd54c576b 100644 --- a/wasm_for_tests/wasm_source/Cargo.lock +++ b/wasm_for_tests/wasm_source/Cargo.lock @@ -1746,8 +1746,8 @@ dependencies = [ [[package]] name = "ethbridge-structs" -version = "0.17.0" -source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.17.0#da943c4723fb41fcae650e3fc4c0a8888f36e647" +version = "0.18.0" +source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.18.0#d49a0d110bb726c526896ff440d542585ced12f2" dependencies = [ "ethabi", "ethers",