From 37e24b8d7078847092409b92129ce2bc52b7db5c Mon Sep 17 00:00:00 2001 From: Damilare Date: Wed, 16 Feb 2022 15:46:59 +0100 Subject: [PATCH 1/8] cross withdrawal test --- Cargo.lock | 2 + pallets/anchor/src/lib.rs | 4 + pallets/anchor/src/tests.rs | 2 + pallets/linkable-tree/src/lib.rs | 3 + pallets/mt/src/lib.rs | 2 + pallets/xanchor/Cargo.toml | 3 + pallets/xanchor/src/lib.rs | 6 +- pallets/xanchor/src/mock/mod.rs | 1 + pallets/xanchor/src/mock/test_utils.rs | 165 +++++++++++++++++++++ pallets/xanchor/src/tests.rs | 194 ++++++++++++++++++++++++- 10 files changed, 379 insertions(+), 3 deletions(-) create mode 100644 pallets/xanchor/src/mock/test_utils.rs diff --git a/Cargo.lock b/Cargo.lock index 74c93b43e..04d13eada 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5229,6 +5229,7 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", + "hex", "orml-currencies", "orml-tokens", "orml-traits", @@ -5254,6 +5255,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std", + "wasm-utils", "webb-primitives", "xcm", "xcm-builder", diff --git a/pallets/anchor/src/lib.rs b/pallets/anchor/src/lib.rs index 91207eb0c..52d309e0a 100644 --- a/pallets/anchor/src/lib.rs +++ b/pallets/anchor/src/lib.rs @@ -385,6 +385,10 @@ impl, I: 'static> AnchorInterface> for Pal bytes.extend_from_slice(&fee_bytes); bytes.extend_from_slice(&refund_bytes); bytes.extend_from_slice(&commitment.encode()); + println!("WITHDRAW PROOF bytes"); + println!("{:?}", &bytes); + println!("WITHDRAW PROOF proof_bytes"); + println!("{:?}", &proof_bytes); let result = >::Verifier::verify(&bytes, proof_bytes)?; ensure!(result, Error::::InvalidWithdrawProof); // withdraw or refresh depending on the refresh commitment value diff --git a/pallets/anchor/src/tests.rs b/pallets/anchor/src/tests.rs index de9a0d0ae..7adf268ba 100644 --- a/pallets/anchor/src/tests.rs +++ b/pallets/anchor/src/tests.rs @@ -166,7 +166,9 @@ fn anchor_works() { // inputs let tree_id = create_anchor(0); + dbg!(tree_id); let src_chain_id = compute_chain_id_type(1u32, SUBSTRATE_CHAIN_TYPE); + dbg!(src_chain_id); let sender_account_id = account::("", 1, SEED); let recipient_account_id = account::("", 2, SEED); let relayer_account_id = account::("", 0, SEED); diff --git a/pallets/linkable-tree/src/lib.rs b/pallets/linkable-tree/src/lib.rs index ed5fd87d0..cecf28e56 100644 --- a/pallets/linkable-tree/src/lib.rs +++ b/pallets/linkable-tree/src/lib.rs @@ -393,6 +393,9 @@ impl, I: 'static> LinkableTreeInspector::iter_prefix(id).into_iter().collect::>(); + println!("nighbor roots"); + println!("{:?}", edges); + // Check membership of provided historical neighbor roots for (i, (chain_id, _)) in edges.iter().enumerate() { Self::ensure_known_neighbor_root(id, *chain_id, roots[i + 1])?; diff --git a/pallets/mt/src/lib.rs b/pallets/mt/src/lib.rs index 4b0b82b4e..2ebfa862e 100644 --- a/pallets/mt/src/lib.rs +++ b/pallets/mt/src/lib.rs @@ -453,6 +453,8 @@ impl, I: 'static> TreeInspector Result { ensure!(Trees::::contains_key(tree_id), Error::::TreeDoesntExist); + println!("{:?}", tree_id); + println!("{:?}", target_root); let mut temp: T::RootIndex = Zero::zero(); while temp < T::RootHistorySize::get() { let cached_root = CachedRoots::::get(tree_id, temp); diff --git a/pallets/xanchor/Cargo.toml b/pallets/xanchor/Cargo.toml index 9a645b40d..83b615e61 100644 --- a/pallets/xanchor/Cargo.toml +++ b/pallets/xanchor/Cargo.toml @@ -64,6 +64,9 @@ polkadot-core-primitives = { git = "https://github.com/paritytech/polkadot", bra polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false } polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false } +wasm-utils = { version = "0.1.1" } +hex = "0.4" + [features] default = ["std"] std = [ diff --git a/pallets/xanchor/src/lib.rs b/pallets/xanchor/src/lib.rs index 6340b4c46..9c35d81ee 100644 --- a/pallets/xanchor/src/lib.rs +++ b/pallets/xanchor/src/lib.rs @@ -682,17 +682,21 @@ impl, I: 'static> Pallet { .encode() .into(), }; - println!("{:?}", update_edge); + println!("{:?}", "updating edge"); + println!("{:?}", r_id); + println!("{:?}", other_para_id); let dest = (Parent, Parachain(other_para_id.into())); let result = T::XcmSender::send_xcm(dest, Xcm(vec![update_edge])); match result { Ok(()) => { + println!("{:?}", "acnchor updated"); Self::deposit_event(Event::RemoteAnchorEdgeUpdated { para_id: other_para_id, resource_id: r_id, }); }, Err(e) => { + println!("{:?}", "acnchor update failed"); Self::deposit_event(Event::RemoteAnchorEdgeUpdateFailed { para_id: other_para_id, resource_id: r_id, diff --git a/pallets/xanchor/src/mock/mod.rs b/pallets/xanchor/src/mock/mod.rs index e0e621750..6e7ec1170 100644 --- a/pallets/xanchor/src/mock/mod.rs +++ b/pallets/xanchor/src/mock/mod.rs @@ -1,5 +1,6 @@ pub mod parachain; pub mod relay_chain; +pub(crate) mod test_utils; use std::ops::Mul; diff --git a/pallets/xanchor/src/mock/test_utils.rs b/pallets/xanchor/src/mock/test_utils.rs new file mode 100644 index 000000000..457743d4e --- /dev/null +++ b/pallets/xanchor/src/mock/test_utils.rs @@ -0,0 +1,165 @@ +use ark_bn254::Bn254; +use ark_ff::{BigInteger, PrimeField}; +use arkworks_circuits::setup::anchor::{ + setup_leaf_with_privates_raw_x5_4, setup_leaf_x5_4, setup_proof_x5_4, AnchorProverSetup, +}; + +use arkworks_utils::utils::common::{setup_params_x5_3, setup_params_x5_4, Curve}; +use webb_primitives::ElementTrait; + +use crate::mock::parachain::Element; +use wasm_utils::{ + note::JsNote, + proof::{generate_proof_js, AnchorProofInput, JsProofInput, ProofInput, ProofInputBuilder}, + types::{Backend, Curve as WasmCurve, Leaves}, +}; + +type Bn254Fr = ark_bn254::Fr; + +type ProofBytes = Vec; +type RootsElement = Vec; +type NullifierHashElement = Element; +type LeafElement = Element; + +// merkle proof path legth +// TreeConfig_x5, x7 HEIGHT is hardcoded to 30 +pub const TREE_DEPTH: usize = 30; +pub const M: usize = 2; +pub type AnchorSetup30_2 = AnchorProverSetup; + +pub fn setup_zk_circuit( + curve: Curve, + recipient_bytes: Vec, + relayer_bytes: Vec, + commitment_bytes: Vec, + pk_bytes: Vec, + src_chain_id: u64, + fee_value: u128, + refund_value: u128, +) -> (ProofBytes, RootsElement, NullifierHashElement, LeafElement) { + let rng = &mut ark_std::test_rng(); + + match curve { + Curve::Bn254 => { + let (secret, nullifier, leaf, nullifier_hash) = + setup_leaf_x5_4::(Curve::Bn254, src_chain_id.into(), rng).unwrap(); + let leaves = vec![leaf.clone()]; + let leaves_f = vec![Bn254Fr::from_le_bytes_mod_order(&leaf)]; + let index = 0; + + let params3 = setup_params_x5_3::(curve); + let params4 = setup_params_x5_4::(curve); + let anchor_setup = AnchorSetup30_2::new(params3, params4); + let (tree, _) = anchor_setup.setup_tree_and_path(&leaves_f, index).unwrap(); + let roots_f = [tree.root().inner(); M]; + let roots_raw = roots_f.map(|x| x.into_repr().to_bytes_le()); + + let (proof, ..) = setup_proof_x5_4::( + curve, + src_chain_id.into(), + secret, + nullifier, + leaves, + index, + roots_raw.clone(), + recipient_bytes, + relayer_bytes, + commitment_bytes, + fee_value, + refund_value, + pk_bytes, + rng, + ) + .unwrap(); + + let roots_element = roots_raw.map(|x| Element::from_bytes(&x)).to_vec(); + let nullifier_hash_element = Element::from_bytes(&nullifier_hash); + let leaf_element = Element::from_bytes(&leaf); + + (proof, roots_element, nullifier_hash_element, leaf_element) + }, + Curve::Bls381 => { + unimplemented!() + }, + } +} + +pub fn setup_wasm_utils_zk_circuit( + curve: Curve, + recipient_bytes: Vec, + relayer_bytes: Vec, + commitment_bytes: [u8; 32], + pk_bytes: Vec, + src_chain_id: u128, + fee_value: u128, + refund_value: u128, +) -> ( + Vec, // proof bytes + Vec, // roots + Element, // nullifier_hash + Element, // leaf +) { + match curve { + Curve::Bn254 => { + let note_secret = "7e0f4bfa263d8b93854772c94851c04b3a9aba38ab808a8d081f6f5be9758110b7147c395ee9bf495734e4703b1f622009c81712520de0bbd5e7a10237c7d829bf6bd6d0729cca778ed9b6fb172bbb12b01927258aca7e0a66fd5691548f8717"; + + let secret = hex::decode(¬e_secret[0..32]).unwrap(); + let nullifier = hex::decode(¬e_secret[32..64]).unwrap(); + let (leaf, _) = setup_leaf_with_privates_raw_x5_4::( + curve, + secret.clone(), + nullifier.clone(), + src_chain_id, + ) + .unwrap(); + + let leaves = vec![leaf.clone()]; + let leaves_f = vec![Bn254Fr::from_le_bytes_mod_order(&leaf)]; + let index = 0; + + let params3 = setup_params_x5_3::(curve); + let params4 = setup_params_x5_4::(curve); + let anchor_setup = AnchorSetup30_2::new(params3, params4); + let (tree, _) = anchor_setup.setup_tree_and_path(&leaves_f, index).unwrap(); + let roots_f = [tree.root().inner(); M]; + let roots_raw = roots_f.map(|x| x.into_repr().to_bytes_le()); + + let mixer_proof_input = AnchorProofInput { + exponentiation: 5, + width: 4, + curve: WasmCurve::Bn254, + backend: Backend::Arkworks, + secrets: secret, + nullifier, + recipient: recipient_bytes, + relayer: relayer_bytes, + pk: pk_bytes, + refund: refund_value, + fee: fee_value, + chain_id: src_chain_id, + leaves, + leaf_index: index, + roots: roots_raw.to_vec(), + commitment: commitment_bytes, + }; + let js_proof_inputs = JsProofInput { inner: ProofInput::Anchor(mixer_proof_input) }; + let proof = generate_proof_js(js_proof_inputs).unwrap(); + + let root_elements = proof.roots.iter().map(|root| Element::from_bytes(&root)).collect(); + let nullifier_hash_element = Element::from_bytes(&proof.nullifier_hash); + let leaf_element = Element::from_bytes(&proof.leaf); + + (proof.proof, root_elements, nullifier_hash_element, leaf_element) + }, + Curve::Bls381 => { + unimplemented!() + }, + } +} + +/// Truncate and pad 256 bit slice in reverse +pub fn truncate_and_pad_reverse(t: &[u8]) -> Vec { + let mut truncated_bytes = t[12..].to_vec(); + truncated_bytes.extend_from_slice(&[0u8; 12]); + truncated_bytes +} diff --git a/pallets/xanchor/src/tests.rs b/pallets/xanchor/src/tests.rs index 12949c4fc..20fec3bfb 100644 --- a/pallets/xanchor/src/tests.rs +++ b/pallets/xanchor/src/tests.rs @@ -1,5 +1,5 @@ use super::{ - mock::{parachain::*, *}, + mock::{parachain::*, test_utils::*, *}, *, }; use ark_bn254::Fr as Bn254Fr; @@ -7,7 +7,7 @@ use arkworks_utils::utils::common::{setup_params_x5_3, setup_params_x5_4, Curve} use codec::Encode; use frame_benchmarking::account; use frame_support::{assert_err, assert_ok, traits::OnInitialize}; -use pallet_anchor::BalanceOf; +use pallet_anchor::{truncate_and_pad, BalanceOf}; use pallet_democracy::{AccountVote, Conviction, Vote}; use std::{convert::TryInto, path::Path}; use webb_primitives::utils::derive_resource_id; @@ -64,6 +64,46 @@ fn setup_environment(curve: Curve) -> Vec { } } +fn setup_environment_withdraw(curve: Curve) -> Vec { + for account_id in [ + account::("", 1, SEED), + account::("", 2, SEED), + account::("", 3, SEED), + account::("", 4, SEED), + account::("", 5, SEED), + account::("", 6, SEED), + ] { + assert_ok!(Balances::set_balance(Origin::root(), account_id, 100_000_000, 0)); + } + + match curve { + Curve::Bn254 => { + let params3 = setup_params_x5_3::(curve); + + // 1. Setup The Hasher Pallet. + assert_ok!(HasherPallet::force_set_parameters(Origin::root(), params3.to_bytes())); + // 2. Initialize MerkleTree pallet. + >::on_initialize(1); + // 3. Setup the VerifierPallet + // but to do so, we need to have a VerifyingKey + let pk_bytes = include_bytes!( + "../../../protocol-substrate-fixtures/fixed-anchor/bn254/x5/proving_key_uncompressed.bin" + ); + let vk_bytes = include_bytes!( + "../../../protocol-substrate-fixtures/fixed-anchor/bn254/x5/verifying_key.bin" + ); + + assert_ok!(VerifierPallet::force_set_parameters(Origin::root(), vk_bytes.to_vec())); + + // finally return the provingkey bytes + pk_bytes.to_vec() + }, + Curve::Bls381 => { + unimplemented!() + }, + } +} + // sanity check that XCM is working #[test] fn dmp() { @@ -797,3 +837,153 @@ fn should_fail_to_call_update_as_signed_account() { ); }); } + +#[test] +fn test_cross_chain_withdrawal() { + MockNet::reset(); + let mut para_a_tree_id = 0; + let mut para_b_tree_id = 0; + + let mut src_chain_id_b = 0; + let mut src_chain_id_a = 0; + + ParaA::execute_with(|| { + setup_environment_withdraw(Curve::Bn254); + let max_edges = 2; + let depth = TREE_DEPTH as u8; + let asset_id = 0; + assert_ok!(Anchor::create(Origin::root(), DEPOSIT_SIZE, max_edges, depth, asset_id)); + para_a_tree_id = MerkleTree::next_tree_id() - 1; + }); + + ParaB::execute_with(|| { + setup_environment_withdraw(Curve::Bn254); + let max_edges = 2; + let depth = TREE_DEPTH as u8; + let asset_id = 0; + assert_ok!(Anchor::create(Origin::root(), DEPOSIT_SIZE, max_edges, depth, asset_id)); + para_b_tree_id = MerkleTree::next_tree_id() - 1; + }); + + const SUBSTRATE_CHAIN_TYPE: [u8; 2] = [2, 0]; + + ParaA::execute_with(|| { + dbg!(para_a_tree_id); + dbg!(para_b_tree_id); + //let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_B)); + let converted_chain_id_bytes = compute_chain_id_type(1u32, SUBSTRATE_CHAIN_TYPE); + let r_id = derive_resource_id(converted_chain_id_bytes, ¶_a_tree_id.encode()); + src_chain_id_a = converted_chain_id_bytes; + assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_b_tree_id)); + }); + + ParaB::execute_with(|| { + //let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_A)); + let converted_chain_id_bytes = compute_chain_id_type(1u32, SUBSTRATE_CHAIN_TYPE); + let r_id = derive_resource_id(converted_chain_id_bytes, ¶_b_tree_id.encode()); + src_chain_id_b = converted_chain_id_bytes.clone(); + assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_a_tree_id)); + }); + + // now we do a deposit on one chain (ParaA) for example + // and check the edges on the other chain (ParaB). + let mut para_a_root = Element::from_bytes(&[0u8; 32]); + ParaA::execute_with(|| { + let account_id = parachain::AccountOne::get(); + let sender_account_id = account_id.clone(); + let leaf = Element::from_bytes(&[1u8; 32]); + // check the balance before the deposit. + let balance_before = Balances::free_balance(account_id.clone()); + // and we do the deposit + assert_ok!(Anchor::deposit_and_update_linked_anchors( + Origin::signed(sender_account_id.clone()), + para_a_tree_id, + leaf + )); + // now we check the balance after the deposit. + let balance_after = Balances::free_balance(account_id); + // the balance should be less now with `deposit_size` + assert_eq!(balance_after, balance_before - DEPOSIT_SIZE); + // now we need also to check if the state got updated. + let tree = MerkleTree::trees(para_a_tree_id).unwrap(); + //dbg!(tree); + assert_eq!(tree.leaf_count, 1); + para_a_root = tree.root; + + let curve = Curve::Bn254; + let pk_bytes = setup_environment_withdraw(curve); + //dbg!(&pk_bytes); + + // inputs + let tree_id = para_b_tree_id; + let src_chain_id = src_chain_id_b.clone(); //2199023257552; //compute_chain_id_type(0u32, [2, 0]); + dbg!(src_chain_id); + + let recipient_account_id = account::("", 2, SEED); + let relayer_account_id = account::("", 0, SEED); + let fee_value = 0; + let refund_value = 0; + + let recipient_bytes = truncate_and_pad(&recipient_account_id.encode()[..]); + let relayer_bytes = truncate_and_pad(&relayer_account_id.encode()[..]); + let commitment_bytes = vec![0u8; 32]; + let commitment_element = Element::from_bytes(&commitment_bytes); + + let (proof_bytes, mut root_elements, nullifier_hash_element, leaf_element) = + setup_zk_circuit( + curve, + recipient_bytes, + relayer_bytes, + commitment_bytes, + pk_bytes, + src_chain_id, + fee_value, + refund_value, + ); + + //let tree_root = MerkleTree::get_root(tree_id).unwrap(); + let tree_root: Element = para_a_root.clone(); + dbg!(&root_elements); + dbg!(¶_a_root); + //root_elements[0] = Element::from_bytes(&[0u8; 32]); + //root_elements[1] = Element::from_bytes(&[0u8; 32]); + // sanity check. + //assert_eq!(root_elements[0], tree_root); + + let balance_before = Balances::free_balance(recipient_account_id.clone()); + // fire the call. + assert_ok!(Anchor::withdraw( + Origin::signed(sender_account_id), + tree_id, + proof_bytes, + root_elements, + nullifier_hash_element, + recipient_account_id.clone(), + relayer_account_id, + fee_value.into(), + refund_value.into(), + commitment_element, + )); + // now we check the recipient balance again. + let balance_after = Balances::free_balance(recipient_account_id.clone()); + assert_eq!(balance_after, balance_before + DEPOSIT_SIZE); + // perfect + + /*crate::mock::assert_last_event::( + crate::Event::::Withdraw { who: recipient_account_id, amount: DEPOSIT_SIZE } + .into(), + );*/ + // Nice! + }); + + // ok now we go to ParaB and check the edges. + // we should expect that the edge for ParaA is there, and the merkle root equal + // to the one we got from ParaA. + ParaB::execute_with(|| { + let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_A)); + dbg!(converted_chain_id_bytes); + let edge = LinkableTree::edge_list(¶_b_tree_id, converted_chain_id_bytes); + assert_eq!(edge.root, para_a_root); + assert_eq!(edge.latest_leaf_index, 1); + }); +} From 7055dd81e0df6e016644ac4deab520c26a7d9297 Mon Sep 17 00:00:00 2001 From: Damilare Date: Wed, 16 Feb 2022 18:36:25 +0100 Subject: [PATCH 2/8] changes --- pallets/xanchor/src/tests.rs | 60 +++++++++++++----------------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/pallets/xanchor/src/tests.rs b/pallets/xanchor/src/tests.rs index 20fec3bfb..4519ee2f4 100644 --- a/pallets/xanchor/src/tests.rs +++ b/pallets/xanchor/src/tests.rs @@ -274,7 +274,7 @@ fn should_bridge_anchors_using_xcm() { }); ParaB::execute_with(|| { - setup_environment(Curve::Bn254); + //setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; let asset_id = 0; @@ -847,8 +847,13 @@ fn test_cross_chain_withdrawal() { let mut src_chain_id_b = 0; let mut src_chain_id_a = 0; + let mut pk_bytes = Vec::new(); + let mut sender_account_id = parachain::AccountOne::get(); + + let curve = Curve::Bn254; + ParaA::execute_with(|| { - setup_environment_withdraw(Curve::Bn254); + pk_bytes = setup_environment_withdraw(curve); let max_edges = 2; let depth = TREE_DEPTH as u8; let asset_id = 0; @@ -857,7 +862,6 @@ fn test_cross_chain_withdrawal() { }); ParaB::execute_with(|| { - setup_environment_withdraw(Curve::Bn254); let max_edges = 2; let depth = TREE_DEPTH as u8; let asset_id = 0; @@ -865,21 +869,17 @@ fn test_cross_chain_withdrawal() { para_b_tree_id = MerkleTree::next_tree_id() - 1; }); - const SUBSTRATE_CHAIN_TYPE: [u8; 2] = [2, 0]; - ParaA::execute_with(|| { dbg!(para_a_tree_id); dbg!(para_b_tree_id); - //let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_B)); - let converted_chain_id_bytes = compute_chain_id_type(1u32, SUBSTRATE_CHAIN_TYPE); + let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_B)); let r_id = derive_resource_id(converted_chain_id_bytes, ¶_a_tree_id.encode()); src_chain_id_a = converted_chain_id_bytes; assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_b_tree_id)); }); ParaB::execute_with(|| { - //let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_A)); - let converted_chain_id_bytes = compute_chain_id_type(1u32, SUBSTRATE_CHAIN_TYPE); + let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_A)); let r_id = derive_resource_id(converted_chain_id_bytes, ¶_b_tree_id.encode()); src_chain_id_b = converted_chain_id_bytes.clone(); assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_a_tree_id)); @@ -889,11 +889,9 @@ fn test_cross_chain_withdrawal() { // and check the edges on the other chain (ParaB). let mut para_a_root = Element::from_bytes(&[0u8; 32]); ParaA::execute_with(|| { - let account_id = parachain::AccountOne::get(); - let sender_account_id = account_id.clone(); let leaf = Element::from_bytes(&[1u8; 32]); // check the balance before the deposit. - let balance_before = Balances::free_balance(account_id.clone()); + let balance_before = Balances::free_balance(sender_account_id.clone()); // and we do the deposit assert_ok!(Anchor::deposit_and_update_linked_anchors( Origin::signed(sender_account_id.clone()), @@ -901,7 +899,7 @@ fn test_cross_chain_withdrawal() { leaf )); // now we check the balance after the deposit. - let balance_after = Balances::free_balance(account_id); + let balance_after = Balances::free_balance(sender_account_id.clone()); // the balance should be less now with `deposit_size` assert_eq!(balance_after, balance_before - DEPOSIT_SIZE); // now we need also to check if the state got updated. @@ -909,14 +907,18 @@ fn test_cross_chain_withdrawal() { //dbg!(tree); assert_eq!(tree.leaf_count, 1); para_a_root = tree.root; + }); + + ParaB::execute_with(|| { + let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_A)); + dbg!(converted_chain_id_bytes); + let edge = LinkableTree::edge_list(¶_b_tree_id, converted_chain_id_bytes); + assert_eq!(edge.root, para_a_root); + assert_eq!(edge.latest_leaf_index, 1); - let curve = Curve::Bn254; - let pk_bytes = setup_environment_withdraw(curve); //dbg!(&pk_bytes); - // inputs - let tree_id = para_b_tree_id; - let src_chain_id = src_chain_id_b.clone(); //2199023257552; //compute_chain_id_type(0u32, [2, 0]); + let src_chain_id = src_chain_id_a.clone(); dbg!(src_chain_id); let recipient_account_id = account::("", 2, SEED); @@ -948,13 +950,13 @@ fn test_cross_chain_withdrawal() { //root_elements[0] = Element::from_bytes(&[0u8; 32]); //root_elements[1] = Element::from_bytes(&[0u8; 32]); // sanity check. - //assert_eq!(root_elements[0], tree_root); + assert_eq!(root_elements[0], tree_root); let balance_before = Balances::free_balance(recipient_account_id.clone()); // fire the call. assert_ok!(Anchor::withdraw( Origin::signed(sender_account_id), - tree_id, + para_b_tree_id, proof_bytes, root_elements, nullifier_hash_element, @@ -967,23 +969,5 @@ fn test_cross_chain_withdrawal() { // now we check the recipient balance again. let balance_after = Balances::free_balance(recipient_account_id.clone()); assert_eq!(balance_after, balance_before + DEPOSIT_SIZE); - // perfect - - /*crate::mock::assert_last_event::( - crate::Event::::Withdraw { who: recipient_account_id, amount: DEPOSIT_SIZE } - .into(), - );*/ - // Nice! - }); - - // ok now we go to ParaB and check the edges. - // we should expect that the edge for ParaA is there, and the merkle root equal - // to the one we got from ParaA. - ParaB::execute_with(|| { - let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_A)); - dbg!(converted_chain_id_bytes); - let edge = LinkableTree::edge_list(¶_b_tree_id, converted_chain_id_bytes); - assert_eq!(edge.root, para_a_root); - assert_eq!(edge.latest_leaf_index, 1); }); } From 44ba634c2fb16389b093e8aa717acf169a0a9596 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 16 Feb 2022 13:21:19 -0500 Subject: [PATCH 3/8] Updates to the test, withdraw failing --- pallets/anchor/src/lib.rs | 2 - pallets/linkable-tree/src/lib.rs | 4 -- pallets/xanchor/src/lib.rs | 2 +- pallets/xanchor/src/tests.rs | 93 +++++++++++++++++--------------- 4 files changed, 50 insertions(+), 51 deletions(-) diff --git a/pallets/anchor/src/lib.rs b/pallets/anchor/src/lib.rs index 52d309e0a..1f98af0d7 100644 --- a/pallets/anchor/src/lib.rs +++ b/pallets/anchor/src/lib.rs @@ -180,8 +180,6 @@ pub mod pallet { pub enum Error { /// Invalid Merkle Roots InvalidMerkleRoots, - /// Unknown root - UnknownRoot, /// Invalid withdraw proof InvalidWithdrawProof, /// Mixer not found. diff --git a/pallets/linkable-tree/src/lib.rs b/pallets/linkable-tree/src/lib.rs index cecf28e56..86b1c4d51 100644 --- a/pallets/linkable-tree/src/lib.rs +++ b/pallets/linkable-tree/src/lib.rs @@ -392,10 +392,6 @@ impl, I: 'static> LinkableTreeInspector 1 { // Get edges and corresponding chain IDs for the anchor let edges = EdgeList::::iter_prefix(id).into_iter().collect::>(); - - println!("nighbor roots"); - println!("{:?}", edges); - // Check membership of provided historical neighbor roots for (i, (chain_id, _)) in edges.iter().enumerate() { Self::ensure_known_neighbor_root(id, *chain_id, roots[i + 1])?; diff --git a/pallets/xanchor/src/lib.rs b/pallets/xanchor/src/lib.rs index 9c35d81ee..415f7207a 100644 --- a/pallets/xanchor/src/lib.rs +++ b/pallets/xanchor/src/lib.rs @@ -736,7 +736,7 @@ pub fn para_id_to_chain_id, I: 'static>(para_id: ParaId) -> T::Chai .unwrap_or_default() } -pub fn chain_id_to_bytes, I: 'static>(chain_id: T::ChainId) -> T::ChainId { +pub fn compute_chain_id_with_internal_type, I: 'static>(chain_id: T::ChainId) -> T::ChainId { T::ChainId::try_from(compute_chain_id_type(chain_id, T::Anchor::get_chain_type())) .unwrap_or_default() } diff --git a/pallets/xanchor/src/tests.rs b/pallets/xanchor/src/tests.rs index 4519ee2f4..3e594321b 100644 --- a/pallets/xanchor/src/tests.rs +++ b/pallets/xanchor/src/tests.rs @@ -9,7 +9,7 @@ use frame_benchmarking::account; use frame_support::{assert_err, assert_ok, traits::OnInitialize}; use pallet_anchor::{truncate_and_pad, BalanceOf}; use pallet_democracy::{AccountVote, Conviction, Vote}; -use std::{convert::TryInto, path::Path}; +use webb_primitives::{merkle_tree::TreeInspector, linkable_tree::LinkableTreeInspector}; use webb_primitives::utils::derive_resource_id; use xcm_simulator::TestExt; @@ -283,14 +283,14 @@ fn should_bridge_anchors_using_xcm() { }); ParaA::execute_with(|| { - let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_B)); - let r_id = derive_resource_id(converted_chain_id_bytes, ¶_a_tree_id.encode()); + let converted_chain_id = compute_chain_id_with_internal_type::(u64::from(PARAID_B)); + let r_id = derive_resource_id(converted_chain_id, ¶_a_tree_id.encode()); assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_b_tree_id)); }); ParaB::execute_with(|| { - let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_A)); - let r_id = derive_resource_id(converted_chain_id_bytes, ¶_b_tree_id.encode()); + let converted_chain_id = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); + let r_id = derive_resource_id(converted_chain_id, ¶_b_tree_id.encode()); assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_a_tree_id)); }); @@ -322,7 +322,7 @@ fn should_bridge_anchors_using_xcm() { // we should expect that the edge for ParaA is there, and the merkle root equal // to the one we got from ParaA. ParaB::execute_with(|| { - let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_A)); + let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); dbg!(converted_chain_id_bytes); let edge = LinkableTree::edge_list(¶_b_tree_id, converted_chain_id_bytes); assert_eq!(edge.root, para_a_root); @@ -449,7 +449,7 @@ fn governance_system_works() { // create a link proposal, saying that we (parachain A) want to link the anchor // (local_tree_id) to the anchor (target_tree_id) located on Parachain B // (target_chain_id). - let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_B)); + let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_B)); let payload = LinkProposal { target_chain_id: converted_chain_id_bytes, target_tree_id: Some(para_b_tree_id), @@ -487,7 +487,7 @@ fn governance_system_works() { // now we do the on-chain proposal checking on chain B. ParaB::execute_with(|| { // we should see the anchor in the pending list. - let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_A)); + let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); dbg!(converted_chain_id_bytes); assert_eq!( XAnchor::pending_linked_anchors(converted_chain_id_bytes, para_b_tree_id), @@ -862,6 +862,7 @@ fn test_cross_chain_withdrawal() { }); ParaB::execute_with(|| { + setup_environment_withdraw(curve); let max_edges = 2; let depth = TREE_DEPTH as u8; let asset_id = 0; @@ -872,14 +873,14 @@ fn test_cross_chain_withdrawal() { ParaA::execute_with(|| { dbg!(para_a_tree_id); dbg!(para_b_tree_id); - let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_B)); + let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_B)); let r_id = derive_resource_id(converted_chain_id_bytes, ¶_a_tree_id.encode()); src_chain_id_a = converted_chain_id_bytes; assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_b_tree_id)); }); ParaB::execute_with(|| { - let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_A)); + let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); let r_id = derive_resource_id(converted_chain_id_bytes, ¶_b_tree_id.encode()); src_chain_id_b = converted_chain_id_bytes.clone(); assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_a_tree_id)); @@ -888,8 +889,34 @@ fn test_cross_chain_withdrawal() { // now we do a deposit on one chain (ParaA) for example // and check the edges on the other chain (ParaB). let mut para_a_root = Element::from_bytes(&[0u8; 32]); + + let recipient_account_id = account::("", 2, SEED); + let relayer_account_id = account::("", 0, SEED); + let fee_value = 0; + let refund_value = 0; + + let recipient_bytes = truncate_and_pad(&recipient_account_id.encode()[..]); + let relayer_bytes = truncate_and_pad(&relayer_account_id.encode()[..]); + let commitment_bytes = vec![0u8; 32]; + let commitment_element = Element::from_bytes(&commitment_bytes); + + let src_chain_id = src_chain_id_a.clone(); + dbg!(src_chain_id); + + let (proof_bytes, mut root_elements, nullifier_hash_element, leaf_element) = + setup_zk_circuit( + curve, + recipient_bytes, + relayer_bytes, + commitment_bytes, + pk_bytes, + src_chain_id, + fee_value, + refund_value, + ); + ParaA::execute_with(|| { - let leaf = Element::from_bytes(&[1u8; 32]); + let leaf = leaf_element; // check the balance before the deposit. let balance_before = Balances::free_balance(sender_account_id.clone()); // and we do the deposit @@ -910,47 +937,25 @@ fn test_cross_chain_withdrawal() { }); ParaB::execute_with(|| { - let converted_chain_id_bytes = chain_id_to_bytes::(u64::from(PARAID_A)); + let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); dbg!(converted_chain_id_bytes); let edge = LinkableTree::edge_list(¶_b_tree_id, converted_chain_id_bytes); assert_eq!(edge.root, para_a_root); assert_eq!(edge.latest_leaf_index, 1); //dbg!(&pk_bytes); + dbg!(¶_a_root); - let src_chain_id = src_chain_id_a.clone(); - dbg!(src_chain_id); - - let recipient_account_id = account::("", 2, SEED); - let relayer_account_id = account::("", 0, SEED); - let fee_value = 0; - let refund_value = 0; - - let recipient_bytes = truncate_and_pad(&recipient_account_id.encode()[..]); - let relayer_bytes = truncate_and_pad(&relayer_account_id.encode()[..]); - let commitment_bytes = vec![0u8; 32]; - let commitment_element = Element::from_bytes(&commitment_bytes); - - let (proof_bytes, mut root_elements, nullifier_hash_element, leaf_element) = - setup_zk_circuit( - curve, - recipient_bytes, - relayer_bytes, - commitment_bytes, - pk_bytes, - src_chain_id, - fee_value, - refund_value, - ); - - //let tree_root = MerkleTree::get_root(tree_id).unwrap(); - let tree_root: Element = para_a_root.clone(); + // Set the first element of `roots` set to be the merkle tree root on `ParaB`. + let tree_root = MerkleTree::get_root(para_b_tree_id).unwrap(); + root_elements[0] = tree_root; + + // Sanity check - the neighbor root should match `ParaA`'s merkle tree root. + assert_eq!(root_elements[1], para_a_root.clone()); dbg!(&root_elements); - dbg!(¶_a_root); - //root_elements[0] = Element::from_bytes(&[0u8; 32]); - //root_elements[1] = Element::from_bytes(&[0u8; 32]); - // sanity check. - assert_eq!(root_elements[0], tree_root); + + let neighbor_roots = >::get_neighbor_roots(para_b_tree_id); + dbg!(&neighbor_roots); let balance_before = Balances::free_balance(recipient_account_id.clone()); // fire the call. From 9e60020c0328017a0b5aa1a68cf7f928ad36abcf Mon Sep 17 00:00:00 2001 From: Damilare Date: Wed, 16 Feb 2022 19:44:29 +0100 Subject: [PATCH 4/8] remove print and dbg statements --- pallets/anchor/src/lib.rs | 4 -- pallets/mt/src/lib.rs | 2 - pallets/xanchor/src/lib.rs | 9 ++--- pallets/xanchor/src/tests.rs | 73 +++++++++++++++++++----------------- 4 files changed, 41 insertions(+), 47 deletions(-) diff --git a/pallets/anchor/src/lib.rs b/pallets/anchor/src/lib.rs index 1f98af0d7..435a5ed37 100644 --- a/pallets/anchor/src/lib.rs +++ b/pallets/anchor/src/lib.rs @@ -383,10 +383,6 @@ impl, I: 'static> AnchorInterface> for Pal bytes.extend_from_slice(&fee_bytes); bytes.extend_from_slice(&refund_bytes); bytes.extend_from_slice(&commitment.encode()); - println!("WITHDRAW PROOF bytes"); - println!("{:?}", &bytes); - println!("WITHDRAW PROOF proof_bytes"); - println!("{:?}", &proof_bytes); let result = >::Verifier::verify(&bytes, proof_bytes)?; ensure!(result, Error::::InvalidWithdrawProof); // withdraw or refresh depending on the refresh commitment value diff --git a/pallets/mt/src/lib.rs b/pallets/mt/src/lib.rs index 2ebfa862e..4b0b82b4e 100644 --- a/pallets/mt/src/lib.rs +++ b/pallets/mt/src/lib.rs @@ -453,8 +453,6 @@ impl, I: 'static> TreeInspector Result { ensure!(Trees::::contains_key(tree_id), Error::::TreeDoesntExist); - println!("{:?}", tree_id); - println!("{:?}", target_root); let mut temp: T::RootIndex = Zero::zero(); while temp < T::RootHistorySize::get() { let cached_root = CachedRoots::::get(tree_id, temp); diff --git a/pallets/xanchor/src/lib.rs b/pallets/xanchor/src/lib.rs index 415f7207a..8f9dbf2f4 100644 --- a/pallets/xanchor/src/lib.rs +++ b/pallets/xanchor/src/lib.rs @@ -682,21 +682,16 @@ impl, I: 'static> Pallet { .encode() .into(), }; - println!("{:?}", "updating edge"); - println!("{:?}", r_id); - println!("{:?}", other_para_id); let dest = (Parent, Parachain(other_para_id.into())); let result = T::XcmSender::send_xcm(dest, Xcm(vec![update_edge])); match result { Ok(()) => { - println!("{:?}", "acnchor updated"); Self::deposit_event(Event::RemoteAnchorEdgeUpdated { para_id: other_para_id, resource_id: r_id, }); }, Err(e) => { - println!("{:?}", "acnchor update failed"); Self::deposit_event(Event::RemoteAnchorEdgeUpdateFailed { para_id: other_para_id, resource_id: r_id, @@ -736,7 +731,9 @@ pub fn para_id_to_chain_id, I: 'static>(para_id: ParaId) -> T::Chai .unwrap_or_default() } -pub fn compute_chain_id_with_internal_type, I: 'static>(chain_id: T::ChainId) -> T::ChainId { +pub fn compute_chain_id_with_internal_type, I: 'static>( + chain_id: T::ChainId, +) -> T::ChainId { T::ChainId::try_from(compute_chain_id_type(chain_id, T::Anchor::get_chain_type())) .unwrap_or_default() } diff --git a/pallets/xanchor/src/tests.rs b/pallets/xanchor/src/tests.rs index 3e594321b..3b0e7355b 100644 --- a/pallets/xanchor/src/tests.rs +++ b/pallets/xanchor/src/tests.rs @@ -9,8 +9,9 @@ use frame_benchmarking::account; use frame_support::{assert_err, assert_ok, traits::OnInitialize}; use pallet_anchor::{truncate_and_pad, BalanceOf}; use pallet_democracy::{AccountVote, Conviction, Vote}; -use webb_primitives::{merkle_tree::TreeInspector, linkable_tree::LinkableTreeInspector}; -use webb_primitives::utils::derive_resource_id; +use webb_primitives::{ + linkable_tree::LinkableTreeInspector, merkle_tree::TreeInspector, utils::derive_resource_id, +}; use xcm_simulator::TestExt; const SEED: u32 = 0; @@ -283,13 +284,15 @@ fn should_bridge_anchors_using_xcm() { }); ParaA::execute_with(|| { - let converted_chain_id = compute_chain_id_with_internal_type::(u64::from(PARAID_B)); + let converted_chain_id = + compute_chain_id_with_internal_type::(u64::from(PARAID_B)); let r_id = derive_resource_id(converted_chain_id, ¶_a_tree_id.encode()); assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_b_tree_id)); }); ParaB::execute_with(|| { - let converted_chain_id = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); + let converted_chain_id = + compute_chain_id_with_internal_type::(u64::from(PARAID_A)); let r_id = derive_resource_id(converted_chain_id, ¶_b_tree_id.encode()); assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_a_tree_id)); }); @@ -322,7 +325,8 @@ fn should_bridge_anchors_using_xcm() { // we should expect that the edge for ParaA is there, and the merkle root equal // to the one we got from ParaA. ParaB::execute_with(|| { - let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); + let converted_chain_id_bytes = + compute_chain_id_with_internal_type::(u64::from(PARAID_A)); dbg!(converted_chain_id_bytes); let edge = LinkableTree::edge_list(¶_b_tree_id, converted_chain_id_bytes); assert_eq!(edge.root, para_a_root); @@ -449,7 +453,8 @@ fn governance_system_works() { // create a link proposal, saying that we (parachain A) want to link the anchor // (local_tree_id) to the anchor (target_tree_id) located on Parachain B // (target_chain_id). - let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_B)); + let converted_chain_id_bytes = + compute_chain_id_with_internal_type::(u64::from(PARAID_B)); let payload = LinkProposal { target_chain_id: converted_chain_id_bytes, target_tree_id: Some(para_b_tree_id), @@ -487,7 +492,8 @@ fn governance_system_works() { // now we do the on-chain proposal checking on chain B. ParaB::execute_with(|| { // we should see the anchor in the pending list. - let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); + let converted_chain_id_bytes = + compute_chain_id_with_internal_type::(u64::from(PARAID_A)); dbg!(converted_chain_id_bytes); assert_eq!( XAnchor::pending_linked_anchors(converted_chain_id_bytes, para_b_tree_id), @@ -844,8 +850,8 @@ fn test_cross_chain_withdrawal() { let mut para_a_tree_id = 0; let mut para_b_tree_id = 0; - let mut src_chain_id_b = 0; let mut src_chain_id_a = 0; + let mut src_chain_id_b = 0; let mut pk_bytes = Vec::new(); let mut sender_account_id = parachain::AccountOne::get(); @@ -873,21 +879,22 @@ fn test_cross_chain_withdrawal() { ParaA::execute_with(|| { dbg!(para_a_tree_id); dbg!(para_b_tree_id); - let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_B)); + let converted_chain_id_bytes = + compute_chain_id_with_internal_type::(u64::from(PARAID_B)); let r_id = derive_resource_id(converted_chain_id_bytes, ¶_a_tree_id.encode()); src_chain_id_a = converted_chain_id_bytes; assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_b_tree_id)); }); ParaB::execute_with(|| { - let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); + let converted_chain_id_bytes = + compute_chain_id_with_internal_type::(u64::from(PARAID_A)); let r_id = derive_resource_id(converted_chain_id_bytes, ¶_b_tree_id.encode()); src_chain_id_b = converted_chain_id_bytes.clone(); assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_a_tree_id)); }); - // now we do a deposit on one chain (ParaA) for example - // and check the edges on the other chain (ParaB). + // set up what is needed to perform deposit on paraA and withdrawal on paraB let mut para_a_root = Element::from_bytes(&[0u8; 32]); let recipient_account_id = account::("", 2, SEED); @@ -899,22 +906,21 @@ fn test_cross_chain_withdrawal() { let relayer_bytes = truncate_and_pad(&relayer_account_id.encode()[..]); let commitment_bytes = vec![0u8; 32]; let commitment_element = Element::from_bytes(&commitment_bytes); - + let src_chain_id = src_chain_id_a.clone(); - dbg!(src_chain_id); - - let (proof_bytes, mut root_elements, nullifier_hash_element, leaf_element) = - setup_zk_circuit( - curve, - recipient_bytes, - relayer_bytes, - commitment_bytes, - pk_bytes, - src_chain_id, - fee_value, - refund_value, - ); + let (proof_bytes, mut root_elements, nullifier_hash_element, leaf_element) = setup_zk_circuit( + curve, + recipient_bytes, + relayer_bytes, + commitment_bytes, + pk_bytes, + src_chain_id, + fee_value, + refund_value, + ); + + // Perform deposit on ParaA ParaA::execute_with(|| { let leaf = leaf_element; // check the balance before the deposit. @@ -931,31 +937,28 @@ fn test_cross_chain_withdrawal() { assert_eq!(balance_after, balance_before - DEPOSIT_SIZE); // now we need also to check if the state got updated. let tree = MerkleTree::trees(para_a_tree_id).unwrap(); - //dbg!(tree); assert_eq!(tree.leaf_count, 1); para_a_root = tree.root; }); + // Perform withdrawal on ParaB ParaB::execute_with(|| { - let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); + let converted_chain_id_bytes = + compute_chain_id_with_internal_type::(u64::from(PARAID_A)); dbg!(converted_chain_id_bytes); let edge = LinkableTree::edge_list(¶_b_tree_id, converted_chain_id_bytes); assert_eq!(edge.root, para_a_root); assert_eq!(edge.latest_leaf_index, 1); - //dbg!(&pk_bytes); - dbg!(¶_a_root); - // Set the first element of `roots` set to be the merkle tree root on `ParaB`. let tree_root = MerkleTree::get_root(para_b_tree_id).unwrap(); root_elements[0] = tree_root; - + // Sanity check - the neighbor root should match `ParaA`'s merkle tree root. assert_eq!(root_elements[1], para_a_root.clone()); - dbg!(&root_elements); - let neighbor_roots = >::get_neighbor_roots(para_b_tree_id); - dbg!(&neighbor_roots); + let neighbor_roots = + >::get_neighbor_roots(para_b_tree_id); let balance_before = Balances::free_balance(recipient_account_id.clone()); // fire the call. From e2155caee21b79eef19a0c0508bca9088ba2d269 Mon Sep 17 00:00:00 2001 From: Damilare Date: Fri, 18 Feb 2022 17:42:36 +0100 Subject: [PATCH 5/8] remove comment --- pallets/xanchor/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/xanchor/src/tests.rs b/pallets/xanchor/src/tests.rs index 3b0e7355b..6b70481cb 100644 --- a/pallets/xanchor/src/tests.rs +++ b/pallets/xanchor/src/tests.rs @@ -275,7 +275,7 @@ fn should_bridge_anchors_using_xcm() { }); ParaB::execute_with(|| { - //setup_environment(Curve::Bn254); + setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; let asset_id = 0; From 295abd6bb7852d23a8ed577cb16e514adc11ed6a Mon Sep 17 00:00:00 2001 From: Filip Lazovic Date: Mon, 21 Feb 2022 19:38:02 +0100 Subject: [PATCH 6/8] Updates --- pallets/xanchor/src/mock/test_utils.rs | 86 +++++++++++++++----------- pallets/xanchor/src/tests.rs | 49 +++++++-------- 2 files changed, 72 insertions(+), 63 deletions(-) diff --git a/pallets/xanchor/src/mock/test_utils.rs b/pallets/xanchor/src/mock/test_utils.rs index 457743d4e..6cc1c589b 100644 --- a/pallets/xanchor/src/mock/test_utils.rs +++ b/pallets/xanchor/src/mock/test_utils.rs @@ -27,56 +27,72 @@ pub const TREE_DEPTH: usize = 30; pub const M: usize = 2; pub type AnchorSetup30_2 = AnchorProverSetup; -pub fn setup_zk_circuit( - curve: Curve, - recipient_bytes: Vec, - relayer_bytes: Vec, - commitment_bytes: Vec, - pk_bytes: Vec, - src_chain_id: u64, - fee_value: u128, - refund_value: u128, -) -> (ProofBytes, RootsElement, NullifierHashElement, LeafElement) { +pub fn setup_leaf(curve: Curve, chain_id: u128) -> ( + Element, // Secret + Element, // Nullifier + Element, // Leaf + Element // Nullifier Hash +) { let rng = &mut ark_std::test_rng(); match curve { Curve::Bn254 => { let (secret, nullifier, leaf, nullifier_hash) = - setup_leaf_x5_4::(Curve::Bn254, src_chain_id.into(), rng).unwrap(); - let leaves = vec![leaf.clone()]; - let leaves_f = vec![Bn254Fr::from_le_bytes_mod_order(&leaf)]; - let index = 0; + setup_leaf_x5_4::(Curve::Bn254, chain_id.into(), rng).unwrap(); - let params3 = setup_params_x5_3::(curve); - let params4 = setup_params_x5_4::(curve); - let anchor_setup = AnchorSetup30_2::new(params3, params4); - let (tree, _) = anchor_setup.setup_tree_and_path(&leaves_f, index).unwrap(); - let roots_f = [tree.root().inner(); M]; - let roots_raw = roots_f.map(|x| x.into_repr().to_bytes_le()); + let secret_element = Element::from_bytes(&secret); + let nullifier_element = Element::from_bytes(&nullifier); + let nullifier_hash_element = Element::from_bytes(&nullifier_hash); + let leaf_element = Element::from_bytes(&leaf); + (secret_element, nullifier_element, leaf_element, nullifier_hash_element) + } + Curve::Bls381 => { + unimplemented!() + }, + } +} + +pub fn setup_zk_circuit( + curve: Curve, + chain_id: u128, + secret: Element, + nullifier: Element, + leaves: Vec, + index: u64, + roots: [Element; M], + recipient: Element, + relayer: Element, + commitment: Element, + fee: u128, + refund: u128, + pk_bytes: Vec, +) -> Vec { + let rng = &mut ark_std::test_rng(); + + match curve { + Curve::Bn254 => { + let leaves_bytes = leaves.iter().map(|x| x.to_vec()).collect(); + let roots_bytes = roots.map(|x| x.to_vec()); let (proof, ..) = setup_proof_x5_4::( curve, - src_chain_id.into(), - secret, - nullifier, - leaves, + chain_id.into(), + secret.to_vec(), + nullifier.to_vec(), + leaves_bytes, index, - roots_raw.clone(), - recipient_bytes, - relayer_bytes, - commitment_bytes, - fee_value, - refund_value, + roots_bytes, + recipient.to_vec(), + relayer.to_vec(), + commitment.to_vec(), + fee, + refund, pk_bytes, rng, ) .unwrap(); - let roots_element = roots_raw.map(|x| Element::from_bytes(&x)).to_vec(); - let nullifier_hash_element = Element::from_bytes(&nullifier_hash); - let leaf_element = Element::from_bytes(&leaf); - - (proof, roots_element, nullifier_hash_element, leaf_element) + proof }, Curve::Bls381 => { unimplemented!() diff --git a/pallets/xanchor/src/tests.rs b/pallets/xanchor/src/tests.rs index 6b70481cb..f6331f59f 100644 --- a/pallets/xanchor/src/tests.rs +++ b/pallets/xanchor/src/tests.rs @@ -854,7 +854,7 @@ fn test_cross_chain_withdrawal() { let mut src_chain_id_b = 0; let mut pk_bytes = Vec::new(); - let mut sender_account_id = parachain::AccountOne::get(); + let sender_account_id = parachain::AccountOne::get(); let curve = Curve::Bn254; @@ -894,35 +894,23 @@ fn test_cross_chain_withdrawal() { assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_a_tree_id)); }); - // set up what is needed to perform deposit on paraA and withdrawal on paraB - let mut para_a_root = Element::from_bytes(&[0u8; 32]); - let recipient_account_id = account::("", 2, SEED); let relayer_account_id = account::("", 0, SEED); let fee_value = 0; let refund_value = 0; - let recipient_bytes = truncate_and_pad(&recipient_account_id.encode()[..]); - let relayer_bytes = truncate_and_pad(&relayer_account_id.encode()[..]); - let commitment_bytes = vec![0u8; 32]; - let commitment_element = Element::from_bytes(&commitment_bytes); + let recipient_element = Element::from_bytes(&truncate_and_pad(&recipient_account_id.encode()[..])); + let relayer_element = Element::from_bytes(&truncate_and_pad(&relayer_account_id.encode()[..])); + let commitment_element = Element::from_bytes(&vec![0u8; 32]); let src_chain_id = src_chain_id_a.clone(); - let (proof_bytes, mut root_elements, nullifier_hash_element, leaf_element) = setup_zk_circuit( - curve, - recipient_bytes, - relayer_bytes, - commitment_bytes, - pk_bytes, - src_chain_id, - fee_value, - refund_value, - ); + let (secret, nullifier, leaf, nullifier_hash) = setup_leaf(Curve::Bn254, src_chain_id.into()); + + let mut root_elements = [Element::zero(); M]; // Perform deposit on ParaA ParaA::execute_with(|| { - let leaf = leaf_element; // check the balance before the deposit. let balance_before = Balances::free_balance(sender_account_id.clone()); // and we do the deposit @@ -938,7 +926,8 @@ fn test_cross_chain_withdrawal() { // now we need also to check if the state got updated. let tree = MerkleTree::trees(para_a_tree_id).unwrap(); assert_eq!(tree.leaf_count, 1); - para_a_root = tree.root; + // set up what is needed to perform deposit on paraA and withdrawal on paraB + root_elements[1] = tree.root; }); // Perform withdrawal on ParaB @@ -947,18 +936,22 @@ fn test_cross_chain_withdrawal() { compute_chain_id_with_internal_type::(u64::from(PARAID_A)); dbg!(converted_chain_id_bytes); let edge = LinkableTree::edge_list(¶_b_tree_id, converted_chain_id_bytes); - assert_eq!(edge.root, para_a_root); + // Sanity check - the neighbor root should match `ParaA`'s merkle tree root. + assert_eq!(edge.root, root_elements[1]); assert_eq!(edge.latest_leaf_index, 1); // Set the first element of `roots` set to be the merkle tree root on `ParaB`. let tree_root = MerkleTree::get_root(para_b_tree_id).unwrap(); root_elements[0] = tree_root; - // Sanity check - the neighbor root should match `ParaA`'s merkle tree root. - assert_eq!(root_elements[1], para_a_root.clone()); - - let neighbor_roots = - >::get_neighbor_roots(para_b_tree_id); + println!("chain_id: {:?}", src_chain_id.encode()); + println!("nullifier_hash: {:?}", nullifier_hash); + println!("roots: {:?}", root_elements); + println!("recipient_bytes: {:?}", recipient_element); + println!("relayer_bytes: {:?}", relayer_element); + println!("fee_bytes: {:?}", fee_value); + println!("refund_bytes: {:?}", refund_value); + let proof_bytes = setup_zk_circuit(Curve::Bn254, src_chain_id.into(), secret, nullifier, vec![leaf], 0, root_elements, recipient_element, relayer_element, commitment_element, fee_value, refund_value, pk_bytes); let balance_before = Balances::free_balance(recipient_account_id.clone()); // fire the call. @@ -966,8 +959,8 @@ fn test_cross_chain_withdrawal() { Origin::signed(sender_account_id), para_b_tree_id, proof_bytes, - root_elements, - nullifier_hash_element, + root_elements.to_vec(), + nullifier_hash, recipient_account_id.clone(), relayer_account_id, fee_value.into(), From 5144a7b0ac4e7df264bd101f1e0914b666d091a0 Mon Sep 17 00:00:00 2001 From: Filip Lazovic Date: Wed, 23 Feb 2022 13:00:36 +0100 Subject: [PATCH 7/8] Added two parachain configs --- pallets/anchor/src/lib.rs | 5 + pallets/xanchor/src/lib.rs | 6 +- pallets/xanchor/src/mock/mod.rs | 124 +-- pallets/xanchor/src/mock/parachain_a.rs | 746 ++++++++++++++++++ .../src/mock/{parachain.rs => parachain_b.rs} | 197 +++-- pallets/xanchor/src/mock/test_utils.rs | 2 +- pallets/xanchor/src/tests.rs | 202 ++--- 7 files changed, 1038 insertions(+), 244 deletions(-) create mode 100644 pallets/xanchor/src/mock/parachain_a.rs rename pallets/xanchor/src/mock/{parachain.rs => parachain_b.rs} (80%) diff --git a/pallets/anchor/src/lib.rs b/pallets/anchor/src/lib.rs index 435a5ed37..ef2f90a7a 100644 --- a/pallets/anchor/src/lib.rs +++ b/pallets/anchor/src/lib.rs @@ -373,6 +373,11 @@ impl, I: 'static> AnchorInterface> for Pal let refund_bytes = refund.using_encoded(element_encoder); let chain_id_type_bytes = T::LinkableTree::get_chain_id_type().using_encoded(element_encoder); + println!("on chain id: {:?}", T::LinkableTree::get_chain_id_type()); + // println!("on chain nullifier_hash: {:?}", nullifier_hash.encode()); + // println!("on chain roots: {:?}", roots.clone()); + // println!("on chain recipient: {:?}", recipient); + // println!("on chain relayer: {:?}", relayer); bytes.extend_from_slice(&chain_id_type_bytes); bytes.extend_from_slice(&nullifier_hash.encode()); for root in &roots { diff --git a/pallets/xanchor/src/lib.rs b/pallets/xanchor/src/lib.rs index 8f9dbf2f4..5a94d4840 100644 --- a/pallets/xanchor/src/lib.rs +++ b/pallets/xanchor/src/lib.rs @@ -568,9 +568,9 @@ impl, I: 'static> Pallet { ) -> DispatchResultWithPostInfo { // extract the resource id information let (tree_id, chain_id) = utils::parse_resource_id::(r_id); - println!("register_new_resource_id"); - println!("tree_id: {:?}", tree_id); - println!("chain_id: {:?}", chain_id); + // println!("register_new_resource_id"); + // println!("tree_id: {:?}", tree_id); + // println!("chain_id: {:?}", chain_id); // and we need to also ensure that the anchor exists ensure!(Self::anchor_exists(tree_id), Error::::AnchorNotFound); // and not already anchored/linked diff --git a/pallets/xanchor/src/mock/mod.rs b/pallets/xanchor/src/mock/mod.rs index 6e7ec1170..6bd0715bb 100644 --- a/pallets/xanchor/src/mock/mod.rs +++ b/pallets/xanchor/src/mock/mod.rs @@ -1,33 +1,78 @@ -pub mod parachain; +pub mod parachain_a; +pub mod parachain_b; pub mod relay_chain; pub(crate) mod test_utils; -use std::ops::Mul; - -use frame_support::traits::{GenesisBuild, OnInitialize}; +use codec::{Decode, Encode}; +pub use webb_primitives::{AccountId, types::ElementTrait}; +use frame_support::ord_parameter_types; use polkadot_parachain::primitives::Id as ParaId; use sp_runtime::traits::AccountIdConversion; use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain}; +use frame_support::{ Deserialize, Serialize }; + +ord_parameter_types! { + pub const AccountOne: AccountId = sp_runtime::AccountId32::new([1u8; 32]); + pub const AccountTwo: AccountId = sp_runtime::AccountId32::new([2u8; 32]); + pub const AccountThree: AccountId = sp_runtime::AccountId32::new([3u8; 32]); + pub const AccountFour: AccountId = sp_runtime::AccountId32::new([4u8; 32]); + pub const AccountFive: AccountId = sp_runtime::AccountId32::new([5u8; 32]); + pub const AccountSix: AccountId = sp_runtime::AccountId32::new([6u8; 32]); +} + +#[derive( + Debug, + Encode, + Decode, + Default, + Copy, + Clone, + PartialEq, + Eq, + scale_info::TypeInfo, + Serialize, + Deserialize, +)] +pub struct Element([u8; 32]); + +impl Element { + pub const fn zero() -> Self { + Element([0; 32]) + } +} + +impl ElementTrait for Element { + fn to_bytes(&self) -> &[u8] { + &self.0 + } + + fn from_bytes(input: &[u8]) -> Self { + let mut buf = [0u8; 32]; + buf.copy_from_slice(input); + Self(buf) + } +} + pub const INITIAL_BALANCE: u128 = 1_000_000_000; pub const PARAID_A: u32 = 2000; pub const PARAID_B: u32 = 3000; decl_test_parachain! { pub struct ParaA { - Runtime = parachain::Runtime, - XcmpMessageHandler = parachain::MsgQueue, - DmpMessageHandler = parachain::MsgQueue, - new_ext = para_ext(PARAID_A), + Runtime = parachain1::Runtime, + XcmpMessageHandler = parachain_a::MsgQueue, + DmpMessageHandler = parachain_a::MsgQueue, + new_ext = parachain_a::para_ext(PARAID_A), } } decl_test_parachain! { pub struct ParaB { - Runtime = parachain::Runtime, - XcmpMessageHandler = parachain::MsgQueue, - DmpMessageHandler = parachain::MsgQueue, - new_ext = para_ext(PARAID_B), + Runtime = parachain2::Runtime, + XcmpMessageHandler = parachain_b::MsgQueue, + DmpMessageHandler = parachain_b::MsgQueue, + new_ext = parachain_b::para_ext(PARAID_B), } } @@ -53,36 +98,6 @@ pub fn para_account_id(id: u32) -> relay_chain::AccountId { ParaId::from(id).into_account() } -pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { - use parachain::{MsgQueue, Runtime}; - - let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - - pallet_balances::GenesisConfig:: { - balances: vec![ - (parachain::AccountOne::get(), INITIAL_BALANCE.mul(1u128)), - (parachain::AccountTwo::get(), INITIAL_BALANCE.mul(2u128)), - (parachain::AccountThree::get(), INITIAL_BALANCE.mul(3u128)), - (parachain::AccountFour::get(), INITIAL_BALANCE.mul(4u128)), - (parachain::AccountFive::get(), INITIAL_BALANCE.mul(5u128)), - (parachain::AccountSix::get(), INITIAL_BALANCE.mul(6u128)), - (para_account_id(PARAID_A), INITIAL_BALANCE), - (para_account_id(PARAID_B), INITIAL_BALANCE), - ], - } - .assimilate_storage(&mut t) - .unwrap(); - pallet_democracy::GenesisConfig::::default() - .assimilate_storage(&mut t) - .unwrap(); - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| { - next_block(); - MsgQueue::set_para_id(para_id.into()); - }); - ext -} - pub fn relay_ext() -> sp_io::TestExternalities { use relay_chain::{Runtime, System}; @@ -90,12 +105,12 @@ pub fn relay_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { balances: vec![ - (parachain::AccountOne::get(), INITIAL_BALANCE), - (parachain::AccountTwo::get(), INITIAL_BALANCE), - (parachain::AccountThree::get(), INITIAL_BALANCE), - (parachain::AccountFour::get(), INITIAL_BALANCE), - (parachain::AccountFive::get(), INITIAL_BALANCE), - (parachain::AccountSix::get(), INITIAL_BALANCE), + (AccountOne::get(), INITIAL_BALANCE), + (AccountTwo::get(), INITIAL_BALANCE), + (AccountThree::get(), INITIAL_BALANCE), + (AccountFour::get(), INITIAL_BALANCE), + (AccountFive::get(), INITIAL_BALANCE), + (AccountSix::get(), INITIAL_BALANCE), (para_account_id(PARAID_A), INITIAL_BALANCE), (para_account_id(PARAID_B), INITIAL_BALANCE), ], @@ -109,16 +124,3 @@ pub fn relay_ext() -> sp_io::TestExternalities { } pub type RelayChainPalletXcm = pallet_xcm::Pallet; -pub type ParachainPalletXcm = pallet_xcm::Pallet; - -pub fn next_block() { - parachain::System::set_block_number(parachain::System::block_number() + 1); - parachain::Scheduler::on_initialize(parachain::System::block_number()); - parachain::Democracy::on_initialize(parachain::System::block_number()); -} - -pub fn fast_forward_to(n: u64) { - while parachain::System::block_number() < n { - next_block(); - } -} diff --git a/pallets/xanchor/src/mock/parachain_a.rs b/pallets/xanchor/src/mock/parachain_a.rs new file mode 100644 index 000000000..a54f7eacb --- /dev/null +++ b/pallets/xanchor/src/mock/parachain_a.rs @@ -0,0 +1,746 @@ +#![allow(clippy::zero_prefixed_literal)] +//! Parachain runtime mock. +use crate as pallet_xanchor; + +use codec::{Decode, Encode}; +use frame_support::{ + construct_runtime, + dispatch::DispatchResult, + parameter_types, + traits::{Everything, Nothing, SortedMembers}, + weights::{constants::WEIGHT_PER_SECOND, Weight}, + PalletId, +}; +use frame_support::traits::{OnInitialize, GenesisBuild}; +use frame_system::{pallet_prelude::OriginFor, EnsureRoot, EnsureSignedBy}; +use orml_currencies::BasicCurrencyAdapter; +use pallet_anchor::BalanceOf; +use sp_core::H256; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, Hash, IdentityLookup}, + Perbill, +}; +use sp_std::{convert::TryFrom, prelude::*}; +use webb_primitives::{Amount, BlockNumber, ChainId}; +use pallet_xcm::XcmPassthrough; +use polkadot_core_primitives::BlockNumber as RelayBlockNumber; +use polkadot_parachain::primitives::{ + DmpMessageHandler, Id as ParaId, Sibling, XcmpMessageFormat, XcmpMessageHandler, +}; +pub use webb_primitives::{ + hasher::{HasherModule, InstanceHasher}, + types::ElementTrait, + AccountId +}; +use std::ops::Mul; +use xcm::{latest::prelude::*, VersionedXcm}; +use xcm_builder::{ + AccountId32Aliases, AllowUnpaidExecutionFrom, CurrencyAdapter as XcmCurrencyAdapter, + EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, IsConcrete, LocationInverter, + NativeAsset, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, + SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, + SovereignSignedViaLocation, +}; +use pallet_democracy::{AccountVote, Conviction, Vote}; +use xcm_executor::{Config, XcmExecutor}; +use arkworks_utils::utils::common::{setup_params_x5_3, Curve}; +use ark_bn254::Fr as Bn254Fr; +use frame_support::assert_ok; +use frame_benchmarking::account; +use super::{AccountOne, AccountTwo, AccountThree, AccountFour, AccountFive, AccountSix, para_account_id, PARAID_A, INITIAL_BALANCE, Element}; + +pub type Balance = u128; +/// Type for storing the id of an asset. +pub type OrmlAssetId = u32; + +pub type ParachainPalletXcm = pallet_xcm::Pallet; + +pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![ + (AccountOne::get(), INITIAL_BALANCE.mul(1u128)), + (AccountTwo::get(), INITIAL_BALANCE.mul(2u128)), + (AccountThree::get(), INITIAL_BALANCE.mul(3u128)), + (AccountFour::get(), INITIAL_BALANCE.mul(4u128)), + (AccountFive::get(), INITIAL_BALANCE.mul(5u128)), + (AccountSix::get(), INITIAL_BALANCE.mul(6u128)), + (para_account_id(para_id), INITIAL_BALANCE), + ], + } + .assimilate_storage(&mut t) + .unwrap(); + pallet_democracy::GenesisConfig::::default() + .assimilate_storage(&mut t) + .unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| { + next_block(); + MsgQueue::set_para_id(para_id.into()); + }); + ext +} + +pub fn next_block() { + System::set_block_number(System::block_number() + 1); + Scheduler::on_initialize(System::block_number()); + Democracy::on_initialize(System::block_number()); +} + +pub fn fast_forward_to(n: u64) { + while System::block_number() < n { + next_block(); + } +} + +const SEED: u32 = 0; + +pub fn setup_environment(curve: Curve) -> Vec { + match curve { + Curve::Bn254 => { + let params3 = setup_params_x5_3::(curve); + + // 1. Setup The Hasher Pallet. + assert_ok!(HasherPallet::force_set_parameters(Origin::root(), params3.to_bytes())); + // 2. Initialize MerkleTree pallet. + >::on_initialize(1); + // 3. Setup the VerifierPallet + // but to do so, we need to have a VerifyingKey + let pk_bytes = include_bytes!( + "../../../../protocol-substrate-fixtures/fixed-anchor/bn254/x5/proving_key_uncompressed.bin" + ); + let vk_bytes = include_bytes!( + "../../../../protocol-substrate-fixtures/fixed-anchor/bn254/x5/verifying_key.bin" + ); + + assert_ok!(VerifierPallet::force_set_parameters(Origin::root(), vk_bytes.to_vec())); + + for account_id in [ + account::("", 1, SEED), + account::("", 2, SEED), + account::("", 3, SEED), + account::("", 4, SEED), + account::("", 5, SEED), + account::("", 6, SEED), + ] { + assert_ok!(Balances::set_balance(Origin::root(), account_id, 100_000_000, 0)); + } + + // finally return the provingkey bytes + pk_bytes.to_vec() + }, + Curve::Bls381 => { + unimplemented!() + }, + } +} + +pub fn setup_environment_withdraw(curve: Curve) -> Vec { + for account_id in [ + account::("", 1, SEED), + account::("", 2, SEED), + account::("", 3, SEED), + account::("", 4, SEED), + account::("", 5, SEED), + account::("", 6, SEED), + ] { + assert_ok!(Balances::set_balance(Origin::root(), account_id, 100_000_000, 0)); + } + + match curve { + Curve::Bn254 => { + let params3 = setup_params_x5_3::(curve); + + // 1. Setup The Hasher Pallet. + assert_ok!(HasherPallet::force_set_parameters(Origin::root(), params3.to_bytes())); + // 2. Initialize MerkleTree pallet. + >::on_initialize(1); + // 3. Setup the VerifierPallet + // but to do so, we need to have a VerifyingKey + let pk_bytes = include_bytes!( + "../../../../protocol-substrate-fixtures/fixed-anchor/bn254/x5/proving_key_uncompressed.bin" + ); + let vk_bytes = include_bytes!( + "../../../../protocol-substrate-fixtures/fixed-anchor/bn254/x5/verifying_key.bin" + ); + + assert_ok!(VerifierPallet::force_set_parameters(Origin::root(), vk_bytes.to_vec())); + + // finally return the provingkey bytes + pk_bytes.to_vec() + }, + Curve::Bls381 => { + unimplemented!() + }, + } +} + +// Governance System Tests +pub fn aye(who: AccountId) -> AccountVote> { + AccountVote::Standard { + vote: Vote { aye: true, conviction: Conviction::None }, + balance: Balances::free_balance(&who), + } +} + +pub fn nay(who: AccountId) -> AccountVote> { + AccountVote::Standard { + vote: Vote { aye: false, conviction: Conviction::None }, + balance: Balances::free_balance(&who), + } +} + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1_000_000); +} + +impl frame_system::Config for Runtime { + type AccountData = pallet_balances::AccountData; + type AccountId = AccountId; + type BaseCallFilter = Everything; + type BlockHashCount = BlockHashCount; + type BlockLength = (); + type BlockNumber = u64; + type BlockWeights = (); + type Call = Call; + type DbWeight = (); + type Event = Event; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type Header = Header; + type Index = u64; + type Lookup = IdentityLookup; + type MaxConsumers = frame_support::traits::ConstU32<16>; + type OnKilledAccount = (); + type OnNewAccount = (); + type OnSetCode = (); + type Origin = Origin; + type PalletInfo = PalletInfo; + type SS58Prefix = (); + type SystemWeightInfo = (); + type Version = (); +} + +parameter_types! { + pub ExistentialDeposit: Balance = 1; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type AccountStore = System; + type Balance = Balance; + type DustRemoval = (); + type Event = Event; + type ExistentialDeposit = ExistentialDeposit; + type MaxLocks = MaxLocks; + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); +} + +parameter_types! { + pub const ReservedXcmpWeight: Weight = WEIGHT_PER_SECOND / 4; + pub const ReservedDmpWeight: Weight = WEIGHT_PER_SECOND / 4; +} + +parameter_types! { + pub const KsmLocation: MultiLocation = MultiLocation::parent(); + pub const RelayNetwork: NetworkId = NetworkId::Kusama; + pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); + pub Ancestry: MultiLocation = Parachain(MsgQueue::parachain_id().into()).into(); +} + +pub type LocationToAccountId = ( + ParentIsPreset, + SiblingParachainConvertsVia, + SiblingParachainConvertsVia, + AccountId32Aliases, +); + +pub type XcmOriginToCallOrigin = ( + SovereignSignedViaLocation, + // Native converter for Relay-chain (Parent) location; will converts to a + // `Relay` origin when recognised. + RelayChainAsNative, + // Native converter for sibling Parachains; will convert to a `SiblingPara` + // origin when recognised. + SiblingParachainAsNative, + // Superuser converter for the Relay-chain (Parent) location. This will + // allow it to issue a transaction from the Root origin. + ParentAsSuperuser, + // Native signed account converter; this just converts an `AccountId32` + // origin into a normal `Origin::Signed` origin of the same 32-byte value. + SignedAccountId32AsNative, + // Xcm origins can be represented natively under the Xcm pallet's Xcm + // origin. + XcmPassthrough, +); + +parameter_types! { + pub const UnitWeightCost: Weight = 1; + pub KsmPerSecond: (AssetId, u128) = (Concrete(Parent.into()), 1); + pub const MaxInstructions: u32 = 100; +} + +pub type LocalAssetTransactor = + XcmCurrencyAdapter, LocationToAccountId, AccountId, ()>; + +pub type XcmRouter = super::ParachainXcmRouter; +pub type Barrier = AllowUnpaidExecutionFrom; + +pub struct XcmConfig; +impl Config for XcmConfig { + type Call = Call; + type XcmSender = XcmRouter; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = XcmOriginToCallOrigin; + type IsReserve = NativeAsset; + type IsTeleporter = (); + type LocationInverter = LocationInverter; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = FixedRateOfFungible; + type ResponseHandler = (); + type AssetTrap = (); + type AssetClaims = (); + type SubscriptionService = (); +} + +#[frame_support::pallet] +pub mod mock_msg_queue { + use super::*; + use frame_support::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Event: From> + IsType<::Event>; + type XcmExecutor: ExecuteXcm; + } + + #[pallet::call] + impl Pallet {} + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::storage] + #[pallet::getter(fn parachain_id)] + pub(super) type ParachainId = StorageValue<_, ParaId, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn received_dmp)] + /// A queue of received DMP messages + pub(super) type ReceivedDmp = StorageValue<_, Vec>, ValueQuery>; + + impl Get for Pallet { + fn get() -> ParaId { + Self::parachain_id() + } + } + + pub type MessageId = [u8; 32]; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + // XCMP + /// Some XCM was executed OK. + Success(Option), + /// Some XCM failed. + Fail(Option, XcmError), + /// Bad XCM version used. + BadVersion(Option), + /// Bad XCM format used. + BadFormat(Option), + + // DMP + /// Downward message is invalid XCM. + InvalidFormat(MessageId), + /// Downward message is unsupported version of XCM. + UnsupportedVersion(MessageId), + /// Downward message executed with the given outcome. + ExecutedDownward(MessageId, Outcome), + } + + impl Pallet { + pub fn set_para_id(para_id: ParaId) { + ParachainId::::put(para_id); + } + + fn handle_xcmp_message( + sender: ParaId, + _sent_at: RelayBlockNumber, + xcm: VersionedXcm, + max_weight: Weight, + ) -> Result { + let hash = Encode::using_encoded(&xcm, T::Hashing::hash); + let (result, event) = match Xcm::::try_from(xcm) { + Ok(xcm) => { + let location = (1, Parachain(sender.into())); + match T::XcmExecutor::execute_xcm(location, xcm, max_weight) { + Outcome::Error(e) => (Err(e.clone()), Event::Fail(Some(hash), e)), + Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))), + // As far as the caller is concerned, this was dispatched without error, so + // we just report the weight used. + Outcome::Incomplete(w, e) => (Ok(w), Event::Fail(Some(hash), e)), + } + }, + Err(()) => (Err(XcmError::UnhandledXcmVersion), Event::BadVersion(Some(hash))), + }; + Self::deposit_event(event); + result + } + } + + impl XcmpMessageHandler for Pallet { + fn handle_xcmp_messages<'a, I: Iterator>( + iter: I, + max_weight: Weight, + ) -> Weight { + for (sender, sent_at, data) in iter { + let mut data_ref = data; + let _ = XcmpMessageFormat::decode(&mut data_ref) + .expect("Simulator encodes with versioned xcm format; qed"); + + let mut remaining_fragments = &data_ref[..]; + while !remaining_fragments.is_empty() { + if let Ok(xcm) = VersionedXcm::::decode(&mut remaining_fragments) { + let _ = Self::handle_xcmp_message(sender, sent_at, xcm, max_weight); + } else { + debug_assert!(false, "Invalid incoming XCMP message data"); + } + } + } + max_weight + } + } + + impl DmpMessageHandler for Pallet { + fn handle_dmp_messages( + iter: impl Iterator)>, + limit: Weight, + ) -> Weight { + for (_i, (_sent_at, data)) in iter.enumerate() { + let id = sp_io::hashing::blake2_256(&data[..]); + let maybe_msg = + VersionedXcm::::decode(&mut &data[..]).map(Xcm::::try_from); + match maybe_msg { + Err(_) => { + Self::deposit_event(Event::InvalidFormat(id)); + }, + Ok(Err(())) => { + Self::deposit_event(Event::UnsupportedVersion(id)); + }, + Ok(Ok(x)) => { + let outcome = T::XcmExecutor::execute_xcm(Parent, x.clone(), limit); + >::append(x); + Self::deposit_event(Event::ExecutedDownward(id, outcome)); + }, + } + } + limit + } + } +} + +impl mock_msg_queue::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; +} + +pub type LocalOriginToLocation = SignedToAccountId32; + +impl pallet_xcm::Config for Runtime { + type Event = Event; + type SendXcmOrigin = EnsureXcmOrigin; + type XcmRouter = XcmRouter; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Nothing; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type LocationInverter = LocationInverter; + type Origin = Origin; + type Call = Call; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; +} + +impl cumulus_pallet_xcm::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; +} + +parameter_types! { + pub const ParameterDeposit: u64 = 1; + pub const StringLimit: u32 = 50; + pub const MetadataDepositBase: u64 = 1; + pub const MetadataDepositPerByte: u64 = 1; +} + +impl pallet_verifier::Config for Runtime { + type Event = Event; + type ForceOrigin = frame_system::EnsureRoot; + type Verifier = webb_primitives::verifying::ArkworksVerifierBn254; + type WeightInfo = (); +} + +impl pallet_hasher::Config for Runtime { + type Event = Event; + type ForceOrigin = frame_system::EnsureRoot; + type Hasher = webb_primitives::hashing::ArkworksPoseidonHasherBn254; + type WeightInfo = (); +} + +parameter_types! { + pub const TreeDeposit: u64 = 1; + pub const LeafDepositBase: u64 = 1; + pub const LeafDepositPerByte: u64 = 1; + pub const Two: u64 = 2; + pub const MaxTreeDepth: u8 = 30; + pub const RootHistorySize: u32 = 1096; + // 21663839004416932945382355908790599225266501822907911457504978515578255421292 + pub const DefaultZeroElement: Element = Element([ + 108, 175, 153, 072, 237, 133, 150, 036, + 226, 065, 231, 118, 015, 052, 027, 130, + 180, 093, 161, 235, 182, 053, 058, 052, + 243, 171, 172, 211, 096, 076, 229, 047, + ]); + pub const MockZeroElement: Element = Element([0; 32]); +} + +impl pallet_mt::Config for Runtime { + type Currency = Balances; + type DataDepositBase = LeafDepositBase; + type DataDepositPerByte = LeafDepositPerByte; + type DefaultZeroElement = MockZeroElement; + type Element = Element; + type Event = Event; + type ForceOrigin = frame_system::EnsureRoot; + type Hasher = HasherPallet; + type LeafIndex = u32; + type MaxTreeDepth = MaxTreeDepth; + type RootHistorySize = RootHistorySize; + type RootIndex = u32; + type StringLimit = StringLimit; + type TreeDeposit = TreeDeposit; + type TreeId = u32; + type Two = Two; + type WeightInfo = (); +} + +parameter_types! { + pub const NativeCurrencyId: OrmlAssetId = 0; + pub const RegistryStringLimit: u32 = 10; +} + +/// Tokens Configurations +impl orml_tokens::Config for Runtime { + type Amount = Amount; + type Balance = u128; + type CurrencyId = OrmlAssetId; + type DustRemovalWhitelist = Nothing; + type Event = Event; + type ExistentialDeposits = AssetRegistry; + type MaxLocks = (); + type OnDust = (); + type WeightInfo = (); +} + +impl orml_currencies::Config for Runtime { + type Event = Event; + type GetNativeCurrencyId = NativeCurrencyId; + type MultiCurrency = Tokens; + type NativeCurrency = BasicCurrencyAdapter; + type WeightInfo = (); +} + +impl pallet_asset_registry::Config for Runtime { + type AssetId = webb_primitives::AssetId; + type AssetNativeLocation = (); + type Balance = u128; + type Event = Event; + type NativeAssetId = NativeCurrencyId; + type RegistryOrigin = frame_system::EnsureRoot; + type StringLimit = RegistryStringLimit; + type WeightInfo = (); +} + +parameter_types! { + pub const HistoryLength: u32 = 30; + pub const AnchorPalletId: PalletId = PalletId(*b"py/anchr"); + // Substrate standalone chain ID type + pub const ChainType: [u8; 2] = [2, 0]; + // This identifier should equal the para ID. + // Note: this can cause issues if they do not match in production. + pub const ChainIdentifier: ChainId = PARAID_A as u64; +} + +impl pallet_linkable_tree::Config for Runtime { + type ChainId = ChainId; + type ChainType = ChainType; + type ChainIdentifier = ChainIdentifier; + type Event = Event; + type HistoryLength = HistoryLength; + type Tree = MerkleTree; + type WeightInfo = (); +} + +impl pallet_anchor::Config for Runtime { + type Currency = Currencies; + type Event = Event; + type LinkableTree = LinkableTree; + type NativeCurrencyId = NativeCurrencyId; + type PalletId = AnchorPalletId; + type PostDepositHook = XAnchor; + type Verifier = VerifierPallet; + type WeightInfo = (); +} + +impl pallet_xanchor::Config for Runtime { + type Anchor = Anchor; + type Call = Call; + type DemocracyGovernanceDelegate = Democracy; + type DemocracyOrigin = EnsureRoot; + type Event = Event; + type Origin = Origin; + type ParaId = MsgQueue; + type XcmSender = XcmRouter; +} + +impl pallet_preimage::Config for Runtime { + type BaseDeposit = (); + type ByteDeposit = (); + type Currency = (); + type Event = Event; + type ManagerOrigin = frame_system::EnsureRoot; + type MaxSize = frame_support::traits::ConstU32<1024>; + type WeightInfo = (); +} + +parameter_types! { + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * BlockWeights::get().max_block; + pub const NoPreimagePostponement: Option = Some(2); +} + +impl pallet_scheduler::Config for Runtime { + type Call = Call; + type Event = Event; + type MaxScheduledPerBlock = (); + type MaximumWeight = MaximumSchedulerWeight; + type NoPreimagePostponement = NoPreimagePostponement; + type Origin = Origin; + type OriginPrivilegeCmp = frame_support::traits::EqualPrivilegeOnly; + type PalletsOrigin = OriginCaller; + type PreimageProvider = Preimage; + type ScheduleOrigin = EnsureRoot; + type WeightInfo = (); +} + +parameter_types! { + pub const LaunchPeriod: u64 = 2; + pub const VotingPeriod: u64 = 2; + pub const FastTrackVotingPeriod: u64 = 2; + pub const MinimumDeposit: u64 = 1; + pub const EnactmentPeriod: u64 = 2; + pub const VoteLockingPeriod: u64 = 3; + pub const CooloffPeriod: u64 = 2; + pub const MaxVotes: u32 = 100; + pub const MaxProposals: u32 = 100; + pub static PreimageByteDeposit: u64 = 0; + pub static InstantAllowed: bool = false; +} + +pub struct OneToFive; +impl SortedMembers for OneToFive { + fn sorted_members() -> Vec { + (1..=5).into_iter().map(|x| sp_runtime::AccountId32::new([x; 32])).collect() + } + + #[cfg(feature = "runtime-benchmarks")] + fn add(_m: &AccountId) {} +} + +impl pallet_democracy::Config for Runtime { + type BlacklistOrigin = EnsureRoot; + type CancelProposalOrigin = EnsureRoot; + type CancellationOrigin = EnsureSignedBy; + type CooloffPeriod = CooloffPeriod; + type Currency = pallet_balances::Pallet; + type EnactmentPeriod = EnactmentPeriod; + type Event = Event; + type ExternalDefaultOrigin = EnsureSignedBy; + type ExternalMajorityOrigin = EnsureSignedBy; + type ExternalOrigin = EnsureSignedBy; + type FastTrackOrigin = EnsureSignedBy; + type FastTrackVotingPeriod = FastTrackVotingPeriod; + type InstantAllowed = InstantAllowed; + type InstantOrigin = EnsureSignedBy; + type LaunchPeriod = LaunchPeriod; + type MaxProposals = MaxProposals; + type MaxVotes = MaxVotes; + type MinimumDeposit = MinimumDeposit; + type OperationalPreimageOrigin = EnsureSignedBy; + type PalletsOrigin = OriginCaller; + type PreimageByteDeposit = PreimageByteDeposit; + type Proposal = Call; + type Scheduler = Scheduler; + type Slash = (); + type VetoOrigin = EnsureSignedBy; + type VoteLockingPeriod = VoteLockingPeriod; + type VotingPeriod = VotingPeriod; + type WeightInfo = (); +} + +impl crate::types::DemocracyGovernanceDelegate> + for Democracy +{ + fn propose( + origin: OriginFor, + proposal: Call, + value: BalanceOf, + ) -> DispatchResult { + let encoded_proposal = proposal.encode(); + let proposal_hash = BlakeTwo256::hash(&encoded_proposal[..]); + Democracy::note_preimage(origin.clone(), encoded_proposal)?; + Democracy::propose(origin, proposal_hash, value)?; + Ok(()) + } +} + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Democracy: pallet_democracy::{Pallet, Call, Storage, Config, Event}, + Preimage: pallet_preimage::{Pallet, Call, Storage, Event}, + Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, + MsgQueue: mock_msg_queue::{Pallet, Storage, Event}, + PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, + CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin}, + HasherPallet: pallet_hasher::{Pallet, Call, Storage, Event}, + VerifierPallet: pallet_verifier::{Pallet, Call, Storage, Event}, + MerkleTree: pallet_mt::{Pallet, Call, Storage, Event}, + Currencies: orml_currencies::{Pallet, Call, Event}, + Tokens: orml_tokens::{Pallet, Storage, Call, Event}, + AssetRegistry: pallet_asset_registry::{Pallet, Call, Storage, Event}, + Anchor: pallet_anchor::{Pallet, Call, Storage, Event}, + LinkableTree: pallet_linkable_tree::{Pallet, Call, Storage, Event}, + XAnchor: pallet_xanchor::{Pallet, Call, Storage, Event}, + } +); diff --git a/pallets/xanchor/src/mock/parachain.rs b/pallets/xanchor/src/mock/parachain_b.rs similarity index 80% rename from pallets/xanchor/src/mock/parachain.rs rename to pallets/xanchor/src/mock/parachain_b.rs index a85b66d20..4f75296da 100644 --- a/pallets/xanchor/src/mock/parachain.rs +++ b/pallets/xanchor/src/mock/parachain_b.rs @@ -6,11 +6,12 @@ use codec::{Decode, Encode}; use frame_support::{ construct_runtime, dispatch::DispatchResult, - ord_parameter_types, parameter_types, + parameter_types, traits::{Everything, Nothing, SortedMembers}, weights::{constants::WEIGHT_PER_SECOND, Weight}, - Deserialize, PalletId, Serialize, + PalletId, }; +use frame_support::traits::{OnInitialize, GenesisBuild}; use frame_system::{pallet_prelude::OriginFor, EnsureRoot, EnsureSignedBy}; use orml_currencies::BasicCurrencyAdapter; use pallet_anchor::BalanceOf; @@ -22,17 +23,18 @@ use sp_runtime::{ }; use sp_std::{convert::TryFrom, prelude::*}; use webb_primitives::{Amount, BlockNumber, ChainId}; - use pallet_xcm::XcmPassthrough; use polkadot_core_primitives::BlockNumber as RelayBlockNumber; use polkadot_parachain::primitives::{ DmpMessageHandler, Id as ParaId, Sibling, XcmpMessageFormat, XcmpMessageHandler, }; pub use webb_primitives::{ + runtime, hasher::{HasherModule, InstanceHasher}, types::ElementTrait, - AccountId, + AccountId }; +use std::ops::Mul; use xcm::{latest::prelude::*, VersionedXcm}; use xcm_builder::{ AccountId32Aliases, AllowUnpaidExecutionFrom, CurrencyAdapter as XcmCurrencyAdapter, @@ -41,13 +43,154 @@ use xcm_builder::{ SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, }; +use pallet_democracy::{AccountVote, Conviction, Vote}; +use arkworks_utils::utils::common::{setup_params_x5_3, Curve}; +use ark_bn254::Fr as Bn254Fr; +use frame_support::assert_ok; +use frame_benchmarking::account; use xcm_executor::{Config, XcmExecutor}; +use super::{AccountOne, AccountTwo, AccountThree, AccountFour, AccountFive, AccountSix, para_account_id, PARAID_B, INITIAL_BALANCE, Element}; pub type Balance = u128; - /// Type for storing the id of an asset. pub type OrmlAssetId = u32; +pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![ + (AccountOne::get(), INITIAL_BALANCE.mul(1u128)), + (AccountTwo::get(), INITIAL_BALANCE.mul(2u128)), + (AccountThree::get(), INITIAL_BALANCE.mul(3u128)), + (AccountFour::get(), INITIAL_BALANCE.mul(4u128)), + (AccountFive::get(), INITIAL_BALANCE.mul(5u128)), + (AccountSix::get(), INITIAL_BALANCE.mul(6u128)), + (para_account_id(para_id), INITIAL_BALANCE), + ], + } + .assimilate_storage(&mut t) + .unwrap(); + pallet_democracy::GenesisConfig::::default() + .assimilate_storage(&mut t) + .unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| { + next_block(); + MsgQueue::set_para_id(para_id.into()); + }); + ext +} + +pub fn next_block() { + System::set_block_number(System::block_number() + 1); + Scheduler::on_initialize(System::block_number()); + Democracy::on_initialize(System::block_number()); +} + +pub fn fast_forward_to(n: u64) { + while System::block_number() < n { + next_block(); + } +} + +const SEED: u32 = 0; + +pub fn setup_environment(curve: Curve) -> Vec { + match curve { + Curve::Bn254 => { + let params3 = setup_params_x5_3::(curve); + + // 1. Setup The Hasher Pallet. + assert_ok!(HasherPallet::force_set_parameters(Origin::root(), params3.to_bytes())); + // 2. Initialize MerkleTree pallet. + >::on_initialize(1); + // 3. Setup the VerifierPallet + // but to do so, we need to have a VerifyingKey + let pk_bytes = include_bytes!( + "../../../../protocol-substrate-fixtures/fixed-anchor/bn254/x5/proving_key_uncompressed.bin" + ); + let vk_bytes = include_bytes!( + "../../../../protocol-substrate-fixtures/fixed-anchor/bn254/x5/verifying_key.bin" + ); + + assert_ok!(VerifierPallet::force_set_parameters(Origin::root(), vk_bytes.to_vec())); + + for account_id in [ + account::("", 1, SEED), + account::("", 2, SEED), + account::("", 3, SEED), + account::("", 4, SEED), + account::("", 5, SEED), + account::("", 6, SEED), + ] { + assert_ok!(Balances::set_balance(Origin::root(), account_id, 100_000_000, 0)); + } + + // finally return the provingkey bytes + pk_bytes.to_vec() + }, + Curve::Bls381 => { + unimplemented!() + }, + } +} + +pub fn setup_environment_withdraw(curve: Curve) -> Vec { + for account_id in [ + account::("", 1, SEED), + account::("", 2, SEED), + account::("", 3, SEED), + account::("", 4, SEED), + account::("", 5, SEED), + account::("", 6, SEED), + ] { + assert_ok!(Balances::set_balance(Origin::root(), account_id, 100_000_000, 0)); + } + + match curve { + Curve::Bn254 => { + let params3 = setup_params_x5_3::(curve); + + // 1. Setup The Hasher Pallet. + assert_ok!(HasherPallet::force_set_parameters(Origin::root(), params3.to_bytes())); + // 2. Initialize MerkleTree pallet. + >::on_initialize(1); + // 3. Setup the VerifierPallet + // but to do so, we need to have a VerifyingKey + let pk_bytes = include_bytes!( + "../../../../protocol-substrate-fixtures/fixed-anchor/bn254/x5/proving_key_uncompressed.bin" + ); + let vk_bytes = include_bytes!( + "../../../../protocol-substrate-fixtures/fixed-anchor/bn254/x5/verifying_key.bin" + ); + + assert_ok!(VerifierPallet::force_set_parameters(Origin::root(), vk_bytes.to_vec())); + + // finally return the provingkey bytes + pk_bytes.to_vec() + }, + Curve::Bls381 => { + unimplemented!() + }, + } +} + +// Governance System Tests +pub fn aye(who: AccountId) -> AccountVote> { + AccountVote::Standard { + vote: Vote { aye: true, conviction: Conviction::None }, + balance: Balances::free_balance(&who), + } +} + +pub fn nay(who: AccountId) -> AccountVote> { + AccountVote::Standard { + vote: Vote { aye: false, conviction: Conviction::None }, + balance: Balances::free_balance(&who), + } +} + parameter_types! { pub const BlockHashCount: u64 = 250; pub BlockWeights: frame_system::limits::BlockWeights = @@ -373,39 +516,6 @@ parameter_types! { pub const MockZeroElement: Element = Element([0; 32]); } -#[derive( - Debug, - Encode, - Decode, - Default, - Copy, - Clone, - PartialEq, - Eq, - scale_info::TypeInfo, - Serialize, - Deserialize, -)] -pub struct Element([u8; 32]); - -impl Element { - pub const fn zero() -> Self { - Element([0; 32]) - } -} - -impl ElementTrait for Element { - fn to_bytes(&self) -> &[u8] { - &self.0 - } - - fn from_bytes(input: &[u8]) -> Self { - let mut buf = [0u8; 32]; - buf.copy_from_slice(input); - Self(buf) - } -} - impl pallet_mt::Config for Runtime { type Currency = Balances; type DataDepositBase = LeafDepositBase; @@ -470,7 +580,7 @@ parameter_types! { pub const ChainType: [u8; 2] = [2, 0]; // This identifier should equal the para ID. // Note: this can cause issues if they do not match in production. - pub const ChainIdentifier: ChainId = 0; + pub const ChainIdentifier: ChainId = PARAID_B as u64; } impl pallet_linkable_tree::Config for Runtime { @@ -548,15 +658,6 @@ parameter_types! { pub static InstantAllowed: bool = false; } -ord_parameter_types! { - pub const AccountOne: AccountId = sp_runtime::AccountId32::new([1u8; 32]); - pub const AccountTwo: AccountId = sp_runtime::AccountId32::new([2u8; 32]); - pub const AccountThree: AccountId = sp_runtime::AccountId32::new([3u8; 32]); - pub const AccountFour: AccountId = sp_runtime::AccountId32::new([4u8; 32]); - pub const AccountFive: AccountId = sp_runtime::AccountId32::new([5u8; 32]); - pub const AccountSix: AccountId = sp_runtime::AccountId32::new([6u8; 32]); -} - pub struct OneToFive; impl SortedMembers for OneToFive { fn sorted_members() -> Vec { diff --git a/pallets/xanchor/src/mock/test_utils.rs b/pallets/xanchor/src/mock/test_utils.rs index 6cc1c589b..08b65c159 100644 --- a/pallets/xanchor/src/mock/test_utils.rs +++ b/pallets/xanchor/src/mock/test_utils.rs @@ -7,7 +7,7 @@ use arkworks_circuits::setup::anchor::{ use arkworks_utils::utils::common::{setup_params_x5_3, setup_params_x5_4, Curve}; use webb_primitives::ElementTrait; -use crate::mock::parachain::Element; +use super::Element; use wasm_utils::{ note::JsNote, proof::{generate_proof_js, AnchorProofInput, JsProofInput, ProofInput, ProofInputBuilder}, diff --git a/pallets/xanchor/src/tests.rs b/pallets/xanchor/src/tests.rs index f6331f59f..42610f354 100644 --- a/pallets/xanchor/src/tests.rs +++ b/pallets/xanchor/src/tests.rs @@ -1,17 +1,15 @@ use super::{ - mock::{parachain::*, test_utils::*, *}, + mock::{parachain_a, parachain_b, test_utils::*, *}, *, }; -use ark_bn254::Fr as Bn254Fr; -use arkworks_utils::utils::common::{setup_params_x5_3, setup_params_x5_4, Curve}; + use codec::Encode; use frame_benchmarking::account; -use frame_support::{assert_err, assert_ok, traits::OnInitialize}; -use pallet_anchor::{truncate_and_pad, BalanceOf}; -use pallet_democracy::{AccountVote, Conviction, Vote}; -use webb_primitives::{ - linkable_tree::LinkableTreeInspector, merkle_tree::TreeInspector, utils::derive_resource_id, -}; +use frame_support::{assert_err, assert_ok}; +use pallet_anchor::truncate_and_pad; +use webb_primitives::utils::derive_resource_id; +use webb_primitives::merkle_tree::TreeInspector; +use arkworks_utils::utils::common::Curve; use xcm_simulator::TestExt; const SEED: u32 = 0; @@ -19,99 +17,13 @@ const TREE_DEPTH: usize = 30; const M: usize = 2; const DEPOSIT_SIZE: u128 = 10_000; -fn setup_environment(curve: Curve) -> Vec { - match curve { - Curve::Bn254 => { - let params3 = setup_params_x5_3::(curve); - - // 1. Setup The Hasher Pallet. - assert_ok!(HasherPallet::force_set_parameters(Origin::root(), params3.to_bytes())); - // 2. Initialize MerkleTree pallet. - >::on_initialize(1); - // 3. Setup the VerifierPallet - // but to do so, we need to have a VerifyingKey - let (pk_bytes, vk_bytes) = ( - std::fs::read( - "../../protocol-substrate-fixtures/fixed-anchor/bn254/x5/proving_key.bin", - ) - .expect("Unable to read file") - .to_vec(), - std::fs::read( - "../../protocol-substrate-fixtures/fixed-anchor/bn254/x5/verifying_key.bin", - ) - .expect("Unable to read file") - .to_vec(), - ); - - assert_ok!(VerifierPallet::force_set_parameters(Origin::root(), vk_bytes.to_vec())); - - for account_id in [ - account::("", 1, SEED), - account::("", 2, SEED), - account::("", 3, SEED), - account::("", 4, SEED), - account::("", 5, SEED), - account::("", 6, SEED), - ] { - assert_ok!(Balances::set_balance(Origin::root(), account_id, 100_000_000, 0)); - } - - // finally return the provingkey bytes - pk_bytes.to_vec() - }, - Curve::Bls381 => { - unimplemented!() - }, - } -} - -fn setup_environment_withdraw(curve: Curve) -> Vec { - for account_id in [ - account::("", 1, SEED), - account::("", 2, SEED), - account::("", 3, SEED), - account::("", 4, SEED), - account::("", 5, SEED), - account::("", 6, SEED), - ] { - assert_ok!(Balances::set_balance(Origin::root(), account_id, 100_000_000, 0)); - } - - match curve { - Curve::Bn254 => { - let params3 = setup_params_x5_3::(curve); - - // 1. Setup The Hasher Pallet. - assert_ok!(HasherPallet::force_set_parameters(Origin::root(), params3.to_bytes())); - // 2. Initialize MerkleTree pallet. - >::on_initialize(1); - // 3. Setup the VerifierPallet - // but to do so, we need to have a VerifyingKey - let pk_bytes = include_bytes!( - "../../../protocol-substrate-fixtures/fixed-anchor/bn254/x5/proving_key_uncompressed.bin" - ); - let vk_bytes = include_bytes!( - "../../../protocol-substrate-fixtures/fixed-anchor/bn254/x5/verifying_key.bin" - ); - - assert_ok!(VerifierPallet::force_set_parameters(Origin::root(), vk_bytes.to_vec())); - - // finally return the provingkey bytes - pk_bytes.to_vec() - }, - Curve::Bls381 => { - unimplemented!() - }, - } -} - // sanity check that XCM is working #[test] fn dmp() { MockNet::reset(); let remark = - parachain::Call::System(frame_system::Call::::remark_with_event { + parachain_a::Call::System(frame_system::Call::::remark_with_event { remark: vec![1, 2, 3], }); Relay::execute_with(|| { @@ -127,7 +39,7 @@ fn dmp() { }); ParaA::execute_with(|| { - use parachain::{Event, System}; + use parachain_a::{Event, System}; assert!(System::events() .iter() .any(|r| matches!(r.event, Event::System(frame_system::Event::Remarked { .. })))); @@ -143,7 +55,7 @@ fn ump() { remark: vec![1, 2, 3], }); ParaA::execute_with(|| { - assert_ok!(ParachainPalletXcm::send_xcm( + assert_ok!(parachain_a::ParachainPalletXcm::send_xcm( Here, Parent, Xcm(vec![Transact { @@ -167,11 +79,11 @@ fn xcmp() { MockNet::reset(); let remark = - parachain::Call::System(frame_system::Call::::remark_with_event { + parachain_a::Call::System(frame_system::Call::::remark_with_event { remark: vec![1, 2, 3], }); ParaA::execute_with(|| { - assert_ok!(ParachainPalletXcm::send_xcm( + assert_ok!(parachain_a::ParachainPalletXcm::send_xcm( Here, (Parent, Parachain(PARAID_B.into())), Xcm(vec![Transact { @@ -183,7 +95,7 @@ fn xcmp() { }); ParaB::execute_with(|| { - use parachain::{Event, System}; + use parachain_b::{Event, System}; assert!(System::events() .iter() .any(|r| matches!(r.event, Event::System(frame_system::Event::Remarked { .. })))); @@ -197,6 +109,7 @@ fn should_link_two_anchors() { let mut para_b_tree_id = 0; ParaA::execute_with(|| { + use parachain_a::{setup_environment, Anchor, Origin, MerkleTree}; setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; @@ -206,6 +119,7 @@ fn should_link_two_anchors() { }); ParaB::execute_with(|| { + use parachain_b::{setup_environment, Anchor, Origin, MerkleTree}; setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; @@ -218,6 +132,7 @@ fn should_link_two_anchors() { // it will try to link the para_a_tree_id to para_b_tree_id // we tell ParaA to link the `para_a_tree_id` to `para_b_tree_id` on the ParaB. ParaA::execute_with(|| { + use parachain_a::{XAnchor, Origin}; // the resource id reads as following // we need to link para_a_tree_id to another anchor defined on ParaB let r_id = derive_resource_id(PARAID_B.into(), ¶_a_tree_id.encode()); @@ -228,6 +143,7 @@ fn should_link_two_anchors() { // Here, the same as above, but the only difference is that // the caller is one of the Parachain A operators. ParaB::execute_with(|| { + use parachain_b::{XAnchor, Origin}; // we need to link para_b_tree_id to another anchor defined on ParaA let r_id = derive_resource_id(PARAID_A.into(), ¶_b_tree_id.encode()); // then, when we are sending the call we tell it which tree we are going to link @@ -237,7 +153,8 @@ fn should_link_two_anchors() { // now we assume both of them are linked, let's check that. ParaA::execute_with(|| { - let exists = crate::LinkedAnchors::::iter().any( + use parachain_a::Runtime; + let exists = crate::LinkedAnchors::::iter().any( |(chain_id, tree_id, target_tree_id)| { chain_id == u64::from(PARAID_B) && tree_id == para_a_tree_id && @@ -248,7 +165,8 @@ fn should_link_two_anchors() { }); ParaB::execute_with(|| { - let exists = crate::LinkedAnchors::::iter().any( + use parachain_b::Runtime; + let exists = crate::LinkedAnchors::::iter().any( |(chain_id, tree_id, target_tree_id)| { chain_id == u64::from(PARAID_A) && tree_id == para_b_tree_id && @@ -266,6 +184,7 @@ fn should_bridge_anchors_using_xcm() { let mut para_b_tree_id = 0; ParaA::execute_with(|| { + use parachain_a::{setup_environment, Anchor, Origin, MerkleTree}; setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; @@ -275,6 +194,7 @@ fn should_bridge_anchors_using_xcm() { }); ParaB::execute_with(|| { + use parachain_b::{setup_environment, Anchor, Origin, MerkleTree}; setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; @@ -284,6 +204,7 @@ fn should_bridge_anchors_using_xcm() { }); ParaA::execute_with(|| { + use parachain_a::{Runtime, XAnchor, Origin}; let converted_chain_id = compute_chain_id_with_internal_type::(u64::from(PARAID_B)); let r_id = derive_resource_id(converted_chain_id, ¶_a_tree_id.encode()); @@ -291,6 +212,7 @@ fn should_bridge_anchors_using_xcm() { }); ParaB::execute_with(|| { + use parachain_b::{Runtime, XAnchor, Origin}; let converted_chain_id = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); let r_id = derive_resource_id(converted_chain_id, ¶_b_tree_id.encode()); @@ -301,7 +223,8 @@ fn should_bridge_anchors_using_xcm() { // and check the edges on the other chain (ParaB). let mut para_a_root = Element::from_bytes(&[0u8; 32]); ParaA::execute_with(|| { - let account_id = parachain::AccountOne::get(); + use parachain_a::{Anchor, Origin, Balances, MerkleTree}; + let account_id = AccountOne::get(); let leaf = Element::from_bytes(&[1u8; 32]); // check the balance before the deposit. let balance_before = Balances::free_balance(account_id.clone()); @@ -325,6 +248,7 @@ fn should_bridge_anchors_using_xcm() { // we should expect that the edge for ParaA is there, and the merkle root equal // to the one we got from ParaA. ParaB::execute_with(|| { + use parachain_b::{Runtime, LinkableTree}; let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); dbg!(converted_chain_id_bytes); @@ -340,12 +264,13 @@ fn should_fail_to_register_resource_id_if_not_the_democracy() { MockNet::reset(); // it should fail to register a resource id if not the current maintainer. ParaA::execute_with(|| { + use parachain_a::{MerkleTree, XAnchor, Origin}; let tree_id = MerkleTree::next_tree_id(); let r_id = derive_resource_id(PARAID_B.into(), &tree_id.encode()); let target_tree_id = 1; assert_err!( XAnchor::register_resource_id( - Origin::signed(parachain::AccountTwo::get()), + Origin::signed(AccountTwo::get()), r_id, target_tree_id ), @@ -359,13 +284,14 @@ fn should_fail_to_register_resource_id_when_anchor_does_not_exist() { MockNet::reset(); // it should fail to register the resource id if the anchor does not exist. ParaA::execute_with(|| { + use parachain_a::{MerkleTree, XAnchor, Origin, Runtime}; // anchor/tree does not exist. let tree_id = MerkleTree::next_tree_id(); let r_id = derive_resource_id(PARAID_B.into(), &tree_id.encode()); let target_tree_id = 1; assert_err!( XAnchor::register_resource_id(Origin::root(), r_id, target_tree_id), - crate::Error::::AnchorNotFound, + crate::Error::::AnchorNotFound, ); }); } @@ -375,6 +301,7 @@ fn should_fail_to_link_anchor_if_it_is_already_anchored() { // it should fail if the resource id is already anchored. MockNet::reset(); ParaA::execute_with(|| { + use parachain_a::{setup_environment, Runtime, Anchor, MerkleTree, XAnchor, Origin}; // first we create the anchor setup_environment(Curve::Bn254); let max_edges = M as _; @@ -389,7 +316,7 @@ fn should_fail_to_link_anchor_if_it_is_already_anchored() { // now we try to link the anchor again, should error. assert_err!( XAnchor::register_resource_id(Origin::root(), r_id, target_tree_id), - crate::Error::::ResourceIsAlreadyAnchored + crate::Error::::ResourceIsAlreadyAnchored ); }); } @@ -400,37 +327,24 @@ fn ensure_that_the_only_way_to_update_edges_is_from_another_parachain() { // from another parachain. MockNet::reset(); ParaA::execute_with(|| { + use parachain_a::{MerkleTree, XAnchor, Origin}; // try to update the edges, from a normal account! // it should fail. let tree_id = MerkleTree::next_tree_id(); let r_id = derive_resource_id(PARAID_B.into(), &tree_id.encode()); assert_err!( - XAnchor::update(Origin::signed(parachain::AccountTwo::get()), r_id, Default::default()), + XAnchor::update(Origin::signed(AccountTwo::get()), r_id, Default::default()), frame_support::error::BadOrigin, ); }); } -// Governance System Tests -fn aye(who: AccountId) -> AccountVote> { - AccountVote::Standard { - vote: Vote { aye: true, conviction: Conviction::None }, - balance: Balances::free_balance(&who), - } -} - -fn nay(who: AccountId) -> AccountVote> { - AccountVote::Standard { - vote: Vote { aye: false, conviction: Conviction::None }, - balance: Balances::free_balance(&who), - } -} - #[test] fn governance_system_works() { MockNet::reset(); // create an anchor on parachain A. let para_a_tree_id = ParaA::execute_with(|| { + use parachain_a::{setup_environment, MerkleTree, Anchor, Origin}; setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; @@ -440,6 +354,7 @@ fn governance_system_works() { }); // Also, Create an anchor on parachain B. let para_b_tree_id = ParaB::execute_with(|| { + use parachain_b::{setup_environment, MerkleTree, Anchor, Origin}; setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; @@ -450,6 +365,7 @@ fn governance_system_works() { // next, we start doing the linking process through the governance system. ParaA::execute_with(|| { + use parachain_a::{fast_forward_to, aye, Democracy, Runtime, XAnchor, Origin}; // create a link proposal, saying that we (parachain A) want to link the anchor // (local_tree_id) to the anchor (target_tree_id) located on Parachain B // (target_chain_id). @@ -491,6 +407,7 @@ fn governance_system_works() { // now we do the on-chain proposal checking on chain B. ParaB::execute_with(|| { + use parachain_b::{fast_forward_to, aye, Democracy, Runtime, XAnchor, Origin}; // we should see the anchor in the pending list. let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); @@ -503,6 +420,7 @@ fn governance_system_works() { fast_forward_to(2); // now we need to vote on the proposal. let referendum_index = Democracy::referendum_count() - 1; + println!("{:?}", referendum_index); assert_ok!(Democracy::vote( Origin::signed(AccountTwo::get()), referendum_index, @@ -523,6 +441,7 @@ fn governance_system_works() { // on chain A we should find them linked too. ParaA::execute_with(|| { + use parachain_a::XAnchor; assert_eq!(XAnchor::pending_linked_anchors(u64::from(PARAID_B), para_a_tree_id), None); assert_eq!(XAnchor::linked_anchors(u64::from(PARAID_B), para_a_tree_id), para_b_tree_id); }); @@ -537,6 +456,7 @@ fn should_fail_to_create_proposal_if_the_anchor_does_not_exist() { MockNet::reset(); // creating a proposal for a non-existing anchor. ParaA::execute_with(|| { + use parachain_a::{XAnchor, MerkleTree, Runtime, Origin}; let payload = LinkProposal { target_chain_id: PARAID_B.into(), target_tree_id: Some(MerkleTree::next_tree_id()), @@ -555,6 +475,7 @@ fn should_fail_to_create_proposal_for_already_linked_anchors() { MockNet::reset(); // create an anchor on parachain A. let para_a_tree_id = ParaA::execute_with(|| { + use parachain_a::{setup_environment, Anchor, MerkleTree, Origin}; setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; @@ -564,6 +485,7 @@ fn should_fail_to_create_proposal_for_already_linked_anchors() { }); // create an anchor on parachain B. let para_b_tree_id = ParaB::execute_with(|| { + use parachain_b::{setup_environment, Anchor, MerkleTree, Origin}; setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; @@ -574,6 +496,7 @@ fn should_fail_to_create_proposal_for_already_linked_anchors() { // force link them. ParaA::execute_with(|| { + use parachain_a::{XAnchor, Origin}; let r_id = derive_resource_id(PARAID_B.into(), ¶_a_tree_id.encode()); assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_b_tree_id)); }); @@ -581,6 +504,7 @@ fn should_fail_to_create_proposal_for_already_linked_anchors() { // now try create a proposal on chain A, it should fail since it is already // linked. ParaA::execute_with(|| { + use parachain_a::{XAnchor, Runtime, Origin}; let payload = LinkProposal { target_chain_id: PARAID_B.into(), target_tree_id: Some(para_b_tree_id), @@ -599,6 +523,7 @@ fn should_fail_to_create_proposal_for_already_pending_linking() { MockNet::reset(); // create an anchor on parachain A. let para_a_tree_id = ParaA::execute_with(|| { + use parachain_a::{setup_environment, Anchor, MerkleTree, Origin}; setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; @@ -609,6 +534,7 @@ fn should_fail_to_create_proposal_for_already_pending_linking() { // create an anchor on parachain B. let para_b_tree_id = ParaB::execute_with(|| { + use parachain_b::{setup_environment, Anchor, MerkleTree, Origin}; setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; @@ -619,6 +545,7 @@ fn should_fail_to_create_proposal_for_already_pending_linking() { // create a proposal on chain A. ParaA::execute_with(|| { + use parachain_a::{XAnchor, Origin}; let payload = LinkProposal { target_chain_id: PARAID_B.into(), target_tree_id: Some(para_b_tree_id), @@ -635,6 +562,7 @@ fn should_fail_to_create_proposal_for_already_pending_linking() { // now try create a new proposal on chain A with different Account it should // fail. ParaA::execute_with(|| { + use parachain_a::{XAnchor, Origin, Runtime}; let payload = LinkProposal { target_chain_id: PARAID_B.into(), target_tree_id: Some(para_b_tree_id), @@ -655,6 +583,7 @@ fn should_fail_to_call_send_link_anchor_message_as_signed_account() { // calling send_link_anchor_message as signed account should fail. // on parachain A. ParaA::execute_with(|| { + use parachain_a::{XAnchor, MerkleTree, Origin}; let payload = LinkProposal { target_chain_id: PARAID_B.into(), target_tree_id: Some(MerkleTree::next_tree_id()), @@ -675,6 +604,7 @@ fn should_fail_to_call_save_link_proposal_as_signed_account() { // calling save_link_proposal as signed account should fail. // on parachain A. ParaA::execute_with(|| { + use parachain_a::{XAnchor, MerkleTree, Origin}; let payload = LinkProposal { target_chain_id: PARAID_B.into(), target_tree_id: Some(MerkleTree::next_tree_id()), @@ -693,6 +623,7 @@ fn should_fail_to_save_link_proposal_on_already_linked_anchors() { MockNet::reset(); // create an anchor on parachain A. let para_a_tree_id = ParaA::execute_with(|| { + use parachain_a::{setup_environment, Anchor, MerkleTree, Origin}; setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; @@ -703,6 +634,7 @@ fn should_fail_to_save_link_proposal_on_already_linked_anchors() { // create an anchor on parachain B. let para_b_tree_id = ParaB::execute_with(|| { + use parachain_b::{setup_environment, Anchor, MerkleTree, Origin}; setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; @@ -713,6 +645,7 @@ fn should_fail_to_save_link_proposal_on_already_linked_anchors() { // force link them. ParaA::execute_with(|| { + use parachain_a::{XAnchor, Origin}; let r_id = derive_resource_id(PARAID_B.into(), ¶_a_tree_id.encode()); println!("r_id: {:?}", r_id); assert_ok!(XAnchor::force_register_resource_id(Origin::root(), r_id, para_b_tree_id)); @@ -720,6 +653,7 @@ fn should_fail_to_save_link_proposal_on_already_linked_anchors() { // now creating a proposal on chain A should fail since it is already linked. ParaA::execute_with(|| { + use parachain_a::{XAnchor, Runtime, Origin}; let payload = LinkProposal { target_chain_id: PARAID_B.into(), target_tree_id: Some(para_b_tree_id), @@ -740,6 +674,7 @@ fn should_fail_to_call_handle_link_anchor_message_without_anchor_being_pending() MockNet::reset(); // create an anchor on parachain A. let para_a_tree_id = ParaA::execute_with(|| { + use parachain_a::{setup_environment, Anchor, MerkleTree, Origin}; setup_environment(Curve::Bn254); let max_edges = M as _; let depth = TREE_DEPTH as u8; @@ -750,6 +685,7 @@ fn should_fail_to_call_handle_link_anchor_message_without_anchor_being_pending() // now calling handle_link_anchor_message directly should fail. // on parachain A, since this anchor is not pending. ParaA::execute_with(|| { + use parachain_a::{XAnchor, Runtime, Origin}; let payload = LinkProposal { target_chain_id: PARAID_B.into(), target_tree_id: Some(para_a_tree_id), @@ -774,6 +710,7 @@ fn should_fail_to_call_link_anchors_as_signed_account() { // calling link_anchors as signed account should fail. // on parachain A. ParaA::execute_with(|| { + use parachain_a::{XAnchor, MerkleTree, Origin}; let payload = LinkProposal { target_chain_id: PARAID_B.into(), target_tree_id: Some(MerkleTree::next_tree_id()), @@ -793,6 +730,7 @@ fn should_fail_to_call_handle_link_anchors_as_signed_account() { // calling handle_link_anchors as signed account should fail. // on parachain A. ParaA::execute_with(|| { + use parachain_a::{XAnchor, MerkleTree, Origin}; let payload = LinkProposal { target_chain_id: PARAID_B.into(), target_tree_id: Some(MerkleTree::next_tree_id()), @@ -812,6 +750,7 @@ fn should_fail_to_call_register_resource_id_as_signed_account() { // calling register_resource_id as signed account should fail. // on parachain A. ParaA::execute_with(|| { + use parachain_a::{XAnchor, MerkleTree, Origin}; let r_id = derive_resource_id(PARAID_B.into(), &MerkleTree::next_tree_id().encode()); assert_err!( XAnchor::register_resource_id( @@ -831,6 +770,7 @@ fn should_fail_to_call_update_as_signed_account() { // calling update as signed account should fail. // on parachain A. ParaA::execute_with(|| { + use parachain_a::{XAnchor, MerkleTree, Origin}; let r_id = derive_resource_id(PARAID_B.into(), &MerkleTree::next_tree_id().encode()); let edge_metadata = EdgeMetadata { src_chain_id: PARAID_B.into(), @@ -854,11 +794,12 @@ fn test_cross_chain_withdrawal() { let mut src_chain_id_b = 0; let mut pk_bytes = Vec::new(); - let sender_account_id = parachain::AccountOne::get(); + let sender_account_id = AccountOne::get(); let curve = Curve::Bn254; ParaA::execute_with(|| { + use parachain_a::{setup_environment_withdraw, Anchor, MerkleTree, Origin}; pk_bytes = setup_environment_withdraw(curve); let max_edges = 2; let depth = TREE_DEPTH as u8; @@ -868,6 +809,7 @@ fn test_cross_chain_withdrawal() { }); ParaB::execute_with(|| { + use parachain_b::{setup_environment_withdraw, Anchor, MerkleTree, Origin}; setup_environment_withdraw(curve); let max_edges = 2; let depth = TREE_DEPTH as u8; @@ -877,6 +819,7 @@ fn test_cross_chain_withdrawal() { }); ParaA::execute_with(|| { + use parachain_a::{XAnchor, Runtime, Origin}; dbg!(para_a_tree_id); dbg!(para_b_tree_id); let converted_chain_id_bytes = @@ -887,6 +830,7 @@ fn test_cross_chain_withdrawal() { }); ParaB::execute_with(|| { + use parachain_b::{XAnchor, Runtime, Origin}; let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); let r_id = derive_resource_id(converted_chain_id_bytes, ¶_b_tree_id.encode()); @@ -911,6 +855,7 @@ fn test_cross_chain_withdrawal() { // Perform deposit on ParaA ParaA::execute_with(|| { + use parachain_a::{Balances, Anchor, MerkleTree, Origin}; // check the balance before the deposit. let balance_before = Balances::free_balance(sender_account_id.clone()); // and we do the deposit @@ -932,6 +877,7 @@ fn test_cross_chain_withdrawal() { // Perform withdrawal on ParaB ParaB::execute_with(|| { + use parachain_b::{Balances, Anchor, MerkleTree, LinkableTree, Runtime, Origin}; let converted_chain_id_bytes = compute_chain_id_with_internal_type::(u64::from(PARAID_A)); dbg!(converted_chain_id_bytes); @@ -944,13 +890,7 @@ fn test_cross_chain_withdrawal() { let tree_root = MerkleTree::get_root(para_b_tree_id).unwrap(); root_elements[0] = tree_root; - println!("chain_id: {:?}", src_chain_id.encode()); - println!("nullifier_hash: {:?}", nullifier_hash); - println!("roots: {:?}", root_elements); - println!("recipient_bytes: {:?}", recipient_element); - println!("relayer_bytes: {:?}", relayer_element); - println!("fee_bytes: {:?}", fee_value); - println!("refund_bytes: {:?}", refund_value); + println!("local chain_id: {:?}", src_chain_id); let proof_bytes = setup_zk_circuit(Curve::Bn254, src_chain_id.into(), secret, nullifier, vec![leaf], 0, root_elements, recipient_element, relayer_element, commitment_element, fee_value, refund_value, pk_bytes); let balance_before = Balances::free_balance(recipient_account_id.clone()); From 43611b57c862ca3415c2fc1f3a853831192e637a Mon Sep 17 00:00:00 2001 From: Filip Lazovic Date: Thu, 24 Feb 2022 16:37:32 +0100 Subject: [PATCH 8/8] WIP --- pallets/xanchor/src/mock/parachain_a.rs | 10 ++++++---- pallets/xanchor/src/mock/parachain_b.rs | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/pallets/xanchor/src/mock/parachain_a.rs b/pallets/xanchor/src/mock/parachain_a.rs index a54f7eacb..a2d696d8d 100644 --- a/pallets/xanchor/src/mock/parachain_a.rs +++ b/pallets/xanchor/src/mock/parachain_a.rs @@ -48,7 +48,7 @@ use arkworks_utils::utils::common::{setup_params_x5_3, Curve}; use ark_bn254::Fr as Bn254Fr; use frame_support::assert_ok; use frame_benchmarking::account; -use super::{AccountOne, AccountTwo, AccountThree, AccountFour, AccountFive, AccountSix, para_account_id, PARAID_A, INITIAL_BALANCE, Element}; +use super::{AccountOne, AccountTwo, AccountThree, AccountFour, AccountFive, AccountSix, para_account_id, PARAID_A, INITIAL_BALANCE, Element, parachain_b}; pub type Balance = u128; /// Type for storing the id of an asset. @@ -262,20 +262,22 @@ pub type LocationToAccountId = ( AccountId32Aliases, ); +pub type CumulusOrigin = cumulus_pallet_xcm::Origin; + pub type XcmOriginToCallOrigin = ( - SovereignSignedViaLocation, + SovereignSignedViaLocation, // Native converter for Relay-chain (Parent) location; will converts to a // `Relay` origin when recognised. RelayChainAsNative, // Native converter for sibling Parachains; will convert to a `SiblingPara` // origin when recognised. - SiblingParachainAsNative, + SiblingParachainAsNative, // Superuser converter for the Relay-chain (Parent) location. This will // allow it to issue a transaction from the Root origin. ParentAsSuperuser, // Native signed account converter; this just converts an `AccountId32` // origin into a normal `Origin::Signed` origin of the same 32-byte value. - SignedAccountId32AsNative, + SignedAccountId32AsNative, // Xcm origins can be represented natively under the Xcm pallet's Xcm // origin. XcmPassthrough, diff --git a/pallets/xanchor/src/mock/parachain_b.rs b/pallets/xanchor/src/mock/parachain_b.rs index 4f75296da..b0973b8b9 100644 --- a/pallets/xanchor/src/mock/parachain_b.rs +++ b/pallets/xanchor/src/mock/parachain_b.rs @@ -49,7 +49,7 @@ use ark_bn254::Fr as Bn254Fr; use frame_support::assert_ok; use frame_benchmarking::account; use xcm_executor::{Config, XcmExecutor}; -use super::{AccountOne, AccountTwo, AccountThree, AccountFour, AccountFive, AccountSix, para_account_id, PARAID_B, INITIAL_BALANCE, Element}; +use super::{AccountOne, AccountTwo, AccountThree, AccountFour, AccountFive, AccountSix, para_account_id, PARAID_B, INITIAL_BALANCE, Element, parachain_a}; pub type Balance = u128; /// Type for storing the id of an asset. @@ -261,20 +261,22 @@ pub type LocationToAccountId = ( AccountId32Aliases, ); +pub type CumulusOrigin = cumulus_pallet_xcm::Origin; + pub type XcmOriginToCallOrigin = ( - SovereignSignedViaLocation, + SovereignSignedViaLocation, // Native converter for Relay-chain (Parent) location; will converts to a // `Relay` origin when recognised. RelayChainAsNative, // Native converter for sibling Parachains; will convert to a `SiblingPara` // origin when recognised. - SiblingParachainAsNative, + SiblingParachainAsNative, // Superuser converter for the Relay-chain (Parent) location. This will // allow it to issue a transaction from the Root origin. ParentAsSuperuser, // Native signed account converter; this just converts an `AccountId32` // origin into a normal `Origin::Signed` origin of the same 32-byte value. - SignedAccountId32AsNative, + SignedAccountId32AsNative, // Xcm origins can be represented natively under the Xcm pallet's Xcm // origin. XcmPassthrough,