From 7bca9b5d55060b3cde59c49b6fa35da986918313 Mon Sep 17 00:00:00 2001 From: satan Date: Tue, 8 Nov 2022 15:12:11 +0100 Subject: [PATCH 01/28] [fix]: Renaming xan to nam --- tests/src/native_vp/eth_bridge_pool.rs | 8 ++++---- wasm/wasm_source/src/tx_bridge_pool.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/src/native_vp/eth_bridge_pool.rs b/tests/src/native_vp/eth_bridge_pool.rs index f2045177c8..f65595dbe3 100644 --- a/tests/src/native_vp/eth_bridge_pool.rs +++ b/tests/src/native_vp/eth_bridge_pool.rs @@ -11,7 +11,7 @@ mod test_bridge_pool_vp { use namada::ledger::eth_bridge::storage::wrapped_erc20s; use namada::ledger::eth_bridge::ADDRESS; use namada::proto::Tx; - use namada::types::address::{wnam, xan}; + use namada::types::address::{nam, wnam}; use namada::types::eth_bridge_pool::{ GasFee, PendingTransfer, TransferToEthereum, }; @@ -80,18 +80,18 @@ mod test_bridge_pool_vp { // initialize Ethereum bridge storage config.init_storage(&mut env.storage); // initialize Bertha's account - env.spawn_accounts([&albert_address(), &bertha_address(), &xan()]); + env.spawn_accounts([&albert_address(), &bertha_address(), &nam()]); // enrich Albert env.credit_tokens( &albert_address(), - &xan(), + &nam(), None, BERTHA_WEALTH.into(), ); // enrich Bertha env.credit_tokens( &bertha_address(), - &xan(), + &nam(), None, BERTHA_WEALTH.into(), ); diff --git a/wasm/wasm_source/src/tx_bridge_pool.rs b/wasm/wasm_source/src/tx_bridge_pool.rs index 768efc39bf..f3dd77dad6 100644 --- a/wasm/wasm_source/src/tx_bridge_pool.rs +++ b/wasm/wasm_source/src/tx_bridge_pool.rs @@ -16,7 +16,7 @@ fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { ctx, payer, &bridge_pool::BRIDGE_POOL_ADDRESS, - &address::xan(), + &address::nam(), None, amount, )?; @@ -32,7 +32,7 @@ fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { ctx, sender, ð_bridge::ADDRESS, - &address::xan(), + &address::nam(), None, amount, )?; From bb98133a2de3b9b0ec145a9b5e968585bb6e8107 Mon Sep 17 00:00:00 2001 From: satan Date: Tue, 29 Nov 2022 10:39:16 +0100 Subject: [PATCH 02/28] [fix]: Fixed the wasm for adding transfers to the bridge pool --- apps/src/lib/node/ledger/shell/init_chain.rs | 1 + apps/src/lib/wasm_loader/mod.rs | 1 - shared/src/types/storage.rs | 34 +++++++++----------- wasm/wasm_source/src/tx_bridge_pool.rs | 2 ++ 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/apps/src/lib/node/ledger/shell/init_chain.rs b/apps/src/lib/node/ledger/shell/init_chain.rs index d98449d9e5..77adab17df 100644 --- a/apps/src/lib/node/ledger/shell/init_chain.rs +++ b/apps/src/lib/node/ledger/shell/init_chain.rs @@ -70,6 +70,7 @@ where genesis.gov_params.init_storage(&mut self.storage); // configure the Ethereum bridge if the configuration is set. if let Some(config) = genesis.ethereum_bridge_params { + tracing::debug!("Initializing Ethereum bridge storage."); config.init_storage(&mut self.storage); } diff --git a/apps/src/lib/wasm_loader/mod.rs b/apps/src/lib/wasm_loader/mod.rs index fa0ea6448f..e82bb92452 100644 --- a/apps/src/lib/wasm_loader/mod.rs +++ b/apps/src/lib/wasm_loader/mod.rs @@ -109,7 +109,6 @@ pub async fn pre_fetch_wasm(wasm_directory: impl AsRef) { let checksums_path = wasm_directory .as_ref() .join(crate::config::DEFAULT_WASM_CHECKSUMS_FILE); - tracing::info!("WASM PATH: {}", checksums_path.to_string_lossy()); // If the checksums file doesn't exists ... if tokio::fs::canonicalize(&checksums_path).await.is_err() { tokio::fs::create_dir_all(&wasm_directory).await.unwrap(); diff --git a/shared/src/types/storage.rs b/shared/src/types/storage.rs index 5ced875453..7525c35044 100644 --- a/shared/src/types/storage.rs +++ b/shared/src/types/storage.rs @@ -264,29 +264,25 @@ pub enum MerkleValue { BridgePoolTransfer(PendingTransfer), } -impl From for MerkleValue -where - T: AsRef<[u8]>, -{ - fn from(bytes: T) -> Self { - Self::Bytes(bytes.as_ref().to_owned()) - } -} - -impl From for MerkleValue { - fn from(transfer: PendingTransfer) -> Self { - Self::BridgePoolTransfer(transfer) +impl MerkleValue { + /// Byte length of the value + pub fn len(&self) -> usize { + match self { + MerkleValue::Bytes(bytes) => bytes.len(), + MerkleValue::BridgePoolTransfer(transfer) => transfer + .try_to_vec() + .expect("Serializing a PendingTransfer should not fail.") + .len(), + } } -} -impl MerkleValue { - /// Get the natural byte representation of the value + /// Byte representation of a value in the Merkle tree pub fn to_bytes(self) -> Vec { match self { - Self::Bytes(bytes) => bytes, - Self::BridgePoolTransfer(transfer) => { - transfer.try_to_vec().unwrap() - } + MerkleValue::Bytes(bytes) => bytes, + MerkleValue::BridgePoolTransfer(transfer) => transfer + .try_to_vec() + .expect("Serializing a PendingTransfer should not fail."), } } } diff --git a/wasm/wasm_source/src/tx_bridge_pool.rs b/wasm/wasm_source/src/tx_bridge_pool.rs index 31c9388def..d127236abd 100644 --- a/wasm/wasm_source/src/tx_bridge_pool.rs +++ b/wasm/wasm_source/src/tx_bridge_pool.rs @@ -61,8 +61,10 @@ fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { } fn native_erc20_address(ctx: &mut Ctx) -> EnvResult { + log_string("Trying to get wnam key"); let addr = ctx.read_bytes(&native_erc20_key()) .map_err(|_| Error::SimpleMessage("Could not read wNam key from storage"))? .unwrap(); + log_string("Got wnam key"); Ok(BorshDeserialize::try_from_slice(addr.as_slice()).unwrap()) } From becad122d2f4f70de2d55a47d5da72aac9a3f4d2 Mon Sep 17 00:00:00 2001 From: satan Date: Wed, 30 Nov 2022 14:35:23 +0100 Subject: [PATCH 03/28] [feat]: Added type alias for byte vector in merkle storage --- shared/src/ledger/storage/merkle_tree.rs | 9 ++++++--- shared/src/ledger/storage/traits.rs | 9 +++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/shared/src/ledger/storage/merkle_tree.rs b/shared/src/ledger/storage/merkle_tree.rs index e0b49f2db4..34d5f4bf73 100644 --- a/shared/src/ledger/storage/merkle_tree.rs +++ b/shared/src/ledger/storage/merkle_tree.rs @@ -55,6 +55,9 @@ pub enum Error { /// Result for functions that may fail type Result = std::result::Result; +/// Type alias for bytes to be put into the Merkle storage +pub(super) type StorageBytes = Vec; + /// Type aliases for the different merkle trees and backing stores pub type SmtStore = DefaultStore; pub type AmtStore = DefaultStore; @@ -321,7 +324,7 @@ impl MerkleTree { .subtree_update(key, value.as_ref())?; // update the base tree with the updated sub root without hashing if *store_type != StoreType::Base { - let base_key = H::hash(&store_type.to_string()); + let base_key = H::hash(store_type.to_string()); self.base.update(base_key.into(), sub_root)?; } Ok(()) @@ -344,7 +347,7 @@ impl MerkleTree { let (store_type, sub_key) = StoreType::sub_key(key)?; let sub_root = self.tree_mut(&store_type).subtree_delete(&sub_key)?; if store_type != StoreType::Base { - let base_key = H::hash(&store_type.to_string()); + let base_key = H::hash(store_type.to_string()); self.base.update(base_key.into(), sub_root)?; } Ok(()) @@ -373,7 +376,7 @@ impl MerkleTree { pub fn get_sub_tree_existence_proof( &self, keys: &[Key], - values: Vec>, + values: Vec, ) -> Result { let first_key = keys.iter().next().ok_or_else(|| { Error::InvalidMerkleKey( diff --git a/shared/src/ledger/storage/traits.rs b/shared/src/ledger/storage/traits.rs index 9ca7798832..b6aff3217a 100644 --- a/shared/src/ledger/storage/traits.rs +++ b/shared/src/ledger/storage/traits.rs @@ -14,6 +14,7 @@ use super::merkle_tree::{Amt, Error, Smt}; use super::{ics23_specs, IBC_KEY_LIMIT}; use crate::ledger::eth_bridge::storage::bridge_pool::BridgePoolTree; use crate::types::eth_bridge_pool::PendingTransfer; +use crate::ledger::storage::merkle_tree::StorageBytes; use crate::types::hash::Hash; use crate::types::storage::{Key, MembershipProof, StringKey, TreeBytes}; @@ -26,7 +27,7 @@ pub trait SubTreeRead { fn subtree_membership_proof( &self, keys: &[Key], - values: Vec>, + values: Vec, ) -> Result; } @@ -54,7 +55,7 @@ impl<'a, H: StorageHasher + Default> SubTreeRead for &'a Smt { fn subtree_membership_proof( &self, keys: &[Key], - mut values: Vec>, + mut values: Vec, ) -> Result { if keys.len() != 1 || values.len() != 1 { return Err(Error::Ics23MultiLeaf); @@ -111,7 +112,7 @@ impl<'a, H: StorageHasher + Default> SubTreeRead for &'a Amt { fn subtree_membership_proof( &self, keys: &[Key], - _: Vec>, + _: Vec, ) -> Result { if keys.len() != 1 { return Err(Error::Ics23MultiLeaf); @@ -165,7 +166,7 @@ impl<'a> SubTreeRead for &'a BridgePoolTree { fn subtree_membership_proof( &self, _: &[Key], - values: Vec>, + values: Vec, ) -> Result { let values = values .iter() From 818da8892dc4043aca36f6dc55e7865b352bfb37 Mon Sep 17 00:00:00 2001 From: satan Date: Thu, 1 Dec 2022 10:52:01 +0100 Subject: [PATCH 04/28] [feat]: Changed the bytes passed into merkle proof to be references --- shared/src/ledger/queries/shell.rs | 13 ++++++------- shared/src/ledger/storage/merkle_tree.rs | 6 +++--- shared/src/ledger/storage/mod.rs | 4 ++-- shared/src/ledger/storage/traits.rs | 18 ++++++++++-------- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/shared/src/ledger/queries/shell.rs b/shared/src/ledger/queries/shell.rs index 335f9b8203..516992aa94 100644 --- a/shared/src/ledger/queries/shell.rs +++ b/shared/src/ledger/queries/shell.rs @@ -250,11 +250,7 @@ where let proof = if request.prove { let proof = ctx .storage - .get_existence_proof( - &storage_key, - value.clone(), - request.height, - ) + .get_existence_proof(&storage_key, &value, request.height) .into_storage_result()?; Some(proof) } else { @@ -309,7 +305,7 @@ where for PrefixValue { key, value } in &data { let mut proof = ctx .storage - .get_existence_proof(key, value.clone(), request.height) + .get_existence_proof(key, value, request.height) .into_storage_result()?; ops.append(&mut proof.ops); } @@ -477,7 +473,10 @@ where ))); } // get the membership proof - match tree.get_sub_tree_existence_proof(&keys, values) { + match tree.get_sub_tree_existence_proof( + &keys, + values.iter().map(|v| v.as_slice()).collect(), + ) { Ok(BridgePool(proof)) => { let data = EncodeCell::new(&RelayProof { // TODO: use actual validators diff --git a/shared/src/ledger/storage/merkle_tree.rs b/shared/src/ledger/storage/merkle_tree.rs index 34d5f4bf73..edd4d2b452 100644 --- a/shared/src/ledger/storage/merkle_tree.rs +++ b/shared/src/ledger/storage/merkle_tree.rs @@ -56,7 +56,7 @@ pub enum Error { type Result = std::result::Result; /// Type alias for bytes to be put into the Merkle storage -pub(super) type StorageBytes = Vec; +pub(super) type StorageBytes<'a> = &'a [u8]; /// Type aliases for the different merkle trees and backing stores pub type SmtStore = DefaultStore; @@ -733,7 +733,7 @@ mod test { let proof = match tree .get_sub_tree_existence_proof( std::array::from_ref(&ibc_key), - vec![ibc_val.clone()], + vec![&ibc_val], ) .unwrap() { @@ -792,7 +792,7 @@ mod test { let proof = match tree .get_sub_tree_existence_proof( std::array::from_ref(&pos_key), - vec![pos_val.clone()], + vec![&pos_val], ) .unwrap() { diff --git a/shared/src/ledger/storage/mod.rs b/shared/src/ledger/storage/mod.rs index 34acc656e6..da517989d8 100644 --- a/shared/src/ledger/storage/mod.rs +++ b/shared/src/ledger/storage/mod.rs @@ -36,7 +36,7 @@ use crate::ledger::pos::namada_proof_of_stake::PosBase; use crate::ledger::pos::types::WeightedValidator; use crate::ledger::pos::PosParams; use crate::ledger::storage::merkle_tree::{ - Error as MerkleTreeError, MerkleRoot, + Error as MerkleTreeError, MerkleRoot, StorageBytes, }; pub use crate::ledger::storage::merkle_tree::{ MerkleTree, MerkleTreeStoresRead, MerkleTreeStoresWrite, StoreRef, @@ -619,7 +619,7 @@ where pub fn get_existence_proof( &self, key: &Key, - value: Vec, + value: StorageBytes, height: BlockHeight, ) -> Result { if height >= self.get_block_height().0 { diff --git a/shared/src/ledger/storage/traits.rs b/shared/src/ledger/storage/traits.rs index ac426c563c..b615abaa98 100644 --- a/shared/src/ledger/storage/traits.rs +++ b/shared/src/ledger/storage/traits.rs @@ -38,7 +38,7 @@ pub trait SubTreeWrite { fn subtree_update( &mut self, key: &Key, - value: &[u8], + value: StorageBytes, ) -> Result; /// Delete a key from the sub-tree fn subtree_delete(&mut self, key: &Key) -> Result; @@ -68,7 +68,7 @@ impl<'a, H: StorageHasher + Default> SubTreeRead for &'a Smt { Ics23Proof::Exist(ep) => Ok(CommitmentProof { proof: Some(Ics23Proof::Exist(ExistenceProof { key: key.to_string().as_bytes().to_vec(), - value, + value: value.to_vec(), leaf: Some(ics23_specs::leaf_spec::()), ..ep })), @@ -84,7 +84,7 @@ impl<'a, H: StorageHasher + Default> SubTreeWrite for &'a mut Smt { fn subtree_update( &mut self, key: &Key, - value: &[u8], + value: StorageBytes, ) -> Result { let value = H::hash(value); self.update(H::hash(key.to_string()).into(), value.into()) @@ -139,7 +139,7 @@ impl<'a, H: StorageHasher + Default> SubTreeWrite for &'a mut Amt { fn subtree_update( &mut self, key: &Key, - value: &[u8], + value: StorageBytes, ) -> Result { let key = StringKey::try_from_bytes(key.to_string().as_bytes())?; let value = TreeBytes::from(value.as_ref().to_owned()); @@ -170,9 +170,7 @@ impl<'a> SubTreeRead for &'a BridgePoolTree { ) -> Result { let values = values .iter() - .filter_map(|val| { - PendingTransfer::try_from_slice(val.as_slice()).ok() - }) + .filter_map(|val| PendingTransfer::try_from_slice(val).ok()) .collect(); self.get_membership_proof(values) .map(Into::into) @@ -181,7 +179,11 @@ impl<'a> SubTreeRead for &'a BridgePoolTree { } impl<'a> SubTreeWrite for &'a mut BridgePoolTree { - fn subtree_update(&mut self, key: &Key, _: &[u8]) -> Result { + fn subtree_update( + &mut self, + key: &Key, + _: StorageBytes, + ) -> Result { self.insert_key(key) .map_err(|err| Error::MerkleTree(err.to_string())) } From 4f51d4b5bc97d2e0665693f4bd2667900c67a17e Mon Sep 17 00:00:00 2001 From: James Hiew Date: Thu, 1 Dec 2022 11:27:13 +0000 Subject: [PATCH 05/28] Ensure pending events require at least the protocol specified min confirmations --- apps/src/lib/node/ledger/ethereum_node/events.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/src/lib/node/ledger/ethereum_node/events.rs b/apps/src/lib/node/ledger/ethereum_node/events.rs index d2e98de2dd..4c87b967bc 100644 --- a/apps/src/lib/node/ledger/ethereum_node/events.rs +++ b/apps/src/lib/node/ledger/ethereum_node/events.rs @@ -126,7 +126,8 @@ pub mod eth_events { match signature { signatures::TRANSFER_TO_NAMADA_SIG => { RawTransfersToNamada::decode(data).map(|txs| PendingEvent { - confirmations: txs.confirmations.into(), + confirmations: min_confirmations + .max(txs.confirmations.into()), block_height, event: EthereumEvent::TransfersToNamada { nonce: txs.nonce, @@ -137,7 +138,8 @@ pub mod eth_events { signatures::TRANSFER_TO_ETHEREUM_SIG => { RawTransfersToEthereum::decode(data).map(|txs| { PendingEvent { - confirmations: txs.confirmations.into(), + confirmations: min_confirmations + .max(txs.confirmations.into()), block_height, event: EthereumEvent::TransfersToEthereum { nonce: txs.nonce, From 53be7c5019eb1a356efad211dc1252e0bbc830d6 Mon Sep 17 00:00:00 2001 From: James Hiew Date: Thu, 1 Dec 2022 11:40:55 +0000 Subject: [PATCH 06/28] Add a basic test for min confirmations --- .../lib/node/ledger/ethereum_node/events.rs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/apps/src/lib/node/ledger/ethereum_node/events.rs b/apps/src/lib/node/ledger/ethereum_node/events.rs index 4c87b967bc..2095b9bd5c 100644 --- a/apps/src/lib/node/ledger/ethereum_node/events.rs +++ b/apps/src/lib/node/ledger/ethereum_node/events.rs @@ -67,6 +67,7 @@ pub mod eth_events { pub type Result = std::result::Result; + #[derive(Clone, Debug, PartialEq)] /// An event waiting for a certain number of confirmations /// before being sent to the ledger pub(in super::super) struct PendingEvent { @@ -759,6 +760,8 @@ pub mod eth_events { #[cfg(test)] mod test_events { + use assert_matches::assert_matches; + use super::*; #[test] @@ -800,6 +803,34 @@ pub mod eth_events { }] ) } + + /// Test that for Ethereum events for which a custom number of + /// confirmations may be specified, if a value lower than the + /// protocol-specified minimum confirmations is attempted to be used, + /// then the protcol-specified minimum confirmations is used instead. + #[test] + fn test_min_confirmations_enforced() -> Result<()> { + let sig = signatures::TRANSFER_TO_NAMADA_SIG; + let arbitrary_block_height = 123u64.into(); + let min_confirmations: Uint256 = 100u64.into(); + let event = RawTransfersToNamada { + transfers: vec![], + nonce: 0.into(), + confirmations: 1, // this is lower than `min_confirmations` + }; + let data = event.encode(); + + let pending_event = PendingEvent::decode( + sig, + arbitrary_block_height, + &data, + min_confirmations.clone(), + )?; + + assert_matches!(pending_event, PendingEvent { confirmations, .. } if confirmations == min_confirmations); + Ok(()) + } + /// For each of the basic types, test that roundtrip /// encoding - decoding is a no-op #[test] From b785eca43f228a4f0cdf9f202a5498f1f481062a Mon Sep 17 00:00:00 2001 From: James Hiew Date: Thu, 1 Dec 2022 11:59:06 +0000 Subject: [PATCH 07/28] Expand test to cover transfers to Ethereum also --- .../lib/node/ledger/ethereum_node/events.rs | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/apps/src/lib/node/ledger/ethereum_node/events.rs b/apps/src/lib/node/ledger/ethereum_node/events.rs index 2095b9bd5c..f603b2b5ff 100644 --- a/apps/src/lib/node/ledger/ethereum_node/events.rs +++ b/apps/src/lib/node/ledger/ethereum_node/events.rs @@ -810,16 +810,37 @@ pub mod eth_events { /// then the protcol-specified minimum confirmations is used instead. #[test] fn test_min_confirmations_enforced() -> Result<()> { - let sig = signatures::TRANSFER_TO_NAMADA_SIG; - let arbitrary_block_height = 123u64.into(); + let arbitrary_block_height: Uint256 = 123u64.into(); let min_confirmations: Uint256 = 100u64.into(); - let event = RawTransfersToNamada { - transfers: vec![], - nonce: 0.into(), - confirmations: 1, // this is lower than `min_confirmations` - }; + let lower_than_min_confirmations = 5; + + let (sig, event) = ( + signatures::TRANSFER_TO_NAMADA_SIG, + RawTransfersToNamada { + transfers: vec![], + nonce: 0.into(), + confirmations: lower_than_min_confirmations, + }, + ); let data = event.encode(); + let pending_event = PendingEvent::decode( + sig, + arbitrary_block_height.clone(), + &data, + min_confirmations.clone(), + )?; + + assert_matches!(pending_event, PendingEvent { confirmations, .. } if confirmations == min_confirmations); + let (sig, event) = ( + signatures::TRANSFER_TO_ETHEREUM_SIG, + RawTransfersToEthereum { + transfers: vec![], + nonce: 0.into(), + confirmations: lower_than_min_confirmations, + }, + ); + let data = event.encode(); let pending_event = PendingEvent::decode( sig, arbitrary_block_height, @@ -828,6 +849,7 @@ pub mod eth_events { )?; assert_matches!(pending_event, PendingEvent { confirmations, .. } if confirmations == min_confirmations); + Ok(()) } From d34a23f60e1d3d374b183f8214e6a5324c5c2bce Mon Sep 17 00:00:00 2001 From: James Hiew Date: Thu, 1 Dec 2022 12:02:19 +0000 Subject: [PATCH 08/28] Test custom confirmations may be used --- .../lib/node/ledger/ethereum_node/events.rs | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/apps/src/lib/node/ledger/ethereum_node/events.rs b/apps/src/lib/node/ledger/ethereum_node/events.rs index f603b2b5ff..e451746265 100644 --- a/apps/src/lib/node/ledger/ethereum_node/events.rs +++ b/apps/src/lib/node/ledger/ethereum_node/events.rs @@ -853,6 +853,54 @@ pub mod eth_events { Ok(()) } + /// Test that for Ethereum events for which a custom number of + /// confirmations may be specified, the custom number is used if it is + /// at least the protocol-specified minimum confirmations. + #[test] + fn test_custom_confirmations_used() { + let arbitrary_block_height: Uint256 = 123u64.into(); + let min_confirmations: Uint256 = 100u64.into(); + let higher_than_min_confirmations = 200; + + let (sig, event) = ( + signatures::TRANSFER_TO_NAMADA_SIG, + RawTransfersToNamada { + transfers: vec![], + nonce: 0.into(), + confirmations: higher_than_min_confirmations, + }, + ); + let data = event.encode(); + let pending_event = PendingEvent::decode( + sig, + arbitrary_block_height.clone(), + &data, + min_confirmations.clone(), + ) + .unwrap(); + + assert_matches!(pending_event, PendingEvent { confirmations, .. } if confirmations == higher_than_min_confirmations.into()); + + let (sig, event) = ( + signatures::TRANSFER_TO_ETHEREUM_SIG, + RawTransfersToEthereum { + transfers: vec![], + nonce: 0.into(), + confirmations: higher_than_min_confirmations, + }, + ); + let data = event.encode(); + let pending_event = PendingEvent::decode( + sig, + arbitrary_block_height, + &data, + min_confirmations, + ) + .unwrap(); + + assert_matches!(pending_event, PendingEvent { confirmations, .. } if confirmations == higher_than_min_confirmations.into()); + } + /// For each of the basic types, test that roundtrip /// encoding - decoding is a no-op #[test] From d4bc962e13c65490646e85b840fdb5225c68cfd7 Mon Sep 17 00:00:00 2001 From: satan Date: Thu, 1 Dec 2022 13:36:00 +0100 Subject: [PATCH 09/28] [fix]: Merge in the part of PR #813 to fix the tx_unbond.wasm tests --- proof_of_stake/src/lib.rs | 10 ----- shared/src/types/token.rs | 10 ++++- .../proptest-regressions/tx_bond.txt | 2 +- wasm/wasm_source/src/tx_bond.rs | 2 +- wasm/wasm_source/src/tx_unbond.rs | 42 ++++++++++--------- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/proof_of_stake/src/lib.rs b/proof_of_stake/src/lib.rs index c2fd2523cc..b6be63cf44 100644 --- a/proof_of_stake/src/lib.rs +++ b/proof_of_stake/src/lib.rs @@ -1046,8 +1046,6 @@ pub enum BondError { InactiveValidator(Address), #[error("Voting power overflow: {0}")] VotingPowerOverflow(TryFromIntError), - #[error("Given zero amount to bond")] - ZeroAmount, } #[allow(missing_docs)] @@ -1065,8 +1063,6 @@ pub enum UnbondError { ValidatorHasNoVotingPower(Address), #[error("Voting power overflow: {0}")] VotingPowerOverflow(TryFromIntError), - #[error("Given zero amount to unbond")] - ZeroAmount, } #[allow(missing_docs)] @@ -1611,9 +1607,6 @@ where + BorshSerialize + BorshSchema, { - if amount == TokenAmount::default() { - return Err(BondError::ZeroAmount); - } // Check the validator state match validator_state { None => { @@ -1791,9 +1784,6 @@ where + BorshSerialize + BorshSchema, { - if amount == TokenAmount::default() { - return Err(UnbondError::ZeroAmount); - } // We can unbond tokens that are bonded for a future epoch (not yet // active), hence we check the total at the pipeline offset let unbondable_amount = bond diff --git a/shared/src/types/token.rs b/shared/src/types/token.rs index 7bc914b6ba..3109fee837 100644 --- a/shared/src/types/token.rs +++ b/shared/src/types/token.rs @@ -234,7 +234,7 @@ impl FromStr for Amount { match rust_decimal::Decimal::from_str(s) { Ok(decimal) => { let scale = decimal.scale(); - if scale > 6 { + if scale > MAX_DECIMAL_PLACES { return Err(AmountParseError::ScaleTooLarge(scale)); } let whole = @@ -518,4 +518,12 @@ pub mod testing { pub fn arb_amount_ceiled(max: u64) -> impl Strategy { (0..=max).prop_map(Amount::from) } + + /// Generate an arbitrary non-zero token amount up to and including given + /// `max` value + pub fn arb_amount_non_zero_ceiled( + max: u64, + ) -> impl Strategy { + (1..=max).prop_map(Amount::from) + } } diff --git a/wasm/wasm_source/proptest-regressions/tx_bond.txt b/wasm/wasm_source/proptest-regressions/tx_bond.txt index 3a88756618..8c589d1abd 100644 --- a/wasm/wasm_source/proptest-regressions/tx_bond.txt +++ b/wasm/wasm_source/proptest-regressions/tx_bond.txt @@ -1 +1 @@ -cc e54347c5114ef29538127ba9ad68d1572af839ec63c015318fc0827818853a22 +cc f22e874350910b197cb02a4a07ec5bef18e16c0d1a39eaabaee43d1fc05ce11d diff --git a/wasm/wasm_source/src/tx_bond.rs b/wasm/wasm_source/src/tx_bond.rs index 8def153df3..ca53c11635 100644 --- a/wasm/wasm_source/src/tx_bond.rs +++ b/wasm/wasm_source/src/tx_bond.rs @@ -353,7 +353,7 @@ mod tests { ( arb_established_address(), prop::option::of(arb_non_internal_address()), - token::testing::arb_amount_ceiled(max_amount), + token::testing::arb_amount_non_zero_ceiled(max_amount), ) .prop_map(|(validator, source, amount)| { transaction::pos::Bond { diff --git a/wasm/wasm_source/src/tx_unbond.rs b/wasm/wasm_source/src/tx_unbond.rs index 0f249e73f3..46db9ec99c 100644 --- a/wasm/wasm_source/src/tx_unbond.rs +++ b/wasm/wasm_source/src/tx_unbond.rs @@ -225,24 +225,24 @@ mod tests { epoch {epoch}" ); } - let start_epoch = match &unbond.source { - Some(_) => { - // This bond was a delegation - namada_tx_prelude::proof_of_stake::types::Epoch::from( - pos_params.pipeline_len, - ) - } - None => { - // This bond was a genesis validator self-bond - namada_tx_prelude::proof_of_stake::types::Epoch::default() - } + let start_epoch = if is_delegation { + // This bond was a delegation + namada_tx_prelude::proof_of_stake::types::Epoch::from( + pos_params.pipeline_len, + ) + } else { + // This bond was a genesis validator self-bond + namada_tx_prelude::proof_of_stake::types::Epoch::default() }; let end_epoch = namada_tx_prelude::proof_of_stake::types::Epoch::from( pos_params.unbonding_len - 1, ); - let expected_unbond = - HashMap::from_iter([((start_epoch, end_epoch), unbond.amount)]); + let expected_unbond = if unbond.amount == token::Amount::default() { + HashMap::new() + } else { + HashMap::from_iter([((start_epoch, end_epoch), unbond.amount)]) + }; let actual_unbond: Unbond = unbonds_post.get(pos_params.unbonding_len).unwrap(); assert_eq!( @@ -390,12 +390,14 @@ mod tests { fn arb_initial_stake_and_unbond() -> impl Strategy { // Generate initial stake - token::testing::arb_amount().prop_flat_map(|initial_stake| { - // Use the initial stake to limit the bond amount - let unbond = arb_unbond(u64::from(initial_stake)); - // Use the generated initial stake too too - (Just(initial_stake), unbond) - }) + token::testing::arb_amount_ceiled((i64::MAX / 8) as u64).prop_flat_map( + |initial_stake| { + // Use the initial stake to limit the bond amount + let unbond = arb_unbond(u64::from(initial_stake)); + // Use the generated initial stake too too + (Just(initial_stake), unbond) + }, + ) } /// Generates an initial validator stake and a unbond, while making sure @@ -406,7 +408,7 @@ mod tests { ( address::testing::arb_established_address(), prop::option::of(address::testing::arb_non_internal_address()), - token::testing::arb_amount_ceiled(max_amount), + token::testing::arb_amount_non_zero_ceiled(max_amount), ) .prop_map(|(validator, source, amount)| { let validator = Address::Established(validator); From ab122240e94c6639a3482c7264bf52750461a15b Mon Sep 17 00:00:00 2001 From: satan Date: Fri, 2 Dec 2022 15:52:29 +0100 Subject: [PATCH 10/28] [feat]: E2E tests for the bridge pool are now working --- apps/src/lib/client/eth_bridge_pool.rs | 17 ++++++-- apps/src/lib/config/genesis.rs | 22 ++++++++-- shared/src/ledger/storage/traits.rs | 1 - tests/src/e2e/eth_bridge_tests.rs | 57 ++++++++++++++++++++++---- tests/src/e2e/setup.rs | 2 + wasm/checksums.json | 38 ++++++++++------- 6 files changed, 107 insertions(+), 30 deletions(-) diff --git a/apps/src/lib/client/eth_bridge_pool.rs b/apps/src/lib/client/eth_bridge_pool.rs index b697995eb4..09171a9cc9 100644 --- a/apps/src/lib/client/eth_bridge_pool.rs +++ b/apps/src/lib/client/eth_bridge_pool.rs @@ -1,6 +1,9 @@ +use std::collections::HashMap; + use borsh::BorshSerialize; use namada::ledger::queries::RPC; use namada::proto::Tx; +use namada::types::eth_abi::Encode; use namada::types::eth_bridge_pool::{ GasFee, PendingTransfer, TransferToEthereum, }; @@ -67,11 +70,19 @@ pub async fn construct_bridge_pool_proof(args: args::BridgePoolProof) { /// Prints out a json payload. pub async fn query_bridge_pool(args: args::Query) { let client = HttpClient::new(args.ledger_address).unwrap(); - let response = RPC + let response: Vec = RPC .shell() .read_ethereum_bridge_pool(&client) .await .unwrap(); - - println!("{:#?}", serde_json::to_string_pretty(&response)); + let pool_contents: HashMap = response + .into_iter() + .map(|transfer| (transfer.keccak256().to_string(), transfer)) + .collect(); + if pool_contents.is_empty() { + println!("Bridge pool is empty."); + } else { + println!("Bridge pool contents: "); + } + println!("{}", serde_json::to_string_pretty(&pool_contents).unwrap()); } diff --git a/apps/src/lib/config/genesis.rs b/apps/src/lib/config/genesis.rs index d27827a1d9..ffbc22cbba 100644 --- a/apps/src/lib/config/genesis.rs +++ b/apps/src/lib/config/genesis.rs @@ -6,13 +6,16 @@ use std::path::Path; use borsh::{BorshDeserialize, BorshSerialize}; use derivative::Derivative; -use namada::ledger::eth_bridge::parameters::EthereumBridgeConfig; +use namada::ledger::eth_bridge::parameters::{ + Contracts, EthereumBridgeConfig, UpgradeableContract, +}; use namada::ledger::governance::parameters::GovParams; use namada::ledger::parameters::Parameters; use namada::ledger::pos::{GenesisValidator, PosParams}; -use namada::types::address::Address; +use namada::types::address::{wnam, Address}; #[cfg(not(feature = "dev"))] use namada::types::chain::ChainId; +use namada::types::ethereum_events::EthAddress; use namada::types::key::dkg_session_keys::DkgPublicKey; use namada::types::key::*; use namada::types::time::DateTimeUtc; @@ -881,7 +884,20 @@ pub fn genesis() -> Genesis { parameters, pos_params: PosParams::default(), gov_params: GovParams::default(), - ethereum_bridge_params: None, + ethereum_bridge_params: Some(EthereumBridgeConfig { + min_confirmations: Default::default(), + contracts: Contracts { + native_erc20: wnam(), + bridge: UpgradeableContract { + address: EthAddress([0; 20]), + version: Default::default(), + }, + governance: UpgradeableContract { + address: EthAddress([1; 20]), + version: Default::default(), + }, + }, + }), } } diff --git a/shared/src/ledger/storage/traits.rs b/shared/src/ledger/storage/traits.rs index 3b0a58725e..b615abaa98 100644 --- a/shared/src/ledger/storage/traits.rs +++ b/shared/src/ledger/storage/traits.rs @@ -15,7 +15,6 @@ use super::{ics23_specs, IBC_KEY_LIMIT}; use crate::ledger::eth_bridge::storage::bridge_pool::BridgePoolTree; use crate::ledger::storage::merkle_tree::StorageBytes; use crate::types::eth_bridge_pool::PendingTransfer; -use crate::ledger::storage::merkle_tree::StorageBytes; use crate::types::hash::Hash; use crate::types::storage::{Key, MembershipProof, StringKey, TreeBytes}; diff --git a/tests/src/e2e/eth_bridge_tests.rs b/tests/src/e2e/eth_bridge_tests.rs index bc8a7cc5eb..1dc629394b 100644 --- a/tests/src/e2e/eth_bridge_tests.rs +++ b/tests/src/e2e/eth_bridge_tests.rs @@ -1,6 +1,10 @@ use color_eyre::eyre::Result; +use namada::ledger::eth_bridge::parameters::{ + Contracts, EthereumBridgeConfig, UpgradeableContract, +}; use namada::types::address::wnam; use namada::types::ethereum_events::testing::DAI_ERC20_ETH_ADDRESS_CHECKSUMMED; +use namada::types::ethereum_events::EthAddress; use namada_apps::config::ethereum_bridge; use super::setup::set_ethereum_bridge_mode; @@ -128,13 +132,37 @@ fn run_ledger_with_ethereum_events_endpoint() -> Result<()> { Ok(()) } +/// In this test, we check the following: +/// 1. We can successfully add tranfers to the bridge pool. +/// 2. We can query the bridge pool and it is non-empty. #[test] fn test_add_to_bridge_pool() { const LEDGER_STARTUP_TIMEOUT_SECONDS: u64 = 40; const CLIENT_COMMAND_TIMEOUT_SECONDS: u64 = 60; + const QUERY_TIMEOUT_SECONDS: u64 = 40; const SOLE_VALIDATOR: Who = Who::Validator(0); let wnam_address = wnam().to_canonical(); - let test = setup::single_node_net().unwrap(); + let test = setup::network( + |mut genesis| { + genesis.ethereum_bridge_params = Some(EthereumBridgeConfig { + min_confirmations: Default::default(), + contracts: Contracts { + native_erc20: wnam(), + bridge: UpgradeableContract { + address: EthAddress([0; 20]), + version: Default::default(), + }, + governance: UpgradeableContract { + address: EthAddress([1; 20]), + version: Default::default(), + }, + }, + }); + genesis + }, + None, + ) + .unwrap(); set_ethereum_bridge_mode( &test, &test.net.chain_id, @@ -142,7 +170,7 @@ fn test_add_to_bridge_pool() { ethereum_bridge::ledger::Mode::EventsEndpoint, ); - let mut anoman_ledger = run_as!( + let mut namadan_ledger = run_as!( test, SOLE_VALIDATOR, Bin::Node, @@ -150,12 +178,14 @@ fn test_add_to_bridge_pool() { Some(LEDGER_STARTUP_TIMEOUT_SECONDS) ) .unwrap(); - anoman_ledger + namadan_ledger .exp_string("Anoma ledger node started") .unwrap(); - anoman_ledger.exp_string("Tendermint node started").unwrap(); - anoman_ledger.exp_string("Committed block hash").unwrap(); - let _bg_ledger = anoman_ledger.background(); + namadan_ledger + .exp_string("Tendermint node started") + .unwrap(); + namadan_ledger.exp_string("Committed block hash").unwrap(); + let _bg_ledger = namadan_ledger.background(); let ledger_addr = get_actor_rpc(&test, &SOLE_VALIDATOR); let tx_args = vec![ @@ -184,12 +214,23 @@ fn test_add_to_bridge_pool() { &ledger_addr, ]; - let mut anomac_tx = run!( + let mut namadac_tx = run!( test, Bin::Client, tx_args, Some(CLIENT_COMMAND_TIMEOUT_SECONDS) ) .unwrap(); - anomac_tx.exp_string("Transaction applied").unwrap(); + namadac_tx.exp_string("Transaction applied").unwrap(); + namadac_tx.exp_string("Transaction is valid").unwrap(); + drop(namadac_tx); + + let mut namadar = run!( + test, + Bin::BridgePool, + ["query", "--ledger-address", &ledger_addr,], + Some(QUERY_TIMEOUT_SECONDS), + ) + .unwrap(); + namadar.exp_string("Bridge pool contents:").unwrap(); } diff --git a/tests/src/e2e/setup.rs b/tests/src/e2e/setup.rs index 773a93069c..cf02c3e790 100644 --- a/tests/src/e2e/setup.rs +++ b/tests/src/e2e/setup.rs @@ -253,6 +253,7 @@ pub enum Bin { Node, Client, Wallet, + BridgePool, } #[derive(Debug)] @@ -711,6 +712,7 @@ where Bin::Node => ("namadan", "info"), Bin::Client => ("namadac", "tendermint_rpc=debug"), Bin::Wallet => ("namadaw", "info"), + Bin::BridgePool => ("namadar", "info"), }; let mut run_cmd = generate_bin_command( diff --git a/wasm/checksums.json b/wasm/checksums.json index 24e4c0b43e..8e54008eac 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,17 +1,25 @@ { - "tx_bond.wasm": "tx_bond.4fc2b1c226d57d94e4043109d1af164ac69f8eb72e12525d97a123d8100817af.wasm", - "tx_bridge_pool.wasm": "tx_bridge_pool.f41d51ed01d5c60909c8ff9a7ed31f19b2d3ef42c24d1daa4143d59e0e797d97.wasm", - "tx_ibc.wasm": "tx_ibc.582a0a6433782caaee708205fc22f40d2af34fcd6994ac8f5fb8bef627778b4d.wasm", - "tx_init_account.wasm": "tx_init_account.0c204ba845658516b20670346c0682595d16d1ca99f42eddde51d1cde4295ffb.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.0a9cbdd68510d723818bb5d95cb0770b4f054ca402f8bbcff18108ea413875de.wasm", - "tx_init_validator.wasm": "tx_init_validator.09d0e561565cb083cb243b4594882c4f424eda73a91f89cce1e814b35ba2eae5.wasm", - "tx_transfer.wasm": "tx_transfer.9f4ad0aed0f1fcf21398c4d12da4ae26937415b01524811c0dceb810f1d1bf4a.wasm", - "tx_unbond.wasm": "tx_unbond.72018d106cca5a856bca041ea30eee579ec61d29f246f1387f3da4ef72c6cfbd.wasm", - "tx_update_vp.wasm": "tx_update_vp.4d585d52ed7f3b1507ed092df82ff7edec362305eb9e84f4dae06f09d75cc727.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.49638241211faf327390a0f07920d8dd40c9d7676d9c1beccd3bad0ff5f6f1a9.wasm", - "tx_withdraw.wasm": "tx_withdraw.1f8faa002868664e42d6e4b7140d5f295a2a0f1e99968656ee4d91c496b8f08d.wasm", - "vp_masp.wasm": "vp_masp.ad12a384f8690ad1a7c084b0a2ce7e72b9743fac7b2229f9a0e290fd0e75619a.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.e7d6cc83ad23f7db10484a051e6ba25105900b154e179768ccc79b955d6f47ca.wasm", - "vp_token.wasm": "vp_token.fbec5c10439c0f2d421799188f9ab677967b931535262dbf4cc7591ea0978aa7.wasm", - "vp_user.wasm": "vp_user.4db5100a828f04ed1fe6d2fee09b56facd8dde1e3bc0ea8d288875bf934d581a.wasm" + "tx_bond.wasm": "tx_bond.d39b2ae31f454a352d9ed31db2d4b55fadb2246eb7fb736890100de77fb57f84.wasm", + "tx_bridge_pool.wasm": "tx_bridge_pool.5ad5652c40311fffb98f5b452c06928ceccb8a94fb6a1524368cce3e4445e8aa.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.2ddee7d15e2e9884f98c8a423a140ba9ac89417ccfcc8473615a464a0d4acf0a.wasm", + "tx_from_intent.wasm": "tx_from_intent.8d25dc3453f6ea39b7b2a3574ff47f26a17ee91e1c71f88adf116dd34cb198dc.wasm", + "tx_ibc.wasm": "tx_ibc.9ec5f2d7e3abf9847d414fcfbf5b1a2cadf166991c8ae941a8a10c6f2fc701fd.wasm", + "tx_init_account.wasm": "tx_init_account.2ca339b1a54239555853a5ace3aba1702d4a2027add6ba53ed1dd3814e45e1a1.wasm", + "tx_init_nft.wasm": "tx_init_nft.5fb223d13032f03e454a763125e69d9188b0bff54f14967161b91dd2bc8efc27.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.c530e0ff5ab37cef227cbc1f26f58daf9c70ca15edc9e714f9ade6d0a989ec61.wasm", + "tx_init_validator.wasm": "tx_init_validator.6504445e5c18660bf8f4e1b42baadf1cd200943b092e90c8a93bdad40ebc7961.wasm", + "tx_mint_nft.wasm": "tx_mint_nft.1278e59c0ed5f0b9834ce121b69f7f3ccba91e7ff4be305b5fa898cdc324690c.wasm", + "tx_reveal_pk.wasm": "tx_reveal_pk.b4d258ab70fdb136bacfa1c2caa765b596c796b330ff81c5756c080f2e21b36b.wasm", + "tx_transfer.wasm": "tx_transfer.ba8a40548e65d7af64e9151a44c4e45c9e4e5d0e8b4bd26b74ecc36fc752c349.wasm", + "tx_unbond.wasm": "tx_unbond.19f40a5bb264aacde8725ea475d73be3618281171d344bd6fc825e970e7fbcf9.wasm", + "tx_update_vp.wasm": "tx_update_vp.5dae0339928ab57bd938b1b10437127e9b01fd43f584103ba703424229a72618.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.60940ab81a965afbc5a1c973d5b4fbd917add369fe561c7ef2ba70b9835dbdae.wasm", + "tx_withdraw.wasm": "tx_withdraw.8496025271b977e5543647cd68452c2d17f4173537fd5390f0e8c379fdfc9a44.wasm", + "vp_implicit.wasm": "vp_implicit.ef275670c60bb360ae7ffe5e5153c06dd18ad63110ce47396114416bcf82ebb8.wasm", + "vp_masp.wasm": "vp_masp.e8b7276779cfd69eaa980f5e1cca3879073b0ac987170c58d0f867c9ecf0cb48.wasm", + "vp_nft.wasm": "vp_nft.173da472fb0b54d24a0e7f45ef78dc7a045b6119967045e37e20b6844db1dd4d.wasm", + "vp_testnet_faucet.wasm": "vp_testnet_faucet.9ef0688ce368780e0d77160c22e3655bdde1295ac6357ce10f83eda04d9f2075.wasm", + "vp_token.wasm": "vp_token.4df4c16e3276ab80cd9be6f21c88b37091d17a7dc021b12f950c742be6ed3794.wasm", + "vp_user.wasm": "vp_user.997779f95f446909d5dc27b879ba31d8ebf811bb9875e329701521991b52657b.wasm", + "vp_validator.wasm": "vp_validator.e335315f0fcd81c869a66d1d9be9b98ea3e102076379a038cbf7eb86d2d85685.wasm" } \ No newline at end of file From 0ac0bc191f816baaddbcc61545f31274e841d859 Mon Sep 17 00:00:00 2001 From: Jacob Turner Date: Tue, 6 Dec 2022 10:36:27 +0100 Subject: [PATCH 11/28] Update shared/src/ledger/storage/merkle_tree.rs Co-authored-by: Tiago Carvalho --- shared/src/ledger/storage/merkle_tree.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/ledger/storage/merkle_tree.rs b/shared/src/ledger/storage/merkle_tree.rs index edd4d2b452..b23e9db7de 100644 --- a/shared/src/ledger/storage/merkle_tree.rs +++ b/shared/src/ledger/storage/merkle_tree.rs @@ -56,7 +56,7 @@ pub enum Error { type Result = std::result::Result; /// Type alias for bytes to be put into the Merkle storage -pub(super) type StorageBytes<'a> = &'a [u8]; +pub(super) type StorageBytes<'a> = std::borrow::Cow<'a, [u8]>; /// Type aliases for the different merkle trees and backing stores pub type SmtStore = DefaultStore; From 8844903b57c94cce94992025a6a8928999da41d4 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 6 Dec 2022 09:51:06 +0000 Subject: [PATCH 12/28] Update apps/src/lib/node/ledger/ethereum_node/events.rs Co-authored-by: Tiago Carvalho --- apps/src/lib/node/ledger/ethereum_node/events.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/src/lib/node/ledger/ethereum_node/events.rs b/apps/src/lib/node/ledger/ethereum_node/events.rs index e451746265..afd8e086fe 100644 --- a/apps/src/lib/node/ledger/ethereum_node/events.rs +++ b/apps/src/lib/node/ledger/ethereum_node/events.rs @@ -807,7 +807,7 @@ pub mod eth_events { /// Test that for Ethereum events for which a custom number of /// confirmations may be specified, if a value lower than the /// protocol-specified minimum confirmations is attempted to be used, - /// then the protcol-specified minimum confirmations is used instead. + /// then the protocol-specified minimum confirmations is used instead. #[test] fn test_min_confirmations_enforced() -> Result<()> { let arbitrary_block_height: Uint256 = 123u64.into(); From 2af693a3965a5271616a56fb12b2603e34054d94 Mon Sep 17 00:00:00 2001 From: satan Date: Tue, 6 Dec 2022 11:00:51 +0100 Subject: [PATCH 13/28] Revert "Update shared/src/ledger/storage/merkle_tree.rs" This reverts commit 0ac0bc191f816baaddbcc61545f31274e841d859. --- shared/src/ledger/storage/merkle_tree.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/ledger/storage/merkle_tree.rs b/shared/src/ledger/storage/merkle_tree.rs index b23e9db7de..edd4d2b452 100644 --- a/shared/src/ledger/storage/merkle_tree.rs +++ b/shared/src/ledger/storage/merkle_tree.rs @@ -56,7 +56,7 @@ pub enum Error { type Result = std::result::Result; /// Type alias for bytes to be put into the Merkle storage -pub(super) type StorageBytes<'a> = std::borrow::Cow<'a, [u8]>; +pub(super) type StorageBytes<'a> = &'a [u8]; /// Type aliases for the different merkle trees and backing stores pub type SmtStore = DefaultStore; From fe3401d2612d5e49737dd76b9970a436742cab32 Mon Sep 17 00:00:00 2001 From: Jacob Turner Date: Tue, 6 Dec 2022 13:20:05 +0100 Subject: [PATCH 14/28] Update apps/src/lib/client/eth_bridge_pool.rs Co-authored-by: Tiago Carvalho --- apps/src/lib/client/eth_bridge_pool.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/src/lib/client/eth_bridge_pool.rs b/apps/src/lib/client/eth_bridge_pool.rs index 09171a9cc9..94f2ce1208 100644 --- a/apps/src/lib/client/eth_bridge_pool.rs +++ b/apps/src/lib/client/eth_bridge_pool.rs @@ -81,6 +81,7 @@ pub async fn query_bridge_pool(args: args::Query) { .collect(); if pool_contents.is_empty() { println!("Bridge pool is empty."); + return; } else { println!("Bridge pool contents: "); } From 1e9dcf5ac2a891cb0a7d6071f5414435590ad5dc Mon Sep 17 00:00:00 2001 From: Jacob Turner Date: Tue, 6 Dec 2022 13:21:10 +0100 Subject: [PATCH 15/28] Update tests/src/e2e/eth_bridge_tests.rs Co-authored-by: Tiago Carvalho --- tests/src/e2e/eth_bridge_tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/src/e2e/eth_bridge_tests.rs b/tests/src/e2e/eth_bridge_tests.rs index 1dc629394b..c447efe5cc 100644 --- a/tests/src/e2e/eth_bridge_tests.rs +++ b/tests/src/e2e/eth_bridge_tests.rs @@ -221,6 +221,7 @@ fn test_add_to_bridge_pool() { Some(CLIENT_COMMAND_TIMEOUT_SECONDS) ) .unwrap(); + namadac_tx.exp_string("Transaction accepted").unwrap(); namadac_tx.exp_string("Transaction applied").unwrap(); namadac_tx.exp_string("Transaction is valid").unwrap(); drop(namadac_tx); From 0a917fc262efb2db116ef66857c712343abfb14b Mon Sep 17 00:00:00 2001 From: satan Date: Tue, 29 Nov 2022 10:39:16 +0100 Subject: [PATCH 16/28] [fix]: Fixed the wasm for adding transfers to the bridge pool --- apps/src/lib/node/ledger/shell/init_chain.rs | 1 + wasm/wasm_source/src/tx_bridge_pool.rs | 23 +++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/apps/src/lib/node/ledger/shell/init_chain.rs b/apps/src/lib/node/ledger/shell/init_chain.rs index 6bc119a6e0..7ead94a34a 100644 --- a/apps/src/lib/node/ledger/shell/init_chain.rs +++ b/apps/src/lib/node/ledger/shell/init_chain.rs @@ -73,6 +73,7 @@ where genesis.gov_params.init_storage(&mut self.storage); // configure the Ethereum bridge if the configuration is set. if let Some(config) = genesis.ethereum_bridge_params { + tracing::debug!("Initializing Ethereum bridge storage."); config.init_storage(&mut self.storage); } diff --git a/wasm/wasm_source/src/tx_bridge_pool.rs b/wasm/wasm_source/src/tx_bridge_pool.rs index 812e95b25f..805ee65381 100644 --- a/wasm/wasm_source/src/tx_bridge_pool.rs +++ b/wasm/wasm_source/src/tx_bridge_pool.rs @@ -9,7 +9,9 @@ use namada_tx_prelude::*; fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]).unwrap(); let transfer = - PendingTransfer::try_from_slice(&signed.data.unwrap()[..]).unwrap(); + PendingTransfer::try_from_slice(&signed.data.unwrap()[..]) + .map_err(|_| Error::SimpleMessage("Error deserializing PendingTransfer"))?; + log_string("Received transfer to add to pool."); // pay the gas fees let GasFee { amount, ref payer } = transfer.gas_fee; token::transfer( @@ -22,14 +24,15 @@ fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { &None, &None, )?; + log_string("Token transfer succeeded."); let TransferToEthereum { - ref asset, + asset, ref sender, amount, .. } = transfer.transfer; // if minting wNam, escrow the correct amount - if *asset == native_erc20_address(ctx) { + if asset == native_erc20_address(ctx)? { token::transfer( ctx, sender, @@ -42,7 +45,7 @@ fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { )?; } else { // Otherwise we escrow ERC20 tokens. - let sub_prefix = wrapped_erc20s::sub_prefix(asset); + let sub_prefix = wrapped_erc20s::sub_prefix(&asset); token::transfer( ctx, sender, @@ -57,11 +60,15 @@ fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { // add transfer into the pool let pending_key = bridge_pool::get_pending_key(&transfer); ctx.write_bytes(&pending_key, transfer.try_to_vec().unwrap()) - .unwrap(); + .map_err(|_| Error::SimpleMessage("Could not write transfer to bridge pool"))?; Ok(()) } -fn native_erc20_address(ctx: &mut Ctx) -> EthAddress { - let addr = ctx.read_bytes(&native_erc20_key()).unwrap().unwrap(); - BorshDeserialize::try_from_slice(addr.as_slice()).unwrap() +fn native_erc20_address(ctx: &mut Ctx) -> EnvResult { + log_string("Trying to get wnam key"); + let addr = ctx.read_bytes(&native_erc20_key()) + .map_err(|_| Error::SimpleMessage("Could not read wNam key from storage"))? + .unwrap(); + log_string("Got wnam key"); + Ok(BorshDeserialize::try_from_slice(addr.as_slice()).unwrap()) } From 92921b8e48d437e79836fe47b9d2aed7786929b8 Mon Sep 17 00:00:00 2001 From: satan Date: Wed, 30 Nov 2022 14:35:23 +0100 Subject: [PATCH 17/28] [feat]: Added type alias for byte vector in merkle storage --- shared/src/ledger/storage/traits.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/shared/src/ledger/storage/traits.rs b/shared/src/ledger/storage/traits.rs index b615abaa98..3b0a58725e 100644 --- a/shared/src/ledger/storage/traits.rs +++ b/shared/src/ledger/storage/traits.rs @@ -15,6 +15,7 @@ use super::{ics23_specs, IBC_KEY_LIMIT}; use crate::ledger::eth_bridge::storage::bridge_pool::BridgePoolTree; use crate::ledger::storage::merkle_tree::StorageBytes; use crate::types::eth_bridge_pool::PendingTransfer; +use crate::ledger::storage::merkle_tree::StorageBytes; use crate::types::hash::Hash; use crate::types::storage::{Key, MembershipProof, StringKey, TreeBytes}; From 7eb1d285b5b0d5d599f8980a7c1ea14460be7eeb Mon Sep 17 00:00:00 2001 From: satan Date: Fri, 2 Dec 2022 15:52:29 +0100 Subject: [PATCH 18/28] [feat]: E2E tests for the bridge pool are now working --- apps/src/lib/client/eth_bridge_pool.rs | 17 +++- apps/src/lib/config/genesis.rs | 22 ++++- shared/src/ledger/storage/traits.rs | 1 - tests/src/e2e/eth_bridge_tests.rs | 111 ++++++++++++++++++++++++- tests/src/e2e/setup.rs | 2 + wasm/checksums.json | 38 +++++---- 6 files changed, 168 insertions(+), 23 deletions(-) diff --git a/apps/src/lib/client/eth_bridge_pool.rs b/apps/src/lib/client/eth_bridge_pool.rs index b697995eb4..09171a9cc9 100644 --- a/apps/src/lib/client/eth_bridge_pool.rs +++ b/apps/src/lib/client/eth_bridge_pool.rs @@ -1,6 +1,9 @@ +use std::collections::HashMap; + use borsh::BorshSerialize; use namada::ledger::queries::RPC; use namada::proto::Tx; +use namada::types::eth_abi::Encode; use namada::types::eth_bridge_pool::{ GasFee, PendingTransfer, TransferToEthereum, }; @@ -67,11 +70,19 @@ pub async fn construct_bridge_pool_proof(args: args::BridgePoolProof) { /// Prints out a json payload. pub async fn query_bridge_pool(args: args::Query) { let client = HttpClient::new(args.ledger_address).unwrap(); - let response = RPC + let response: Vec = RPC .shell() .read_ethereum_bridge_pool(&client) .await .unwrap(); - - println!("{:#?}", serde_json::to_string_pretty(&response)); + let pool_contents: HashMap = response + .into_iter() + .map(|transfer| (transfer.keccak256().to_string(), transfer)) + .collect(); + if pool_contents.is_empty() { + println!("Bridge pool is empty."); + } else { + println!("Bridge pool contents: "); + } + println!("{}", serde_json::to_string_pretty(&pool_contents).unwrap()); } diff --git a/apps/src/lib/config/genesis.rs b/apps/src/lib/config/genesis.rs index d27827a1d9..ffbc22cbba 100644 --- a/apps/src/lib/config/genesis.rs +++ b/apps/src/lib/config/genesis.rs @@ -6,13 +6,16 @@ use std::path::Path; use borsh::{BorshDeserialize, BorshSerialize}; use derivative::Derivative; -use namada::ledger::eth_bridge::parameters::EthereumBridgeConfig; +use namada::ledger::eth_bridge::parameters::{ + Contracts, EthereumBridgeConfig, UpgradeableContract, +}; use namada::ledger::governance::parameters::GovParams; use namada::ledger::parameters::Parameters; use namada::ledger::pos::{GenesisValidator, PosParams}; -use namada::types::address::Address; +use namada::types::address::{wnam, Address}; #[cfg(not(feature = "dev"))] use namada::types::chain::ChainId; +use namada::types::ethereum_events::EthAddress; use namada::types::key::dkg_session_keys::DkgPublicKey; use namada::types::key::*; use namada::types::time::DateTimeUtc; @@ -881,7 +884,20 @@ pub fn genesis() -> Genesis { parameters, pos_params: PosParams::default(), gov_params: GovParams::default(), - ethereum_bridge_params: None, + ethereum_bridge_params: Some(EthereumBridgeConfig { + min_confirmations: Default::default(), + contracts: Contracts { + native_erc20: wnam(), + bridge: UpgradeableContract { + address: EthAddress([0; 20]), + version: Default::default(), + }, + governance: UpgradeableContract { + address: EthAddress([1; 20]), + version: Default::default(), + }, + }, + }), } } diff --git a/shared/src/ledger/storage/traits.rs b/shared/src/ledger/storage/traits.rs index 3b0a58725e..b615abaa98 100644 --- a/shared/src/ledger/storage/traits.rs +++ b/shared/src/ledger/storage/traits.rs @@ -15,7 +15,6 @@ use super::{ics23_specs, IBC_KEY_LIMIT}; use crate::ledger::eth_bridge::storage::bridge_pool::BridgePoolTree; use crate::ledger::storage::merkle_tree::StorageBytes; use crate::types::eth_bridge_pool::PendingTransfer; -use crate::ledger::storage::merkle_tree::StorageBytes; use crate::types::hash::Hash; use crate::types::storage::{Key, MembershipProof, StringKey, TreeBytes}; diff --git a/tests/src/e2e/eth_bridge_tests.rs b/tests/src/e2e/eth_bridge_tests.rs index 57d9fa4793..1dc629394b 100644 --- a/tests/src/e2e/eth_bridge_tests.rs +++ b/tests/src/e2e/eth_bridge_tests.rs @@ -1,11 +1,17 @@ use color_eyre::eyre::Result; +use namada::ledger::eth_bridge::parameters::{ + Contracts, EthereumBridgeConfig, UpgradeableContract, +}; +use namada::types::address::wnam; +use namada::types::ethereum_events::testing::DAI_ERC20_ETH_ADDRESS_CHECKSUMMED; +use namada::types::ethereum_events::EthAddress; use namada_apps::config::ethereum_bridge; use super::setup::set_ethereum_bridge_mode; use crate::e2e::helpers::get_actor_rpc; use crate::e2e::setup; use crate::e2e::setup::constants::{ - wasm_abs_path, ALBERT, TX_WRITE_STORAGE_KEY_WASM, + wasm_abs_path, ALBERT, BERTHA, NAM, TX_WRITE_STORAGE_KEY_WASM, }; use crate::e2e::setup::{Bin, Who}; use crate::{run, run_as}; @@ -125,3 +131,106 @@ fn run_ledger_with_ethereum_events_endpoint() -> Result<()> { Ok(()) } + +/// In this test, we check the following: +/// 1. We can successfully add tranfers to the bridge pool. +/// 2. We can query the bridge pool and it is non-empty. +#[test] +fn test_add_to_bridge_pool() { + const LEDGER_STARTUP_TIMEOUT_SECONDS: u64 = 40; + const CLIENT_COMMAND_TIMEOUT_SECONDS: u64 = 60; + const QUERY_TIMEOUT_SECONDS: u64 = 40; + const SOLE_VALIDATOR: Who = Who::Validator(0); + let wnam_address = wnam().to_canonical(); + let test = setup::network( + |mut genesis| { + genesis.ethereum_bridge_params = Some(EthereumBridgeConfig { + min_confirmations: Default::default(), + contracts: Contracts { + native_erc20: wnam(), + bridge: UpgradeableContract { + address: EthAddress([0; 20]), + version: Default::default(), + }, + governance: UpgradeableContract { + address: EthAddress([1; 20]), + version: Default::default(), + }, + }, + }); + genesis + }, + None, + ) + .unwrap(); + set_ethereum_bridge_mode( + &test, + &test.net.chain_id, + &Who::Validator(0), + ethereum_bridge::ledger::Mode::EventsEndpoint, + ); + + let mut namadan_ledger = run_as!( + test, + SOLE_VALIDATOR, + Bin::Node, + &["ledger"], + Some(LEDGER_STARTUP_TIMEOUT_SECONDS) + ) + .unwrap(); + namadan_ledger + .exp_string("Anoma ledger node started") + .unwrap(); + namadan_ledger + .exp_string("Tendermint node started") + .unwrap(); + namadan_ledger.exp_string("Committed block hash").unwrap(); + let _bg_ledger = namadan_ledger.background(); + + let ledger_addr = get_actor_rpc(&test, &SOLE_VALIDATOR); + let tx_args = vec![ + "add-erc20-transfer", + "--address", + BERTHA, + "--signer", + BERTHA, + "--amount", + "100", + "--erc20", + &wnam_address, + "--ethereum-address", + DAI_ERC20_ETH_ADDRESS_CHECKSUMMED, + "--fee-amount", + "10", + "--fee-payer", + BERTHA, + "--gas-amount", + "0", + "--gas-limit", + "0", + "--gas-token", + NAM, + "--ledger-address", + &ledger_addr, + ]; + + let mut namadac_tx = run!( + test, + Bin::Client, + tx_args, + Some(CLIENT_COMMAND_TIMEOUT_SECONDS) + ) + .unwrap(); + namadac_tx.exp_string("Transaction applied").unwrap(); + namadac_tx.exp_string("Transaction is valid").unwrap(); + drop(namadac_tx); + + let mut namadar = run!( + test, + Bin::BridgePool, + ["query", "--ledger-address", &ledger_addr,], + Some(QUERY_TIMEOUT_SECONDS), + ) + .unwrap(); + namadar.exp_string("Bridge pool contents:").unwrap(); +} diff --git a/tests/src/e2e/setup.rs b/tests/src/e2e/setup.rs index 773a93069c..cf02c3e790 100644 --- a/tests/src/e2e/setup.rs +++ b/tests/src/e2e/setup.rs @@ -253,6 +253,7 @@ pub enum Bin { Node, Client, Wallet, + BridgePool, } #[derive(Debug)] @@ -711,6 +712,7 @@ where Bin::Node => ("namadan", "info"), Bin::Client => ("namadac", "tendermint_rpc=debug"), Bin::Wallet => ("namadaw", "info"), + Bin::BridgePool => ("namadar", "info"), }; let mut run_cmd = generate_bin_command( diff --git a/wasm/checksums.json b/wasm/checksums.json index 24e4c0b43e..8e54008eac 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,17 +1,25 @@ { - "tx_bond.wasm": "tx_bond.4fc2b1c226d57d94e4043109d1af164ac69f8eb72e12525d97a123d8100817af.wasm", - "tx_bridge_pool.wasm": "tx_bridge_pool.f41d51ed01d5c60909c8ff9a7ed31f19b2d3ef42c24d1daa4143d59e0e797d97.wasm", - "tx_ibc.wasm": "tx_ibc.582a0a6433782caaee708205fc22f40d2af34fcd6994ac8f5fb8bef627778b4d.wasm", - "tx_init_account.wasm": "tx_init_account.0c204ba845658516b20670346c0682595d16d1ca99f42eddde51d1cde4295ffb.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.0a9cbdd68510d723818bb5d95cb0770b4f054ca402f8bbcff18108ea413875de.wasm", - "tx_init_validator.wasm": "tx_init_validator.09d0e561565cb083cb243b4594882c4f424eda73a91f89cce1e814b35ba2eae5.wasm", - "tx_transfer.wasm": "tx_transfer.9f4ad0aed0f1fcf21398c4d12da4ae26937415b01524811c0dceb810f1d1bf4a.wasm", - "tx_unbond.wasm": "tx_unbond.72018d106cca5a856bca041ea30eee579ec61d29f246f1387f3da4ef72c6cfbd.wasm", - "tx_update_vp.wasm": "tx_update_vp.4d585d52ed7f3b1507ed092df82ff7edec362305eb9e84f4dae06f09d75cc727.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.49638241211faf327390a0f07920d8dd40c9d7676d9c1beccd3bad0ff5f6f1a9.wasm", - "tx_withdraw.wasm": "tx_withdraw.1f8faa002868664e42d6e4b7140d5f295a2a0f1e99968656ee4d91c496b8f08d.wasm", - "vp_masp.wasm": "vp_masp.ad12a384f8690ad1a7c084b0a2ce7e72b9743fac7b2229f9a0e290fd0e75619a.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.e7d6cc83ad23f7db10484a051e6ba25105900b154e179768ccc79b955d6f47ca.wasm", - "vp_token.wasm": "vp_token.fbec5c10439c0f2d421799188f9ab677967b931535262dbf4cc7591ea0978aa7.wasm", - "vp_user.wasm": "vp_user.4db5100a828f04ed1fe6d2fee09b56facd8dde1e3bc0ea8d288875bf934d581a.wasm" + "tx_bond.wasm": "tx_bond.d39b2ae31f454a352d9ed31db2d4b55fadb2246eb7fb736890100de77fb57f84.wasm", + "tx_bridge_pool.wasm": "tx_bridge_pool.5ad5652c40311fffb98f5b452c06928ceccb8a94fb6a1524368cce3e4445e8aa.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.2ddee7d15e2e9884f98c8a423a140ba9ac89417ccfcc8473615a464a0d4acf0a.wasm", + "tx_from_intent.wasm": "tx_from_intent.8d25dc3453f6ea39b7b2a3574ff47f26a17ee91e1c71f88adf116dd34cb198dc.wasm", + "tx_ibc.wasm": "tx_ibc.9ec5f2d7e3abf9847d414fcfbf5b1a2cadf166991c8ae941a8a10c6f2fc701fd.wasm", + "tx_init_account.wasm": "tx_init_account.2ca339b1a54239555853a5ace3aba1702d4a2027add6ba53ed1dd3814e45e1a1.wasm", + "tx_init_nft.wasm": "tx_init_nft.5fb223d13032f03e454a763125e69d9188b0bff54f14967161b91dd2bc8efc27.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.c530e0ff5ab37cef227cbc1f26f58daf9c70ca15edc9e714f9ade6d0a989ec61.wasm", + "tx_init_validator.wasm": "tx_init_validator.6504445e5c18660bf8f4e1b42baadf1cd200943b092e90c8a93bdad40ebc7961.wasm", + "tx_mint_nft.wasm": "tx_mint_nft.1278e59c0ed5f0b9834ce121b69f7f3ccba91e7ff4be305b5fa898cdc324690c.wasm", + "tx_reveal_pk.wasm": "tx_reveal_pk.b4d258ab70fdb136bacfa1c2caa765b596c796b330ff81c5756c080f2e21b36b.wasm", + "tx_transfer.wasm": "tx_transfer.ba8a40548e65d7af64e9151a44c4e45c9e4e5d0e8b4bd26b74ecc36fc752c349.wasm", + "tx_unbond.wasm": "tx_unbond.19f40a5bb264aacde8725ea475d73be3618281171d344bd6fc825e970e7fbcf9.wasm", + "tx_update_vp.wasm": "tx_update_vp.5dae0339928ab57bd938b1b10437127e9b01fd43f584103ba703424229a72618.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.60940ab81a965afbc5a1c973d5b4fbd917add369fe561c7ef2ba70b9835dbdae.wasm", + "tx_withdraw.wasm": "tx_withdraw.8496025271b977e5543647cd68452c2d17f4173537fd5390f0e8c379fdfc9a44.wasm", + "vp_implicit.wasm": "vp_implicit.ef275670c60bb360ae7ffe5e5153c06dd18ad63110ce47396114416bcf82ebb8.wasm", + "vp_masp.wasm": "vp_masp.e8b7276779cfd69eaa980f5e1cca3879073b0ac987170c58d0f867c9ecf0cb48.wasm", + "vp_nft.wasm": "vp_nft.173da472fb0b54d24a0e7f45ef78dc7a045b6119967045e37e20b6844db1dd4d.wasm", + "vp_testnet_faucet.wasm": "vp_testnet_faucet.9ef0688ce368780e0d77160c22e3655bdde1295ac6357ce10f83eda04d9f2075.wasm", + "vp_token.wasm": "vp_token.4df4c16e3276ab80cd9be6f21c88b37091d17a7dc021b12f950c742be6ed3794.wasm", + "vp_user.wasm": "vp_user.997779f95f446909d5dc27b879ba31d8ebf811bb9875e329701521991b52657b.wasm", + "vp_validator.wasm": "vp_validator.e335315f0fcd81c869a66d1d9be9b98ea3e102076379a038cbf7eb86d2d85685.wasm" } \ No newline at end of file From 72e22c795666c7f69a22e2ae5c5915c349718d05 Mon Sep 17 00:00:00 2001 From: Jacob Turner Date: Tue, 6 Dec 2022 13:20:05 +0100 Subject: [PATCH 19/28] Update apps/src/lib/client/eth_bridge_pool.rs Co-authored-by: Tiago Carvalho --- apps/src/lib/client/eth_bridge_pool.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/src/lib/client/eth_bridge_pool.rs b/apps/src/lib/client/eth_bridge_pool.rs index 09171a9cc9..94f2ce1208 100644 --- a/apps/src/lib/client/eth_bridge_pool.rs +++ b/apps/src/lib/client/eth_bridge_pool.rs @@ -81,6 +81,7 @@ pub async fn query_bridge_pool(args: args::Query) { .collect(); if pool_contents.is_empty() { println!("Bridge pool is empty."); + return; } else { println!("Bridge pool contents: "); } From f94015b1f9e2d73d8a62ecd61dc06cb2d0105bf6 Mon Sep 17 00:00:00 2001 From: Jacob Turner Date: Tue, 6 Dec 2022 13:21:10 +0100 Subject: [PATCH 20/28] Update tests/src/e2e/eth_bridge_tests.rs Co-authored-by: Tiago Carvalho --- tests/src/e2e/eth_bridge_tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/src/e2e/eth_bridge_tests.rs b/tests/src/e2e/eth_bridge_tests.rs index 1dc629394b..c447efe5cc 100644 --- a/tests/src/e2e/eth_bridge_tests.rs +++ b/tests/src/e2e/eth_bridge_tests.rs @@ -221,6 +221,7 @@ fn test_add_to_bridge_pool() { Some(CLIENT_COMMAND_TIMEOUT_SECONDS) ) .unwrap(); + namadac_tx.exp_string("Transaction accepted").unwrap(); namadac_tx.exp_string("Transaction applied").unwrap(); namadac_tx.exp_string("Transaction is valid").unwrap(); drop(namadac_tx); From 685d50b551adfa9d014381b7f0dfcb5501702878 Mon Sep 17 00:00:00 2001 From: satan Date: Tue, 6 Dec 2022 13:47:43 +0100 Subject: [PATCH 21/28] [feat]: Added e2e test to CI workflow --- .github/workflows/scripts/e2e.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/scripts/e2e.json b/.github/workflows/scripts/e2e.json index fd8939ba9a..e2fc12f9ea 100644 --- a/.github/workflows/scripts/e2e.json +++ b/.github/workflows/scripts/e2e.json @@ -1,5 +1,6 @@ { "e2e::eth_bridge_tests::everything": 4, + "e2e::eth_bridge_tests::test_add_to_bridge_pool": 10, "e2e::ledger_tests::double_signing_gets_slashed": 12, "e2e::ledger_tests::invalid_transactions": 8, "e2e::ledger_tests::ledger_many_txs_in_a_block": 41, From e95d71a03127d2c9848f427648b84f0652660bb1 Mon Sep 17 00:00:00 2001 From: satan Date: Tue, 6 Dec 2022 16:02:38 +0100 Subject: [PATCH 22/28] [feat]: Birdge pool query now returns only a json payload --- apps/src/lib/client/eth_bridge_pool.rs | 13 ++++++++++--- tests/src/e2e/eth_bridge_tests.rs | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/apps/src/lib/client/eth_bridge_pool.rs b/apps/src/lib/client/eth_bridge_pool.rs index 94f2ce1208..1f4594c92b 100644 --- a/apps/src/lib/client/eth_bridge_pool.rs +++ b/apps/src/lib/client/eth_bridge_pool.rs @@ -7,6 +7,7 @@ use namada::types::eth_abi::Encode; use namada::types::eth_bridge_pool::{ GasFee, PendingTransfer, TransferToEthereum, }; +use serde::{Deserialize, Serialize}; use super::signing::TxSigningKey; use super::tx::process_tx; @@ -66,6 +67,13 @@ pub async fn construct_bridge_pool_proof(args: args::BridgePoolProof) { ); } +/// A json serializable representation of the Ethereum +/// bridge pool. +#[derive(Serialize, Deserialize)] +struct BridgePoolResponse { + bridge_pool_contents: HashMap, +} + /// Query the contents of the Ethereum bridge pool. /// Prints out a json payload. pub async fn query_bridge_pool(args: args::Query) { @@ -82,8 +90,7 @@ pub async fn query_bridge_pool(args: args::Query) { if pool_contents.is_empty() { println!("Bridge pool is empty."); return; - } else { - println!("Bridge pool contents: "); } - println!("{}", serde_json::to_string_pretty(&pool_contents).unwrap()); + let contents = BridgePoolResponse{ bridge_pool_contents: pool_contents}; + println!("{}", serde_json::to_string_pretty(&contents).unwrap()); } diff --git a/tests/src/e2e/eth_bridge_tests.rs b/tests/src/e2e/eth_bridge_tests.rs index c447efe5cc..b124f967b9 100644 --- a/tests/src/e2e/eth_bridge_tests.rs +++ b/tests/src/e2e/eth_bridge_tests.rs @@ -233,5 +233,5 @@ fn test_add_to_bridge_pool() { Some(QUERY_TIMEOUT_SECONDS), ) .unwrap(); - namadar.exp_string("Bridge pool contents:").unwrap(); + namadar.exp_string(r#""bridge_pool_contents":"#).unwrap(); } From db48ac94986d03bbe29d22e03fff8d832e55d271 Mon Sep 17 00:00:00 2001 From: satan Date: Tue, 6 Dec 2022 16:10:33 +0100 Subject: [PATCH 23/28] [fix]: Removed DAI address as receiver address from e2e test --- tests/src/e2e/eth_bridge_tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/e2e/eth_bridge_tests.rs b/tests/src/e2e/eth_bridge_tests.rs index b124f967b9..9d39c6ce03 100644 --- a/tests/src/e2e/eth_bridge_tests.rs +++ b/tests/src/e2e/eth_bridge_tests.rs @@ -3,7 +3,6 @@ use namada::ledger::eth_bridge::parameters::{ Contracts, EthereumBridgeConfig, UpgradeableContract, }; use namada::types::address::wnam; -use namada::types::ethereum_events::testing::DAI_ERC20_ETH_ADDRESS_CHECKSUMMED; use namada::types::ethereum_events::EthAddress; use namada_apps::config::ethereum_bridge; @@ -141,6 +140,7 @@ fn test_add_to_bridge_pool() { const CLIENT_COMMAND_TIMEOUT_SECONDS: u64 = 60; const QUERY_TIMEOUT_SECONDS: u64 = 40; const SOLE_VALIDATOR: Who = Who::Validator(0); + const RECEIVER: &str = "0x6B175474E89094C55Da98b954EedeAC495271d0F"; let wnam_address = wnam().to_canonical(); let test = setup::network( |mut genesis| { @@ -199,7 +199,7 @@ fn test_add_to_bridge_pool() { "--erc20", &wnam_address, "--ethereum-address", - DAI_ERC20_ETH_ADDRESS_CHECKSUMMED, + RECEIVER, "--fee-amount", "10", "--fee-payer", From fd6a396ca07fe7eadd091a1b9552ba61bb9ea0ca Mon Sep 17 00:00:00 2001 From: Jacob Turner Date: Wed, 7 Dec 2022 10:36:07 +0100 Subject: [PATCH 24/28] Update wasm/wasm_source/src/tx_bridge_pool.rs Co-authored-by: James --- wasm/wasm_source/src/tx_bridge_pool.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wasm/wasm_source/src/tx_bridge_pool.rs b/wasm/wasm_source/src/tx_bridge_pool.rs index d162422967..0f4c2c2139 100644 --- a/wasm/wasm_source/src/tx_bridge_pool.rs +++ b/wasm/wasm_source/src/tx_bridge_pool.rs @@ -8,10 +8,10 @@ use namada_tx_prelude::*; #[transaction] fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { let signed = SignedTxData::try_from_slice(&tx_data[..]) - .map_err(|_| Error::SimpleMessage("Data not signed."))?; + .map_err(|e| Error::wrap("Error deserializing SignedTxData", e))?; let transfer = PendingTransfer::try_from_slice(&signed.data.unwrap()[..]) - .map_err(|_| { - Error::SimpleMessage("Error deserializing PendingTransfer") + .map_err(|e| { + Error::wrap("Error deserializing PendingTransfer", e) })?; log_string("Received transfer to add to pool."); // pay the gas fees From 80c1897bce23a0ac83a4a24890407c12ad5d8c98 Mon Sep 17 00:00:00 2001 From: Jacob Turner Date: Wed, 7 Dec 2022 10:36:28 +0100 Subject: [PATCH 25/28] Update wasm/wasm_source/src/tx_bridge_pool.rs Co-authored-by: James --- wasm/wasm_source/src/tx_bridge_pool.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wasm/wasm_source/src/tx_bridge_pool.rs b/wasm/wasm_source/src/tx_bridge_pool.rs index 0f4c2c2139..1b535ce442 100644 --- a/wasm/wasm_source/src/tx_bridge_pool.rs +++ b/wasm/wasm_source/src/tx_bridge_pool.rs @@ -63,9 +63,7 @@ fn apply_tx(ctx: &mut Ctx, tx_data: Vec) -> TxResult { // add transfer into the pool let pending_key = bridge_pool::get_pending_key(&transfer); ctx.write_bytes(&pending_key, transfer.try_to_vec().unwrap()) - .map_err(|_| { - Error::SimpleMessage("Could not write transfer to bridge pool") - })?; + .wrap_err("Could not write transfer to bridge pool")?; Ok(()) } From 7c77d5e03f9cfa8ff8ef543353633caebd2dd960 Mon Sep 17 00:00:00 2001 From: Jacob Turner Date: Wed, 7 Dec 2022 10:36:42 +0100 Subject: [PATCH 26/28] Update wasm/wasm_source/src/tx_bridge_pool.rs Co-authored-by: James --- wasm/wasm_source/src/tx_bridge_pool.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wasm/wasm_source/src/tx_bridge_pool.rs b/wasm/wasm_source/src/tx_bridge_pool.rs index 1b535ce442..e246bdb930 100644 --- a/wasm/wasm_source/src/tx_bridge_pool.rs +++ b/wasm/wasm_source/src/tx_bridge_pool.rs @@ -71,9 +71,7 @@ fn native_erc20_address(ctx: &mut Ctx) -> EnvResult { log_string("Trying to get wnam key"); let addr = ctx .read_bytes(&native_erc20_key()) - .map_err(|_| { - Error::SimpleMessage("Could not read wNam key from storage") - })? + .map_err(|e| Error::wrap("Could not read wNam key from storage", e))? .unwrap(); log_string("Got wnam key"); Ok(BorshDeserialize::try_from_slice(addr.as_slice()).unwrap()) From e02f00c11b27708c1e5c2b11613a131816acf44d Mon Sep 17 00:00:00 2001 From: satan Date: Wed, 7 Dec 2022 10:41:17 +0100 Subject: [PATCH 27/28] [fix]: reverted wasm/checksums.json --- wasm/checksums.json | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/wasm/checksums.json b/wasm/checksums.json index 8e54008eac..24e4c0b43e 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,25 +1,17 @@ { - "tx_bond.wasm": "tx_bond.d39b2ae31f454a352d9ed31db2d4b55fadb2246eb7fb736890100de77fb57f84.wasm", - "tx_bridge_pool.wasm": "tx_bridge_pool.5ad5652c40311fffb98f5b452c06928ceccb8a94fb6a1524368cce3e4445e8aa.wasm", - "tx_change_validator_commission.wasm": "tx_change_validator_commission.2ddee7d15e2e9884f98c8a423a140ba9ac89417ccfcc8473615a464a0d4acf0a.wasm", - "tx_from_intent.wasm": "tx_from_intent.8d25dc3453f6ea39b7b2a3574ff47f26a17ee91e1c71f88adf116dd34cb198dc.wasm", - "tx_ibc.wasm": "tx_ibc.9ec5f2d7e3abf9847d414fcfbf5b1a2cadf166991c8ae941a8a10c6f2fc701fd.wasm", - "tx_init_account.wasm": "tx_init_account.2ca339b1a54239555853a5ace3aba1702d4a2027add6ba53ed1dd3814e45e1a1.wasm", - "tx_init_nft.wasm": "tx_init_nft.5fb223d13032f03e454a763125e69d9188b0bff54f14967161b91dd2bc8efc27.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.c530e0ff5ab37cef227cbc1f26f58daf9c70ca15edc9e714f9ade6d0a989ec61.wasm", - "tx_init_validator.wasm": "tx_init_validator.6504445e5c18660bf8f4e1b42baadf1cd200943b092e90c8a93bdad40ebc7961.wasm", - "tx_mint_nft.wasm": "tx_mint_nft.1278e59c0ed5f0b9834ce121b69f7f3ccba91e7ff4be305b5fa898cdc324690c.wasm", - "tx_reveal_pk.wasm": "tx_reveal_pk.b4d258ab70fdb136bacfa1c2caa765b596c796b330ff81c5756c080f2e21b36b.wasm", - "tx_transfer.wasm": "tx_transfer.ba8a40548e65d7af64e9151a44c4e45c9e4e5d0e8b4bd26b74ecc36fc752c349.wasm", - "tx_unbond.wasm": "tx_unbond.19f40a5bb264aacde8725ea475d73be3618281171d344bd6fc825e970e7fbcf9.wasm", - "tx_update_vp.wasm": "tx_update_vp.5dae0339928ab57bd938b1b10437127e9b01fd43f584103ba703424229a72618.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.60940ab81a965afbc5a1c973d5b4fbd917add369fe561c7ef2ba70b9835dbdae.wasm", - "tx_withdraw.wasm": "tx_withdraw.8496025271b977e5543647cd68452c2d17f4173537fd5390f0e8c379fdfc9a44.wasm", - "vp_implicit.wasm": "vp_implicit.ef275670c60bb360ae7ffe5e5153c06dd18ad63110ce47396114416bcf82ebb8.wasm", - "vp_masp.wasm": "vp_masp.e8b7276779cfd69eaa980f5e1cca3879073b0ac987170c58d0f867c9ecf0cb48.wasm", - "vp_nft.wasm": "vp_nft.173da472fb0b54d24a0e7f45ef78dc7a045b6119967045e37e20b6844db1dd4d.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.9ef0688ce368780e0d77160c22e3655bdde1295ac6357ce10f83eda04d9f2075.wasm", - "vp_token.wasm": "vp_token.4df4c16e3276ab80cd9be6f21c88b37091d17a7dc021b12f950c742be6ed3794.wasm", - "vp_user.wasm": "vp_user.997779f95f446909d5dc27b879ba31d8ebf811bb9875e329701521991b52657b.wasm", - "vp_validator.wasm": "vp_validator.e335315f0fcd81c869a66d1d9be9b98ea3e102076379a038cbf7eb86d2d85685.wasm" + "tx_bond.wasm": "tx_bond.4fc2b1c226d57d94e4043109d1af164ac69f8eb72e12525d97a123d8100817af.wasm", + "tx_bridge_pool.wasm": "tx_bridge_pool.f41d51ed01d5c60909c8ff9a7ed31f19b2d3ef42c24d1daa4143d59e0e797d97.wasm", + "tx_ibc.wasm": "tx_ibc.582a0a6433782caaee708205fc22f40d2af34fcd6994ac8f5fb8bef627778b4d.wasm", + "tx_init_account.wasm": "tx_init_account.0c204ba845658516b20670346c0682595d16d1ca99f42eddde51d1cde4295ffb.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.0a9cbdd68510d723818bb5d95cb0770b4f054ca402f8bbcff18108ea413875de.wasm", + "tx_init_validator.wasm": "tx_init_validator.09d0e561565cb083cb243b4594882c4f424eda73a91f89cce1e814b35ba2eae5.wasm", + "tx_transfer.wasm": "tx_transfer.9f4ad0aed0f1fcf21398c4d12da4ae26937415b01524811c0dceb810f1d1bf4a.wasm", + "tx_unbond.wasm": "tx_unbond.72018d106cca5a856bca041ea30eee579ec61d29f246f1387f3da4ef72c6cfbd.wasm", + "tx_update_vp.wasm": "tx_update_vp.4d585d52ed7f3b1507ed092df82ff7edec362305eb9e84f4dae06f09d75cc727.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.49638241211faf327390a0f07920d8dd40c9d7676d9c1beccd3bad0ff5f6f1a9.wasm", + "tx_withdraw.wasm": "tx_withdraw.1f8faa002868664e42d6e4b7140d5f295a2a0f1e99968656ee4d91c496b8f08d.wasm", + "vp_masp.wasm": "vp_masp.ad12a384f8690ad1a7c084b0a2ce7e72b9743fac7b2229f9a0e290fd0e75619a.wasm", + "vp_testnet_faucet.wasm": "vp_testnet_faucet.e7d6cc83ad23f7db10484a051e6ba25105900b154e179768ccc79b955d6f47ca.wasm", + "vp_token.wasm": "vp_token.fbec5c10439c0f2d421799188f9ab677967b931535262dbf4cc7591ea0978aa7.wasm", + "vp_user.wasm": "vp_user.4db5100a828f04ed1fe6d2fee09b56facd8dde1e3bc0ea8d288875bf934d581a.wasm" } \ No newline at end of file From d681d44080ea3281e805e4f73280dd9fa33cf38d Mon Sep 17 00:00:00 2001 From: satan Date: Wed, 7 Dec 2022 10:42:05 +0100 Subject: [PATCH 28/28] [fix]: Formatting --- apps/src/lib/client/eth_bridge_pool.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/src/lib/client/eth_bridge_pool.rs b/apps/src/lib/client/eth_bridge_pool.rs index 1f4594c92b..a33c03bac4 100644 --- a/apps/src/lib/client/eth_bridge_pool.rs +++ b/apps/src/lib/client/eth_bridge_pool.rs @@ -91,6 +91,8 @@ pub async fn query_bridge_pool(args: args::Query) { println!("Bridge pool is empty."); return; } - let contents = BridgePoolResponse{ bridge_pool_contents: pool_contents}; + let contents = BridgePoolResponse { + bridge_pool_contents: pool_contents, + }; println!("{}", serde_json::to_string_pretty(&contents).unwrap()); }