From 1f975bc5bde5a9185ffe7da9ca079728eae0030d Mon Sep 17 00:00:00 2001 From: Xuyang Song Date: Mon, 26 Aug 2024 22:57:12 +0800 Subject: [PATCH] update the swap intent exmaple --- taiga_halo2/examples/tx_examples/main.rs | 6 +- .../tx_examples/token_swap_with_intent.rs | 213 ++++++----------- .../src/circuit/resource_logic_bytecode.rs | 22 +- .../src/circuit/resource_logic_examples.rs | 12 +- .../or_relation_intent.rs | 226 +++++++++++------- taiga_halo2/src/resource_tree.rs | 2 +- taiga_halo2/src/shielded_ptx.rs | 8 +- 7 files changed, 234 insertions(+), 255 deletions(-) diff --git a/taiga_halo2/examples/tx_examples/main.rs b/taiga_halo2/examples/tx_examples/main.rs index dec144be..41ab3299 100644 --- a/taiga_halo2/examples/tx_examples/main.rs +++ b/taiga_halo2/examples/tx_examples/main.rs @@ -1,6 +1,6 @@ // mod partial_fulfillment_token_swap; mod token; -// mod token_swap_with_intent; +mod token_swap_with_intent; mod token_swap_without_intent; fn main() { use rand::rngs::OsRng; @@ -9,8 +9,8 @@ fn main() { let tx = token_swap_without_intent::create_token_swap_transaction(rng); tx.execute().unwrap(); - // let tx = token_swap_with_intent::create_token_swap_intent_transaction(rng); - // tx.execute().unwrap(); + let tx = token_swap_with_intent::create_token_swap_intent_transaction(rng); + tx.execute().unwrap(); // let tx = partial_fulfillment_token_swap::create_token_swap_transaction(rng); // tx.execute().unwrap(); diff --git a/taiga_halo2/examples/tx_examples/token_swap_with_intent.rs b/taiga_halo2/examples/tx_examples/token_swap_with_intent.rs index 6e1b99b0..feb99e37 100644 --- a/taiga_halo2/examples/tx_examples/token_swap_with_intent.rs +++ b/taiga_halo2/examples/tx_examples/token_swap_with_intent.rs @@ -18,7 +18,8 @@ use taiga_halo2::{ constant::TAIGA_COMMITMENT_TREE_DEPTH, merkle_tree::{Anchor, MerklePath}, nullifier::NullifierKeyContainer, - resource::{Resource, ResourceLogics}, + resource::ResourceLogics, + resource_tree::{ResourceExistenceWitness, ResourceMerkleTreeLeaves}, shielded_ptx::ShieldedPartialTransaction, transaction::{ShieldedPartialTxBundle, Transaction, TransparentPartialTxBundle}, }; @@ -53,10 +54,6 @@ pub fn create_token_intent_ptx( input_nk, ); - // padding the zero resources - let padding_input_resource = Resource::random_padding_resource(&mut rng); - let mut padding_output_resource = Resource::random_padding_resource(&mut rng); - let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); // Create compliance pairs @@ -69,79 +66,51 @@ pub fn create_token_intent_ptx( &mut rng, ); - // Fetch a valid anchor for padding input resources - let anchor = Anchor::from(pallas::Base::random(&mut rng)); - let compliance_2 = ComplianceInfo::new( - padding_input_resource, - merkle_path, - Some(anchor), - &mut padding_output_resource, - &mut rng, - ); - vec![compliance_1, compliance_2] + vec![compliance_1] }; - // Create resource logics - let (input_resource_logics, output_resource_logics) = { - let input_resources = [*input_resource.resource(), padding_input_resource]; - let output_resources = [intent_resource, padding_output_resource]; - // Create resource_logics for the input resource - let input_resource_resource_logics = input_resource.generate_input_token_resource_logics( + // Collect resource merkle leaves + let input_resource_nf = input_resource.get_nf().unwrap().inner(); + let output_resource_cm = intent_resource.commitment().inner(); + let resource_merkle_tree = + ResourceMerkleTreeLeaves::new(vec![input_resource_nf, output_resource_cm]); + + // Create resource logics for the input resource + let input_resource_resource_logics = { + let merkle_path = resource_merkle_tree + .generate_path(input_resource_nf) + .unwrap(); + input_resource.generate_input_token_resource_logics( &mut rng, input_auth, input_auth_sk, - input_resources, - output_resources, - ); - - // Create resource logics for the intent resource - let intent_resource_resource_logics = { - let intent_resource_logic = OrRelationIntentResourceLogicCircuit { - self_resource_id: intent_resource.commitment().inner(), - input_resources, - output_resources, - token_1, - token_2, - receiver_npk: input_resource_npk, - receiver_value: input_resource.value, - }; + merkle_path, + ) + }; - ResourceLogics::new(Box::new(intent_resource_logic), vec![]) + // Create resource logics for the intent(output) resource + let output_resource_resource_logics = { + let merkle_path = resource_merkle_tree + .generate_path(output_resource_cm) + .unwrap(); + let intent_resource_witness = ResourceExistenceWitness::new(intent_resource, merkle_path); + let circuit = OrRelationIntentResourceLogicCircuit { + self_resource: intent_resource_witness, + // the desired resource won't be checked. + desired_resource: intent_resource_witness, + token_1, + token_2, + receiver_npk: input_resource_npk, + receiver_value: input_resource.value, }; - - // Create resource logics for the padding input - let padding_input_resource_logics = - ResourceLogics::create_input_padding_resource_resource_logics( - &padding_input_resource, - input_resources, - output_resources, - ); - - // Create resource_logics for the padding output - let padding_output_resource_logics = - ResourceLogics::create_output_padding_resource_resource_logics( - &padding_output_resource, - input_resources, - output_resources, - ); - - ( - vec![ - input_resource_resource_logics, - padding_input_resource_logics, - ], - vec![ - intent_resource_resource_logics, - padding_output_resource_logics, - ], - ) + ResourceLogics::new(Box::new(circuit), vec![]) }; // Create shielded partial tx let ptx = ShieldedPartialTransaction::build( compliances, - input_resource_logics, - output_resource_logics, + vec![input_resource_resource_logics], + vec![output_resource_resource_logics], vec![], &mut rng, ) @@ -172,95 +141,65 @@ pub fn consume_token_intent_ptx( ); // output resource - let input_resource_nf = intent_resource.get_nf().unwrap(); let output_auth = TokenAuthorization::new(output_auth_pk, *COMPRESSED_TOKEN_AUTH_VK); let output_npk = NullifierKeyContainer::from_key(input_nk).get_npk(); let mut output_resource = output_token.create_random_output_token_resource(&mut rng, output_npk, &output_auth); - // padding the zero resources - let padding_input_resource = Resource::random_padding_resource(&mut rng); - let mut padding_output_resource = Resource::random_padding_resource(&mut rng); - let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); // Fetch a valid anchor for dummy resources let anchor = Anchor::from(pallas::Base::random(&mut rng)); // Create compliance pairs - let compliances = { - let compliance_1 = ComplianceInfo::new( - intent_resource, - merkle_path.clone(), - Some(anchor), - &mut output_resource.resource, - &mut rng, - ); - - let compliance_2 = ComplianceInfo::new( - padding_input_resource, - merkle_path, - Some(anchor), - &mut padding_output_resource, - &mut rng, - ); - vec![compliance_1, compliance_2] - }; - - // Create resource logics - let (input_resource_logics, output_resource_logics) = { - let input_resources = [intent_resource, padding_input_resource]; - let output_resources = [*output_resource.resource(), padding_output_resource]; - // Create resource_logics for the intent - let intent_resource_logics = { - let intent_resource_logic = OrRelationIntentResourceLogicCircuit { - self_resource_id: input_resource_nf.inner(), - input_resources, - output_resources, - token_1, - token_2, - receiver_npk, - receiver_value, - }; + let compliance = ComplianceInfo::new( + intent_resource, + merkle_path.clone(), + Some(anchor), + &mut output_resource.resource, + &mut rng, + ); - ResourceLogics::new(Box::new(intent_resource_logic), vec![]) + let input_resource_nf = intent_resource.get_nf().unwrap().inner(); + let output_resource_cm = output_resource.commitment().inner(); + let resource_merkle_tree = + ResourceMerkleTreeLeaves::new(vec![input_resource_nf, output_resource_cm]); + + let output_merkle_path = resource_merkle_tree + .generate_path(output_resource_cm) + .unwrap(); + + // Create resource logics for the intent(input) resource + let intent_resource_logics = { + let merkle_path = resource_merkle_tree + .generate_path(input_resource_nf) + .unwrap(); + let intent_resource_logic = OrRelationIntentResourceLogicCircuit { + self_resource: ResourceExistenceWitness::new(intent_resource, merkle_path), + desired_resource: ResourceExistenceWitness::new( + output_resource.resource, + output_merkle_path, + ), + token_1, + token_2, + receiver_npk, + receiver_value, }; - // Create resource logics for the output token resource - let output_token_resource_logics = output_resource.generate_output_token_resource_logics( - &mut rng, - output_auth, - input_resources, - output_resources, - ); - - // Create resource_logics for the padding input - let padding_input_resource_logics = - ResourceLogics::create_input_padding_resource_resource_logics( - &padding_input_resource, - input_resources, - output_resources, - ); - - // Create resource_logics for the padding output - let padding_output_resource_logics = - ResourceLogics::create_output_padding_resource_resource_logics( - &padding_output_resource, - input_resources, - output_resources, - ); - - ( - vec![intent_resource_logics, padding_input_resource_logics], - vec![output_token_resource_logics, padding_output_resource_logics], - ) + ResourceLogics::new(Box::new(intent_resource_logic), vec![]) }; + let output_resource_logics = output_resource.generate_output_token_resource_logics( + &mut rng, + output_auth, + output_merkle_path, + ); + // Create shielded partial tx ShieldedPartialTransaction::build( - compliances, - input_resource_logics, - output_resource_logics, + vec![compliance], + vec![intent_resource_logics], + vec![output_resource_logics], vec![], &mut rng, ) diff --git a/taiga_halo2/src/circuit/resource_logic_bytecode.rs b/taiga_halo2/src/circuit/resource_logic_bytecode.rs index c80d046b..7fd37506 100644 --- a/taiga_halo2/src/circuit/resource_logic_bytecode.rs +++ b/taiga_halo2/src/circuit/resource_logic_bytecode.rs @@ -2,7 +2,7 @@ use crate::circuit::resource_logic_examples::TrivialResourceLogicCircuit; #[cfg(feature = "examples")] use crate::circuit::resource_logic_examples::{ - // or_relation_intent::OrRelationIntentResourceLogicCircuit, + or_relation_intent::OrRelationIntentResourceLogicCircuit, // partial_fulfillment_intent::PartialFulfillmentIntentResourceLogicCircuit, receiver_resource_logic::ReceiverResourceLogicCircuit, signature_verification::SignatureVerificationResourceLogicCircuit, @@ -107,11 +107,11 @@ impl ResourceLogicByteCode { // PartialFulfillmentIntentResourceLogicCircuit::from_bytes(&self.inputs); // Ok(resource_logic.get_verifying_info()) // } - // #[cfg(feature = "examples")] - // ResourceLogicRepresentation::OrRelationIntent => { - // let resource_logic = OrRelationIntentResourceLogicCircuit::from_bytes(&self.inputs); - // Ok(resource_logic.get_verifying_info()) - // } + #[cfg(feature = "examples")] + ResourceLogicRepresentation::OrRelationIntent => { + let resource_logic = OrRelationIntentResourceLogicCircuit::from_bytes(&self.inputs); + Ok(resource_logic.get_verifying_info()) + } #[allow(unreachable_patterns)] _ => Err(TransactionError::InvalidResourceLogicRepresentation), } @@ -163,11 +163,11 @@ impl ResourceLogicByteCode { // PartialFulfillmentIntentResourceLogicCircuit::from_bytes(&self.inputs); // resource_logic.verify_transparently()? // } - // #[cfg(feature = "examples")] - // ResourceLogicRepresentation::OrRelationIntent => { - // let resource_logic = OrRelationIntentResourceLogicCircuit::from_bytes(&self.inputs); - // resource_logic.verify_transparently()? - // } + #[cfg(feature = "examples")] + ResourceLogicRepresentation::OrRelationIntent => { + let resource_logic = OrRelationIntentResourceLogicCircuit::from_bytes(&self.inputs); + resource_logic.verify_transparently()? + } #[allow(unreachable_patterns)] _ => return Err(TransactionError::InvalidResourceLogicRepresentation), }; diff --git a/taiga_halo2/src/circuit/resource_logic_examples.rs b/taiga_halo2/src/circuit/resource_logic_examples.rs index 1abc4bba..3edd70ab 100644 --- a/taiga_halo2/src/circuit/resource_logic_examples.rs +++ b/taiga_halo2/src/circuit/resource_logic_examples.rs @@ -14,8 +14,8 @@ use crate::{ resource_logic_vk::ResourceLogicVerifyingKey, resource_tree::ResourceExistenceWitness, }; -#[cfg(feature = "borsh")] -use borsh::{BorshDeserialize, BorshSerialize}; +// #[cfg(feature = "borsh")] +// use borsh::{BorshDeserialize, BorshSerialize}; use halo2_proofs::plonk::{keygen_pk, keygen_vk, ProvingKey}; use halo2_proofs::{ circuit::{floor_planner, Layouter}, @@ -24,13 +24,11 @@ use halo2_proofs::{ use lazy_static::lazy_static; use pasta_curves::{pallas, vesta}; use rand::{rngs::OsRng, RngCore}; -#[cfg(feature = "nif")] -use rustler::{Decoder, Encoder, Env, NifResult, NifStruct, Term}; #[cfg(feature = "examples")] mod field_addition; -// #[cfg(feature = "examples")] -// pub mod or_relation_intent; +#[cfg(feature = "examples")] +pub mod or_relation_intent; // #[cfg(feature = "examples")] // pub mod partial_fulfillment_intent; #[cfg(feature = "examples")] @@ -88,7 +86,7 @@ impl TrivialResourceLogicCircuit { bincode::serialize(&self).unwrap() } - pub fn from_bytes(bytes: &Vec) -> Self { + pub fn from_bytes(bytes: &[u8]) -> Self { bincode::deserialize(bytes).unwrap() } } diff --git a/taiga_halo2/src/circuit/resource_logic_examples/or_relation_intent.rs b/taiga_halo2/src/circuit/resource_logic_examples/or_relation_intent.rs index e4a49c57..5ec569c5 100644 --- a/taiga_halo2/src/circuit/resource_logic_examples/or_relation_intent.rs +++ b/taiga_halo2/src/circuit/resource_logic_examples/or_relation_intent.rs @@ -5,25 +5,25 @@ use crate::{ circuit::{ blake2s::publicize_default_dynamic_resource_logic_commitments, - gadgets::{ - assign_free_advice, - poseidon_hash::poseidon_hash_gadget, - target_resource_variable::{get_is_input_resource_flag, get_owned_resource_variable}, - }, + gadgets::{assign_free_advice, assign_free_constant, poseidon_hash::poseidon_hash_gadget}, + integrity::load_resource, + merkle_circuit::MerklePoseidonChip, + resource_commitment::ResourceCommitChip, resource_logic_bytecode::{ResourceLogicByteCode, ResourceLogicRepresentation}, resource_logic_circuit::{ - BasicResourceLogicVariables, ResourceLogicCircuit, ResourceLogicConfig, - ResourceLogicPublicInputs, ResourceLogicVerifyingInfo, ResourceLogicVerifyingInfoTrait, + ResourceLogicCircuit, ResourceLogicConfig, ResourceLogicPublicInputs, + ResourceLogicVerifyingInfo, ResourceLogicVerifyingInfoTrait, ResourceStatus, }, resource_logic_examples::token::{Token, TOKEN_VK}, }, - constant::{NUM_RESOURCE, SETUP_PARAMS_MAP}, + constant::SETUP_PARAMS_MAP, error::TransactionError, nullifier::Nullifier, proof::Proof, resource::{RandomSeed, Resource}, resource_logic_commitment::ResourceLogicCommitment, resource_logic_vk::ResourceLogicVerifyingKey, + resource_tree::ResourceExistenceWitness, utils::poseidon_hash_n, utils::read_base_field, }; @@ -48,9 +48,10 @@ lazy_static! { // OrRelationIntentResourceLogicCircuit #[derive(Clone, Debug, Default)] pub struct OrRelationIntentResourceLogicCircuit { - pub self_resource_id: pallas::Base, - pub input_resources: [Resource; NUM_RESOURCE], - pub output_resources: [Resource; NUM_RESOURCE], + // self_resource is the intent resource + pub self_resource: ResourceExistenceWitness, + // If the self_resource(intent) is an output resource, a dummy desired resource is needed. + pub desired_resource: ResourceExistenceWitness, pub token_1: Token, pub token_2: Token, pub receiver_npk: pallas::Base, @@ -101,15 +102,53 @@ impl ResourceLogicCircuit for OrRelationIntentResourceLogicCircuit { &self, config: Self::Config, mut layouter: impl Layouter, - basic_variables: BasicResourceLogicVariables, + self_resource: ResourceStatus, ) -> Result<(), Error> { - let self_resource_id = basic_variables.get_self_resource_id(); - let is_input_resource = get_is_input_resource_flag( - config.get_is_input_resource_flag_config, - layouter.namespace(|| "get is_input_resource_flag"), - &self_resource_id, - &basic_variables.get_input_resource_nfs(), - &basic_variables.get_output_resource_cms(), + // check + { + let one = assign_free_constant( + layouter.namespace(|| "constant one"), + config.advices[0], + pallas::Base::one(), + )?; + layouter.assign_region( + || "check label", + |mut region| { + region.constrain_equal(one.cell(), self_resource.resource.is_ephemeral.cell()) + }, + )?; + } + // load the desired resource + let desired_resource = { + // Construct a merkle chip + let merkle_chip = MerklePoseidonChip::construct(config.merkle_config); + + // Construct a resource_commit chip + let resource_commit_chip = + ResourceCommitChip::construct(config.resource_commit_config.clone()); + + load_resource( + layouter.namespace(|| "load the desired resource"), + config.advices, + resource_commit_chip, + config.conditional_select_config, + merkle_chip, + &self.desired_resource, + )? + }; + + // check self_resource and desired_resource are on the same tree + layouter.assign_region( + || "conditional equal: check root", + |mut region| { + config.conditional_equal_config.assign_region( + &self_resource.is_input, + &self_resource.resource_merkle_root, + &desired_resource.resource_merkle_root, + 0, + &mut region, + ) + }, )?; let token_resource_logic_vk = assign_free_advice( @@ -169,18 +208,12 @@ impl ResourceLogicCircuit for OrRelationIntentResourceLogicCircuit { ], )?; - // search target resource and get the intent label - let label = get_owned_resource_variable( - config.get_owned_resource_variable_config, - layouter.namespace(|| "get owned resource label"), - &self_resource_id, - &basic_variables.get_label_searchable_pairs(), - )?; - // check the label of intent resource layouter.assign_region( || "check label", - |mut region| region.constrain_equal(encoded_label.cell(), label.cell()), + |mut region| { + region.constrain_equal(encoded_label.cell(), self_resource.resource.label.cell()) + }, )?; // check the resource_logic vk of output resource @@ -188,11 +221,9 @@ impl ResourceLogicCircuit for OrRelationIntentResourceLogicCircuit { || "conditional equal: check resource_logic vk", |mut region| { config.conditional_equal_config.assign_region( - &is_input_resource, + &self_resource.is_input, &token_resource_logic_vk, - &basic_variables.output_resource_variables[0] - .resource_variables - .logic, + &desired_resource.resource.logic, 0, &mut region, ) @@ -204,11 +235,9 @@ impl ResourceLogicCircuit for OrRelationIntentResourceLogicCircuit { || "conditional equal: check npk", |mut region| { config.conditional_equal_config.assign_region( - &is_input_resource, + &self_resource.is_input, &receiver_npk, - &basic_variables.output_resource_variables[0] - .resource_variables - .npk, + &desired_resource.resource.npk, 0, &mut region, ) @@ -220,34 +249,48 @@ impl ResourceLogicCircuit for OrRelationIntentResourceLogicCircuit { || "conditional equal: check value", |mut region| { config.conditional_equal_config.assign_region( - &is_input_resource, + &self_resource.is_input, &receiver_value, - &basic_variables.output_resource_variables[0] - .resource_variables - .value, + &desired_resource.resource.value, 0, &mut region, ) }, )?; + // check the desired_resource is an output + { + let zero_constant = assign_free_constant( + layouter.namespace(|| "constant zero"), + config.advices[0], + pallas::Base::zero(), + )?; + + layouter.assign_region( + || "conditional equal: check desired_resource is_input", + |mut region| { + config.conditional_equal_config.assign_region( + &self_resource.is_input, + &zero_constant, + &desired_resource.is_input, + 0, + &mut region, + ) + }, + )?; + } + // check the token_property and token_quantity in conditions - let output_resource_token_property = &basic_variables.output_resource_variables[0] - .resource_variables - .label; - let output_resource_token_quantity = &basic_variables.output_resource_variables[0] - .resource_variables - .quantity; layouter.assign_region( || "extended or relatioin", |mut region| { config.extended_or_relation_config.assign_region( - &is_input_resource, + &self_resource.is_input, (&token_property_1, &token_quantity_1), (&token_property_2, &token_quantity_2), ( - output_resource_token_property, - output_resource_token_quantity, + &desired_resource.resource.label, + &desired_resource.resource.quantity, ), 0, &mut region, @@ -265,14 +308,6 @@ impl ResourceLogicCircuit for OrRelationIntentResourceLogicCircuit { Ok(()) } - fn get_input_resources(&self) -> &[Resource; NUM_RESOURCE] { - &self.input_resources - } - - fn get_output_resources(&self) -> &[Resource; NUM_RESOURCE] { - &self.output_resources - } - fn get_public_inputs(&self, mut rng: impl RngCore) -> ResourceLogicPublicInputs { let mut public_inputs = self.get_mandatory_public_inputs(); let default_resource_logic_cm: [pallas::Base; 2] = @@ -287,8 +322,8 @@ impl ResourceLogicCircuit for OrRelationIntentResourceLogicCircuit { public_inputs.into() } - fn get_self_resource_id(&self) -> pallas::Base { - self.self_resource_id + fn get_self_resource(&self) -> ResourceExistenceWitness { + self.self_resource } } @@ -297,14 +332,8 @@ resource_logic_verifying_info_impl!(OrRelationIntentResourceLogicCircuit); impl BorshSerialize for OrRelationIntentResourceLogicCircuit { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { - writer.write_all(&self.self_resource_id.to_repr())?; - for input in self.input_resources.iter() { - input.serialize(writer)?; - } - - for output in self.output_resources.iter() { - output.serialize(writer)?; - } + self.self_resource.serialize(writer)?; + self.desired_resource.serialize(writer)?; self.token_1.serialize(writer)?; self.token_2.serialize(writer)?; @@ -318,21 +347,15 @@ impl BorshSerialize for OrRelationIntentResourceLogicCircuit { impl BorshDeserialize for OrRelationIntentResourceLogicCircuit { fn deserialize_reader(reader: &mut R) -> std::io::Result { - let self_resource_id = read_base_field(reader)?; - let input_resources: Vec<_> = (0..NUM_RESOURCE) - .map(|_| Resource::deserialize_reader(reader)) - .collect::>()?; - let output_resources: Vec<_> = (0..NUM_RESOURCE) - .map(|_| Resource::deserialize_reader(reader)) - .collect::>()?; + let self_resource = ResourceExistenceWitness::deserialize_reader(reader)?; + let desired_resource = ResourceExistenceWitness::deserialize_reader(reader)?; let token_1 = Token::deserialize_reader(reader)?; let token_2 = Token::deserialize_reader(reader)?; let receiver_npk = read_base_field(reader)?; let receiver_value = read_base_field(reader)?; Ok(Self { - self_resource_id, - input_resources: input_resources.try_into().unwrap(), - output_resources: output_resources.try_into().unwrap(), + self_resource, + desired_resource, token_1, token_2, receiver_npk, @@ -374,7 +397,7 @@ fn test_halo2_or_relation_intent_resource_logic_circuit() { use crate::constant::RESOURCE_LOGIC_CIRCUIT_PARAMS_SIZE; use crate::{ circuit::resource_logic_examples::token::COMPRESSED_TOKEN_VK, - resource::tests::random_resource, + resource::tests::random_resource, resource_tree::ResourceMerkleTreeLeaves, }; use halo2_proofs::arithmetic::Field; use halo2_proofs::dev::MockProver; @@ -382,33 +405,52 @@ fn test_halo2_or_relation_intent_resource_logic_circuit() { let mut rng = OsRng; let circuit = { - let mut output_resources = [(); NUM_RESOURCE].map(|_| random_resource(&mut rng)); let token_1 = Token::new("token1".to_string(), 1u64); let token_2 = Token::new("token2".to_string(), 2u64); - output_resources[0].kind.logic = *COMPRESSED_TOKEN_VK; - output_resources[0].kind.label = token_1.encode_name(); - output_resources[0].quantity = token_1.quantity(); + + // Create an output desired resource + let mut desired_resource = random_resource(&mut rng); + desired_resource.kind.logic = *COMPRESSED_TOKEN_VK; + desired_resource.kind.label = token_1.encode_name(); + desired_resource.quantity = token_1.quantity(); let nk = pallas::Base::random(&mut rng); - let npk = output_resources[0].get_npk(); let intent_resource = create_intent_resource( &mut rng, &token_1, &token_2, - npk, - output_resources[0].value, + desired_resource.get_npk(), + desired_resource.value, nk, ); - let padding_input_resource = Resource::random_padding_resource(&mut rng); - let input_resources = [intent_resource, padding_input_resource]; + + // Collect resource merkle leaves + let input_resource_nf_1 = intent_resource.get_nf().unwrap().inner(); + let output_resource_cm_1 = desired_resource.commitment().inner(); + let resource_merkle_tree = + ResourceMerkleTreeLeaves::new(vec![input_resource_nf_1, output_resource_cm_1]); + + let intent_resource_witness = { + let merkle_path = resource_merkle_tree + .generate_path(input_resource_nf_1) + .unwrap(); + ResourceExistenceWitness::new(intent_resource, merkle_path) + }; + + let desired_resource_witness = { + let merkle_path = resource_merkle_tree + .generate_path(output_resource_cm_1) + .unwrap(); + ResourceExistenceWitness::new(desired_resource, merkle_path) + }; + OrRelationIntentResourceLogicCircuit { - self_resource_id: input_resources[0].get_nf().unwrap().inner(), - input_resources, - output_resources, + self_resource: intent_resource_witness, + desired_resource: desired_resource_witness, token_1, token_2, - receiver_npk: npk, - receiver_value: output_resources[0].value, + receiver_npk: desired_resource.get_npk(), + receiver_value: desired_resource.value, } }; diff --git a/taiga_halo2/src/resource_tree.rs b/taiga_halo2/src/resource_tree.rs index 8b61b20c..6337bf4e 100644 --- a/taiga_halo2/src/resource_tree.rs +++ b/taiga_halo2/src/resource_tree.rs @@ -62,7 +62,7 @@ impl ResourceExistenceWitness { bincode::serialize(&self).unwrap() } - pub fn from_bytes(bytes: &Vec) -> Self { + pub fn from_bytes(bytes: &[u8]) -> Self { bincode::deserialize(bytes).unwrap() } } diff --git a/taiga_halo2/src/shielded_ptx.rs b/taiga_halo2/src/shielded_ptx.rs index 18ed1a98..b27bfdba 100644 --- a/taiga_halo2/src/shielded_ptx.rs +++ b/taiga_halo2/src/shielded_ptx.rs @@ -16,7 +16,7 @@ use pasta_curves::pallas; use rand::RngCore; #[cfg(feature = "nif")] -use rustler::{Decoder, Encoder, Env, NifResult, NifStruct, Term}; +use rustler::NifStruct; #[cfg(feature = "serde")] use serde; @@ -87,9 +87,9 @@ impl ShieldedPartialTransaction { .collect(); Ok(Self { - compliances: compliances.try_into().unwrap(), - inputs: inputs?.try_into().unwrap(), - outputs: outputs?.try_into().unwrap(), + compliances, + inputs: inputs?, + outputs: outputs?, binding_sig_r: Some(rcv_sum), hints, })