Skip to content

Commit

Permalink
Refactor partial_fulfillment_intent, `partial_fulfillment_token_swa…
Browse files Browse the repository at this point in the history
…p_tx` examples (#231)

* [tmp] tx_examples::partial_fulfillment_token_swap: Comment out example

* taiga_halo2::Nullifier: introduce Nullifier::random method

* vp_examples::partial_fulfillment_intent: Update example

* vp_examples::partial_fulfillment_intent: Modularise structs

* tx-examples::partial_fulfillment_token_swap: Fix example
  • Loading branch information
therealyingtong authored Oct 18, 2023
1 parent 5880f50 commit df9410c
Show file tree
Hide file tree
Showing 6 changed files with 692 additions and 583 deletions.
156 changes: 38 additions & 118 deletions taiga_halo2/examples/tx_examples/partial_fulfillment_token_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@ use pasta_curves::{group::Curve, pallas};
use rand::{CryptoRng, RngCore};
use taiga_halo2::{
circuit::vp_examples::{
partial_fulfillment_intent::{
create_intent_note, PartialFulfillmentIntentValidityPredicateCircuit,
},
partial_fulfillment_intent::{PartialFulfillmentIntentValidityPredicateCircuit, Swap},
signature_verification::COMPRESSED_TOKEN_AUTH_VK,
token::{Token, TokenAuthorization},
token::{Token, TokenAuthorization, TokenNote},
},
constant::TAIGA_COMMITMENT_TREE_DEPTH,
merkle_tree::{Anchor, MerklePath},
note::{InputNoteProvingInfo, Note, OutputNoteProvingInfo},
nullifier::{Nullifier, NullifierKeyContainer},
nullifier::NullifierKeyContainer,
shielded_ptx::ShieldedPartialTransaction,
transaction::{ShieldedPartialTxBundle, Transaction, TransparentPartialTxBundle},
};
Expand All @@ -29,39 +27,17 @@ pub fn create_token_intent_ptx<R: RngCore>(
sell: Token,
buy: Token,
input_auth_sk: pallas::Scalar,
input_nk: NullifierKeyContainer, // NullifierKeyContainer::Key
) -> (
ShieldedPartialTransaction,
NullifierKeyContainer,
pallas::Base,
pallas::Base,
Nullifier,
) {
) -> (ShieldedPartialTransaction, Swap, Note) {
let input_auth = TokenAuthorization::from_sk_vk(&input_auth_sk, &COMPRESSED_TOKEN_AUTH_VK);

// input note
let rho = Nullifier::from(pallas::Base::random(&mut rng));
let input_note = sell.create_random_token_note(&mut rng, rho, input_nk, &input_auth);

// output intent note
let input_note_nk_com = input_note.get_nk_commitment();
let input_note_nf = input_note.get_nf().unwrap();
let intent_note = create_intent_note(
&mut rng,
&sell,
&buy,
input_note_nk_com,
input_note.app_data_dynamic,
input_note_nf,
input_nk,
);
let swap = Swap::random(&mut rng, sell, buy, input_auth);
let intent_note = swap.create_intent_note(&mut rng);

// padding the zero notes
let padding_input_note = Note::random_padding_input_note(&mut rng);
let padding_input_note_nf = padding_input_note.get_nf().unwrap();
let padding_output_note = Note::random_padding_output_note(&mut rng, padding_input_note_nf);

let input_notes = [*input_note.note(), padding_input_note];
let input_notes = [*swap.sell.note(), padding_input_note];
let output_notes = [intent_note, padding_output_note];

let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH);
Expand All @@ -70,7 +46,7 @@ pub fn create_token_intent_ptx<R: RngCore>(
let anchor = Anchor::from(pallas::Base::random(&mut rng));

// Create the input note proving info
let input_note_proving_info = input_note.generate_input_token_note_proving_info(
let input_note_proving_info = swap.sell.generate_input_token_note_proving_info(
&mut rng,
input_auth,
input_auth_sk,
Expand All @@ -85,10 +61,7 @@ pub fn create_token_intent_ptx<R: RngCore>(
owned_note_pub_id: intent_note.commitment().inner(),
input_notes,
output_notes,
sell: sell.clone(),
buy,
receiver_nk_com: input_note_nk_com,
receiver_app_data_dynamic: input_note.app_data_dynamic,
swap: swap.clone(),
};

OutputNoteProvingInfo::new(intent_note, Box::new(intent_vp), vec![])
Expand Down Expand Up @@ -118,61 +91,23 @@ pub fn create_token_intent_ptx<R: RngCore>(
&mut rng,
);

(
ptx,
input_nk,
input_note_nk_com,
input_note.app_data_dynamic,
rho,
)
(ptx, swap, intent_note)
}

#[allow(clippy::too_many_arguments)]
pub fn consume_token_intent_ptx<R: RngCore>(
mut rng: R,
sell: Token,
buy: Token,
bought_note_value: u64,
returned_note_value: u64,
input_rho: Nullifier,
input_nk: NullifierKeyContainer, // NullifierKeyContainer::Key
receiver_nk_com: pallas::Base,
receiver_app_data_dynamic: pallas::Base,
swap: Swap,
intent_note: Note,
offer: Token,
output_auth_pk: pallas::Point,
) -> ShieldedPartialTransaction {
// input intent note
let intent_note = create_intent_note(
&mut rng,
&sell,
&buy,
receiver_nk_com,
receiver_app_data_dynamic,
input_rho,
input_nk,
);
let (input_notes, output_notes) = swap.fill(&mut rng, intent_note, offer);
let [intent_note, padding_input_note] = input_notes;
let [bought_note, returned_note] = output_notes;

// output notes
let input_note_nf = intent_note.get_nf().unwrap();
let output_auth = TokenAuthorization::new(output_auth_pk, *COMPRESSED_TOKEN_AUTH_VK);
let bought_token = Token::new(buy.name().inner(), bought_note_value);
let bought_note =
bought_token.create_random_token_note(&mut rng, input_note_nf, input_nk, &output_auth);

// padding the zero note
let padding_input_note = Note::random_padding_input_note(&mut rng);
let padding_input_note_nf = padding_input_note.get_nf().unwrap();
let returned_token = Token::new(sell.name().inner(), returned_note_value);
let returned_note = returned_token.create_random_token_note(
&mut rng,
padding_input_note_nf,
input_nk,
&output_auth,
);
// let padding_output_note = Note::random_padding_input_note(&mut rng, padding_input_note_nf);

let input_notes = [intent_note, padding_input_note];
let output_notes = [*bought_note.note(), *returned_note.note()];

let merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH);

// Fetch a valid anchor for dummy notes
Expand All @@ -181,13 +116,10 @@ pub fn consume_token_intent_ptx<R: RngCore>(
// Create the intent note proving info
let intent_note_proving_info = {
let intent_vp = PartialFulfillmentIntentValidityPredicateCircuit {
owned_note_pub_id: input_note_nf.inner(),
owned_note_pub_id: intent_note.get_nf().unwrap().inner(),
input_notes,
output_notes,
sell: sell.clone(),
buy: buy.clone(),
receiver_nk_com,
receiver_app_data_dynamic,
swap: swap.clone(),
};

InputNoteProvingInfo::new(
Expand All @@ -200,12 +132,11 @@ pub fn consume_token_intent_ptx<R: RngCore>(
};

// Create the output note proving info
let bought_note_proving_info = bought_note.generate_output_token_note_proving_info(
&mut rng,
output_auth,
input_notes,
output_notes,
);
let bought_note_proving_info = TokenNote {
token_name: swap.buy.name().clone(),
note: bought_note,
}
.generate_output_token_note_proving_info(&mut rng, output_auth, input_notes, output_notes);

// Create the padding input note proving info
let padding_input_note_proving_info = InputNoteProvingInfo::create_padding_note_proving_info(
Expand All @@ -217,12 +148,11 @@ pub fn consume_token_intent_ptx<R: RngCore>(
);

// Create the returned note proving info
let returned_note_proving_info = returned_note.generate_output_token_note_proving_info(
&mut rng,
output_auth,
input_notes,
output_notes,
);
let returned_note_proving_info = TokenNote {
token_name: swap.sell.token_name().clone(),
note: returned_note,
}
.generate_output_token_note_proving_info(&mut rng, output_auth, input_notes, output_notes);

// Create shielded partial tx
ShieldedPartialTransaction::build(
Expand All @@ -236,46 +166,36 @@ pub fn consume_token_intent_ptx<R: RngCore>(
pub fn create_token_swap_transaction<R: RngCore + CryptoRng>(mut rng: R) -> Transaction {
let generator = pallas::Point::generator().to_affine();

// Alice creates the partial transaction with 5 BTC input and intent output
// Alice creates the partial transaction with:
// - 2 BTC sell
// - intent output encoding 10 ETH ask
let alice_auth_sk = pallas::Scalar::random(&mut rng);
let alice_auth_pk = generator * alice_auth_sk;
let alice_nk = NullifierKeyContainer::random_key(&mut rng);
let sell = Token::new("btc".to_string(), 2u64);
let buy = Token::new("eth".to_string(), 10u64);
let (alice_ptx, intent_nk, receiver_nk_com, receiver_app_data_dynamic, intent_rho) =
create_token_intent_ptx(&mut rng, sell.clone(), buy.clone(), alice_auth_sk, alice_nk);
let (alice_ptx, swap, intent_note) =
create_token_intent_ptx(&mut rng, sell.clone(), buy.clone(), alice_auth_sk);

// Bob creates the partial transaction with 1 DOLPHIN input and 5 BTC output
let bob_auth_sk = pallas::Scalar::random(&mut rng);
let bob_auth_pk = generator * bob_auth_sk;
let bob_nk = NullifierKeyContainer::random_key(&mut rng);
let eth_token = Token::new("eth".to_string(), 5);
let btc_token = Token::new("btc".to_string(), 1);
let offer = Token::new("eth".to_string(), 5);
let returned = Token::new("btc".to_string(), 1);

let bob_ptx = create_token_swap_ptx(
&mut rng,
eth_token,
offer.clone(),
bob_auth_sk,
bob_nk,
btc_token,
returned,
bob_auth_pk,
bob_nk.to_commitment(),
);

// Solver/Bob creates the partial transaction to consume the intent note
// The bob_ptx and solver_ptx can be merged to one ptx.
let solver_ptx = consume_token_intent_ptx(
&mut rng,
sell,
buy,
5u64,
1u64,
intent_rho,
intent_nk,
receiver_nk_com,
receiver_app_data_dynamic,
alice_auth_pk,
);
let solver_ptx = consume_token_intent_ptx(&mut rng, swap, intent_note, offer, alice_auth_pk);

// Solver creates the final transaction
let shielded_tx_bundle = ShieldedPartialTxBundle::new(vec![alice_ptx, bob_ptx, solver_ptx]);
Expand Down
Loading

0 comments on commit df9410c

Please sign in to comment.