Skip to content

Commit 7bdc0a4

Browse files
TalDereiconorsch
authored andcommitted
funding: LQT nullifier set for epoch (#5034)
## 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
1 parent 825d2ce commit 7bdc0a4

File tree

8 files changed

+76
-4
lines changed

8 files changed

+76
-4
lines changed

crates/core/app-tests/tests/spend.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use penumbra_sdk_sct::{
1717
use penumbra_sdk_shielded_pool::{
1818
component::ShieldedPool, Note, SpendPlan, SpendProof, SpendProofPrivate, SpendProofPublic,
1919
};
20-
use penumbra_sdk_txhash::{EffectHash, TransactionContext};
20+
use penumbra_sdk_txhash::{EffectHash, TransactionContext, TransactionId};
2121
use rand_core::{OsRng, SeedableRng};
2222
use std::{ops::Deref, sync::Arc};
2323
use tendermint::abci;
@@ -65,6 +65,7 @@ async fn spend_happy_path() -> anyhow::Result<()> {
6565
let transaction_context = TransactionContext {
6666
anchor: root,
6767
effect_hash: EffectHash(dummy_effect_hash),
68+
transaction_id: TransactionId([0; 32]),
6869
};
6970

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

194196
// 3. Simulate execution of the Spend action

crates/core/component/funding/src/component.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use penumbra_sdk_asset::{Value, STAKING_TOKEN_ASSET_ID};
99
use penumbra_sdk_proto::{DomainType, StateWriteProto};
1010
use penumbra_sdk_stake::component::validator_handler::ValidatorDataRead;
1111
pub use view::{StateReadExt, StateWriteExt};
12+
pub(crate) mod liquidity_tournament;
1213

1314
use std::sync::Arc;
1415

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod nullifier;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use async_trait::async_trait;
2+
use penumbra_sdk_txhash::TransactionId;
3+
4+
use crate::component::state_key;
5+
use cnidarium::{StateRead, StateWrite};
6+
use penumbra_sdk_proto::{StateReadProto, StateWriteProto};
7+
use penumbra_sdk_sct::{component::clock::EpochRead, Nullifier};
8+
9+
#[allow(dead_code)]
10+
#[async_trait]
11+
pub trait NullifierRead: StateRead {
12+
/// Returns the `TransactionId` if the nullifier has been spent; otherwise, returns None.
13+
async fn get_lqt_spent_nullifier(&self, nullifier: Nullifier) -> Option<TransactionId> {
14+
// Grab the ambient epoch index.
15+
let epoch_index = self
16+
.get_current_epoch()
17+
.await
18+
.expect("epoch is always set")
19+
.index;
20+
21+
let nullifier_key = &state_key::lqt::v1::nullifier::key(epoch_index, &nullifier);
22+
23+
let tx_id: Option<TransactionId> = self
24+
.nonverifiable_get(&nullifier_key.as_bytes())
25+
.await
26+
.expect(&format!(
27+
"failed to retrieve key {} from non-verifiable storage",
28+
nullifier_key,
29+
));
30+
31+
tx_id
32+
}
33+
}
34+
35+
impl<T: StateRead + ?Sized> NullifierRead for T {}
36+
37+
#[allow(dead_code)]
38+
#[async_trait]
39+
pub trait NullifierWrite: StateWrite {
40+
/// Sets the LQT nullifier in the NV storage.
41+
fn put_lqt_spent_nullifier(
42+
&mut self,
43+
epoch_index: u64,
44+
nullifier: Nullifier,
45+
tx_id: TransactionId,
46+
) {
47+
let nullifier_key = state_key::lqt::v1::nullifier::key(epoch_index, &nullifier);
48+
49+
self.nonverifiable_put(nullifier_key.into(), tx_id);
50+
}
51+
}
52+
53+
impl<T: StateWrite + ?Sized> NullifierWrite for T {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
11
pub fn funding_parameters() -> &'static str {
22
"funding/parameters"
33
}
4+
5+
pub mod lqt {
6+
pub mod v1 {
7+
pub mod nullifier {
8+
use penumbra_sdk_sct::Nullifier;
9+
10+
/// A nullifier set indexed by epoch, mapping each epoch to its corresponding `TransactionId`.
11+
pub(crate) fn key(epoch_index: u64, nullifier: &Nullifier) -> String {
12+
format!("funding/lqt/v1/nullifier/{epoch_index:020}/lookup/{nullifier}")
13+
}
14+
}
15+
}
16+
}

crates/core/component/funding/src/component/view.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
use async_trait::async_trait;
2-
31
use crate::{component::state_key, params::FundingParameters};
42
use anyhow::Result;
3+
use async_trait::async_trait;
54
use cnidarium::{StateRead, StateWrite};
65
use penumbra_sdk_proto::{StateReadProto, StateWriteProto};
76

crates/core/transaction/src/transaction.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ impl Transaction {
144144
TransactionContext {
145145
anchor: self.anchor,
146146
effect_hash: self.effect_hash(),
147+
transaction_id: self.id(),
147148
}
148149
}
149150

crates/core/txhash/src/context.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::EffectHash;
1+
use crate::{EffectHash, TransactionId};
22
use penumbra_sdk_tct as tct;
33

44
/// Stateless verification context for a transaction.
@@ -10,4 +10,6 @@ pub struct TransactionContext {
1010
pub anchor: tct::Root,
1111
/// The transaction's effect hash.
1212
pub effect_hash: EffectHash,
13+
/// The transaction's id.
14+
pub transaction_id: TransactionId,
1315
}

0 commit comments

Comments
 (0)