Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TASK] Test cross-chain withdrawals with xanchor + anchor #161

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

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

6 changes: 4 additions & 2 deletions pallets/anchor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,6 @@ pub mod pallet {
pub enum Error<T, I = ()> {
/// Invalid Merkle Roots
InvalidMerkleRoots,
/// Unknown root
UnknownRoot,
/// Invalid withdraw proof
InvalidWithdrawProof,
/// Mixer not found.
Expand Down Expand Up @@ -385,6 +383,10 @@ impl<T: Config<I>, I: 'static> AnchorInterface<AnchorConfigration<T, I>> for Pal
bytes.extend_from_slice(&fee_bytes);
bytes.extend_from_slice(&refund_bytes);
bytes.extend_from_slice(&commitment.encode());
println!("WITHDRAW PROOF bytes");
drewstone marked this conversation as resolved.
Show resolved Hide resolved
println!("{:?}", &bytes);
println!("WITHDRAW PROOF proof_bytes");
println!("{:?}", &proof_bytes);
let result = <T as pallet::Config<I>>::Verifier::verify(&bytes, proof_bytes)?;
ensure!(result, Error::<T, I>::InvalidWithdrawProof);
// withdraw or refresh depending on the refresh commitment value
Expand Down
2 changes: 2 additions & 0 deletions pallets/anchor/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<AccountId>("", 1, SEED);
let recipient_account_id = account::<AccountId>("", 2, SEED);
let relayer_account_id = account::<AccountId>("", 0, SEED);
Expand Down
1 change: 0 additions & 1 deletion pallets/linkable-tree/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,6 @@ impl<T: Config<I>, I: 'static> LinkableTreeInspector<LinkableTreeConfigration<T,
if roots.len() > 1 {
// Get edges and corresponding chain IDs for the anchor
let edges = EdgeList::<T, I>::iter_prefix(id).into_iter().collect::<Vec<_>>();

// 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])?;
Expand Down
2 changes: 2 additions & 0 deletions pallets/mt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,8 @@ impl<T: Config<I>, I: 'static> TreeInspector<T::AccountId, T::TreeId, T::Element

fn is_known_root(tree_id: T::TreeId, target_root: T::Element) -> Result<bool, DispatchError> {
ensure!(Trees::<T, I>::contains_key(tree_id), Error::<T, I>::TreeDoesntExist);
println!("{:?}", tree_id);
drewstone marked this conversation as resolved.
Show resolved Hide resolved
println!("{:?}", target_root);
let mut temp: T::RootIndex = Zero::zero();
while temp < T::RootHistorySize::get() {
let cached_root = CachedRoots::<T, I>::get(tree_id, temp);
Expand Down
3 changes: 3 additions & 0 deletions pallets/xanchor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand Down
8 changes: 6 additions & 2 deletions pallets/xanchor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,17 +682,21 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
.encode()
.into(),
};
println!("{:?}", update_edge);
println!("{:?}", "updating edge");
drewstone marked this conversation as resolved.
Show resolved Hide resolved
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,
Expand Down Expand Up @@ -732,7 +736,7 @@ pub fn para_id_to_chain_id<T: Config<I>, I: 'static>(para_id: ParaId) -> T::Chai
.unwrap_or_default()
}

pub fn chain_id_to_bytes<T: Config<I>, I: 'static>(chain_id: T::ChainId) -> T::ChainId {
pub fn compute_chain_id_with_internal_type<T: Config<I>, 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()
}
1 change: 1 addition & 0 deletions pallets/xanchor/src/mock/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod parachain;
pub mod relay_chain;
pub(crate) mod test_utils;

use std::ops::Mul;

Expand Down
165 changes: 165 additions & 0 deletions pallets/xanchor/src/mock/test_utils.rs
Original file line number Diff line number Diff line change
@@ -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<u8>;
type RootsElement = Vec<Element>;
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<Bn254Fr, M, TREE_DEPTH>;

pub fn setup_zk_circuit(
curve: Curve,
recipient_bytes: Vec<u8>,
relayer_bytes: Vec<u8>,
commitment_bytes: Vec<u8>,
pk_bytes: Vec<u8>,
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::<Bn254Fr, _>(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::<Bn254Fr>(curve);
let params4 = setup_params_x5_4::<Bn254Fr>(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::<Bn254, _>(
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<u8>,
relayer_bytes: Vec<u8>,
commitment_bytes: [u8; 32],
pk_bytes: Vec<u8>,
src_chain_id: u128,
fee_value: u128,
refund_value: u128,
) -> (
Vec<u8>, // proof bytes
Vec<Element>, // roots
Element, // nullifier_hash
Element, // leaf
) {
match curve {
Curve::Bn254 => {
let note_secret = "7e0f4bfa263d8b93854772c94851c04b3a9aba38ab808a8d081f6f5be9758110b7147c395ee9bf495734e4703b1f622009c81712520de0bbd5e7a10237c7d829bf6bd6d0729cca778ed9b6fb172bbb12b01927258aca7e0a66fd5691548f8717";

let secret = hex::decode(&note_secret[0..32]).unwrap();
let nullifier = hex::decode(&note_secret[32..64]).unwrap();
let (leaf, _) = setup_leaf_with_privates_raw_x5_4::<Bn254Fr>(
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::<Bn254Fr>(curve);
let params4 = setup_params_x5_4::<Bn254Fr>(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<u8> {
let mut truncated_bytes = t[12..].to_vec();
truncated_bytes.extend_from_slice(&[0u8; 12]);
truncated_bytes
}
Loading