Skip to content

Commit

Permalink
funding: LQT nullifier set for epoch (#5034)
Browse files Browse the repository at this point in the history
## Describe your changes

state key for epoch-scoped nullifier set (mapping nullifiers with their
associated transaction id), serving as a precursor for performing the
necessary stateful [nullifier
check](https://github.com/penumbra-zone/penumbra/pull/5033/files#diff-a0986b8d223ab5b1c5536ba06bde1ede6d08f635eb97b386549ecfb55a4f2a4bR112).
Additionally, augments the transaction context with `TransactionId`.

## Issue ticket number and link

references #5029

## Checklist before requesting a review

- [x] I have added guiding text to explain how a reviewer should test
these changes.

- [x] If this code contains consensus-breaking changes, I have added the
"consensus-breaking" label. Otherwise, I declare my belief that there
are not consensus-breaking changes, for the following reason:

  > LQT branch
  • Loading branch information
TalDerei authored and conorsch committed Feb 4, 2025
1 parent e6a7d05 commit b98584e
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 4 deletions.
4 changes: 3 additions & 1 deletion crates/core/app-tests/tests/spend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use penumbra_sdk_sct::{
use penumbra_sdk_shielded_pool::{
component::ShieldedPool, Note, SpendPlan, SpendProof, SpendProofPrivate, SpendProofPublic,
};
use penumbra_sdk_txhash::{EffectHash, TransactionContext};
use penumbra_sdk_txhash::{EffectHash, TransactionContext, TransactionId};
use rand_core::{OsRng, SeedableRng};
use std::{ops::Deref, sync::Arc};
use tendermint::abci;
Expand Down Expand Up @@ -65,6 +65,7 @@ async fn spend_happy_path() -> anyhow::Result<()> {
let transaction_context = TransactionContext {
anchor: root,
effect_hash: EffectHash(dummy_effect_hash),
transaction_id: TransactionId([0; 32]),
};

// 3. Simulate execution of the Spend action
Expand Down Expand Up @@ -189,6 +190,7 @@ async fn invalid_dummy_spend() {
let transaction_context = TransactionContext {
anchor: root,
effect_hash: EffectHash(dummy_effect_hash),
transaction_id: TransactionId([0; 32]),
};

// 3. Simulate execution of the Spend action
Expand Down
1 change: 1 addition & 0 deletions crates/core/component/funding/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use penumbra_sdk_asset::{Value, STAKING_TOKEN_ASSET_ID};
use penumbra_sdk_proto::{DomainType, StateWriteProto};
use penumbra_sdk_stake::component::validator_handler::ValidatorDataRead;
pub use view::{StateReadExt, StateWriteExt};
pub(crate) mod liquidity_tournament;

use std::sync::Arc;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod nullifier;
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use async_trait::async_trait;
use penumbra_sdk_txhash::TransactionId;

use crate::component::state_key;
use cnidarium::{StateRead, StateWrite};
use penumbra_sdk_proto::{StateReadProto, StateWriteProto};
use penumbra_sdk_sct::{component::clock::EpochRead, Nullifier};

#[allow(dead_code)]
#[async_trait]
pub trait NullifierRead: StateRead {
/// Returns the `TransactionId` if the nullifier has been spent; otherwise, returns None.
async fn get_lqt_spent_nullifier(&self, nullifier: Nullifier) -> Option<TransactionId> {
// Grab the ambient epoch index.
let epoch_index = self
.get_current_epoch()
.await
.expect("epoch is always set")
.index;

let nullifier_key = &state_key::lqt::v1::nullifier::key(epoch_index, &nullifier);

let tx_id: Option<TransactionId> = self
.nonverifiable_get(&nullifier_key.as_bytes())
.await
.expect(&format!(
"failed to retrieve key {} from non-verifiable storage",
nullifier_key,
));

tx_id
}
}

impl<T: StateRead + ?Sized> NullifierRead for T {}

#[allow(dead_code)]
#[async_trait]
pub trait NullifierWrite: StateWrite {
/// Sets the LQT nullifier in the NV storage.
fn put_lqt_spent_nullifier(
&mut self,
epoch_index: u64,
nullifier: Nullifier,
tx_id: TransactionId,
) {
let nullifier_key = state_key::lqt::v1::nullifier::key(epoch_index, &nullifier);

self.nonverifiable_put(nullifier_key.into(), tx_id);
}
}

impl<T: StateWrite + ?Sized> NullifierWrite for T {}
13 changes: 13 additions & 0 deletions crates/core/component/funding/src/component/state_key.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
pub fn funding_parameters() -> &'static str {
"funding/parameters"
}

pub mod lqt {
pub mod v1 {
pub mod nullifier {
use penumbra_sdk_sct::Nullifier;

/// A nullifier set indexed by epoch, mapping each epoch to its corresponding `TransactionId`.
pub(crate) fn key(epoch_index: u64, nullifier: &Nullifier) -> String {
format!("funding/lqt/v1/nullifier/{epoch_index:020}/lookup/{nullifier}")
}
}
}
}
3 changes: 1 addition & 2 deletions crates/core/component/funding/src/component/view.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use async_trait::async_trait;

use crate::{component::state_key, params::FundingParameters};
use anyhow::Result;
use async_trait::async_trait;
use cnidarium::{StateRead, StateWrite};
use penumbra_sdk_proto::{StateReadProto, StateWriteProto};

Expand Down
1 change: 1 addition & 0 deletions crates/core/transaction/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ impl Transaction {
TransactionContext {
anchor: self.anchor,
effect_hash: self.effect_hash(),
transaction_id: self.id(),
}
}

Expand Down
4 changes: 3 additions & 1 deletion crates/core/txhash/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::EffectHash;
use crate::{EffectHash, TransactionId};
use penumbra_sdk_tct as tct;

/// Stateless verification context for a transaction.
Expand All @@ -10,4 +10,6 @@ pub struct TransactionContext {
pub anchor: tct::Root,
/// The transaction's effect hash.
pub effect_hash: EffectHash,
/// The transaction's id.
pub transaction_id: TransactionId,
}

0 comments on commit b98584e

Please sign in to comment.