Skip to content

Commit

Permalink
mock-consensus: ⭐ use transaction plan to add spends
Browse files Browse the repository at this point in the history
* #3588.
* #3788.
* #3857
  • Loading branch information
cratelyn committed Feb 22, 2024
1 parent 6b99c0e commit 56ca685
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 38 deletions.
51 changes: 13 additions & 38 deletions crates/core/app/tests/mock_consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,48 +93,23 @@ async fn mock_consensus_can_send_a_spend_action() -> anyhow::Result<()> {
.witness(note.commit())
.ok_or_else(|| anyhow!("index is not witnessed"))?;

// ...and use it to craft a `Spend`.
let (spend, spend_key) = {
use {decaf377_rdsa::SigningKey, penumbra_shielded_pool::SpendPlan};
let spend_plan = SpendPlan::new(&mut rng, note, proof.position());
let auth_sig = test_keys::SPEND_KEY
.spend_auth_key()
.randomize(&spend_plan.randomizer)
.sign(&mut rng, [0u8; 64].as_ref());
let spend = spend_plan.spend(&test_keys::FULL_VIEWING_KEY, auth_sig, proof, sct.root());
let key = SigningKey::from(spend_plan.value_blinding);
(spend, key)
};

// Next, craft a transaction, containing this `Spend`.
let tx = {
use {
penumbra_asset::Value,
penumbra_fee::Fee,
penumbra_num::Amount,
penumbra_transaction::{Action, Transaction, TransactionBody, TransactionParameters},
penumbra_txhash::AuthorizingData,
};
let transaction_parameters = TransactionParameters {
expiry_height: 0,
chain_id: "i-wonder-if-this-is-load-bearing".to_owned(),
fee: Fee(Value {
amount: Amount::zero(),
asset_id,
}),
penumbra_proto::DomainType,
penumbra_shielded_pool::SpendPlan,
penumbra_transaction::{Transaction, TransactionPlan},
};
let transaction_body = TransactionBody {
actions: vec![Action::Spend(spend)],
transaction_parameters,
..Default::default()
};
let binding_sig = spend_key.sign(rng, transaction_body.auth_hash().as_bytes());
let transaction = Transaction {
transaction_body,
binding_sig,
anchor: sct.root(),
};
<Transaction as penumbra_proto::DomainType>::encode_to_vec(&transaction)

let (viewing_key, spend_key) = (&test_keys::FULL_VIEWING_KEY, &test_keys::SPEND_KEY);
let mut plan = TransactionPlan::default();
plan.actions
.push(SpendPlan::new(&mut rng, note, proof.position()).into());
let witness = plan.witness_data(sct)?;
let auth = plan.authorize(rand_core::OsRng, spend_key)?;
plan.build_concurrent(viewing_key, &witness, &auth)
.await
.map(|tx| tx.encode_to_vec())?
};

// Execute the transaction, and sync another mock client up to the latest snapshot.
Expand Down
21 changes: 21 additions & 0 deletions crates/core/transaction/src/plan/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,25 @@ impl TransactionPlan {
// 4. Return the completed transaction.
Ok(tx)
}

/// Returns a [`WitnessData`], which may be used to build this transaction.
pub fn witness_data(&self, sct: penumbra_tct::Tree) -> Result<WitnessData, anyhow::Error> {
let anchor = sct.root();

let witness_note = |spend: &penumbra_shielded_pool::SpendPlan| {
let commitment = spend.note.commit();
sct.witness(commitment)
.ok_or_else(|| anyhow::anyhow!("commitment should exist in tree"))
.map(|proof| (commitment, proof))
};
let state_commitment_proofs = self
.spend_plans()
.map(witness_note)
.collect::<Result<_, _>>()?;

Ok(WitnessData {
anchor,
state_commitment_proofs,
})
}
}

0 comments on commit 56ca685

Please sign in to comment.