Skip to content

Commit 6cad70b

Browse files
apollo_proof_manager: add nonce to key
1 parent 9964a0a commit 6cad70b

File tree

7 files changed

+162
-66
lines changed

7 files changed

+162
-66
lines changed

crates/apollo_gateway/src/gateway.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use apollo_transaction_converter::{
2929
};
3030
use async_trait::async_trait;
3131
use blockifier::state::contract_class_manager::ContractClassManager;
32+
use starknet_api::core::{ContractAddress, Nonce};
3233
use starknet_api::executable_transaction::AccountTransaction;
3334
use starknet_api::rpc_transaction::{
3435
InternalRpcTransaction,
@@ -205,13 +206,18 @@ impl<
205206
.inspect_err(|e| metric_counters.record_add_tx_failure(e))?;
206207

207208
let mut proof_archive_handle = None;
208-
if let Some((proof_facts, proof)) = proof_data {
209+
if let Some((proof_facts, tx_nonce, sender_address, proof)) = proof_data {
209210
let tx_hash = internal_tx.tx_hash;
210211
// Proof is verified during conversion to internal tx. It is stored here, after
211212
// validation, to avoid storing proofs for rejected transactions.
212213
let store_result = self
213214
.transaction_converter
214-
.store_proof_in_proof_manager(proof_facts.clone(), proof.clone())
215+
.store_proof_in_proof_manager(
216+
proof_facts.clone(),
217+
proof.clone(),
218+
tx_nonce,
219+
sender_address,
220+
)
215221
.await;
216222
match store_result {
217223
Ok(proof_manager_store_duration) => {
@@ -325,7 +331,11 @@ impl<
325331
tx: RpcTransaction,
326332
tx_signature: &TransactionSignature,
327333
) -> Result<
328-
(InternalRpcTransaction, AccountTransaction, Option<(ProofFacts, Proof)>),
334+
(
335+
InternalRpcTransaction,
336+
AccountTransaction,
337+
Option<(ProofFacts, Nonce, ContractAddress, Proof)>,
338+
),
329339
StarknetError,
330340
> {
331341
let (internal_tx, verification_handle) =
@@ -356,7 +366,7 @@ impl<
356366
&self,
357367
verification_handle: Option<VerificationHandle>,
358368
tx_signature: &TransactionSignature,
359-
) -> Result<Option<(ProofFacts, Proof)>, StarknetError> {
369+
) -> Result<Option<(ProofFacts, Nonce, ContractAddress, Proof)>, StarknetError> {
360370
let Some(handle) = verification_handle else {
361371
return Ok(None);
362372
};
@@ -373,7 +383,7 @@ impl<
373383
transaction_converter_err_to_deprecated_gw_err(tx_signature, e)
374384
})?;
375385

376-
Ok(Some((handle.proof_facts, handle.proof)))
386+
Ok(Some((handle.proof_facts, handle.nonce, handle.sender_address, handle.proof)))
377387
}
378388
}
379389

crates/apollo_gateway/src/gateway_test.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,18 @@ impl MockDependencies {
187187
self.mock_mempool_client.expect_validate_tx().once().with(eq(args)).return_once(|_| result);
188188
}
189189

190-
fn expect_store_proof(&mut self, proof_facts: ProofFacts, proof: Proof) {
190+
fn expect_store_proof(
191+
&mut self,
192+
proof_facts: ProofFacts,
193+
proof: Proof,
194+
nonce: Nonce,
195+
sender_address: ContractAddress,
196+
) {
191197
self.mock_transaction_converter
192198
.expect_store_proof_in_proof_manager()
193199
.once()
194-
.with(eq(proof_facts), eq(proof))
195-
.returning(|_, _| Ok(std::time::Duration::ZERO));
200+
.with(eq(proof_facts), eq(proof), eq(nonce), eq(sender_address))
201+
.returning(|_, _, _, _| Ok(std::time::Duration::ZERO));
196202
}
197203
}
198204

@@ -267,6 +273,8 @@ fn setup_transaction_converter_mock(
267273
Some(VerificationHandle {
268274
proof_facts: invoke_tx.proof_facts.clone(),
269275
proof: invoke_tx.proof.clone(),
276+
nonce: invoke_tx.nonce,
277+
sender_address: invoke_tx.sender_address,
270278
verification_task,
271279
})
272280
} else {
@@ -346,8 +354,12 @@ async fn setup_mock_state(
346354
// If the transaction has proof facts, expect set_proof to be called on the proof manager.
347355
if let RpcTransaction::Invoke(RpcInvokeTransaction::V3(ref invoke_tx)) = input_tx {
348356
if !invoke_tx.proof_facts.is_empty() {
349-
mock_dependencies
350-
.expect_store_proof(invoke_tx.proof_facts.clone(), invoke_tx.proof.clone());
357+
mock_dependencies.expect_store_proof(
358+
invoke_tx.proof_facts.clone(),
359+
invoke_tx.proof.clone(),
360+
invoke_tx.nonce,
361+
invoke_tx.sender_address,
362+
);
351363
}
352364
}
353365

crates/apollo_proof_manager/src/communication.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,27 @@ pub type RemoteProofManagerServer =
1313
impl ComponentRequestHandler<ProofManagerRequest, ProofManagerResponse> for ProofManager {
1414
async fn handle_request(&mut self, request: ProofManagerRequest) -> ProofManagerResponse {
1515
match request {
16-
ProofManagerRequest::SetProof(proof_facts, proof) => ProofManagerResponse::SetProof(
17-
self.set_proof(proof_facts, proof)
18-
.await
19-
.map_err(|e| ProofManagerError::ProofStorage(e.to_string())),
20-
),
21-
ProofManagerRequest::GetProof(proof_facts) => ProofManagerResponse::GetProof(
22-
self.get_proof(proof_facts)
23-
.await
24-
.map_err(|e| ProofManagerError::ProofStorage(e.to_string())),
25-
),
26-
ProofManagerRequest::ContainsProof(proof_facts) => ProofManagerResponse::ContainsProof(
27-
self.contains_proof(proof_facts)
28-
.await
29-
.map_err(|e| ProofManagerError::ProofStorage(e.to_string())),
30-
),
16+
ProofManagerRequest::SetProof(proof_facts, nonce, sender_address, proof) => {
17+
ProofManagerResponse::SetProof(
18+
self.set_proof(proof_facts, nonce, sender_address, proof)
19+
.await
20+
.map_err(|e| ProofManagerError::ProofStorage(e.to_string())),
21+
)
22+
}
23+
ProofManagerRequest::GetProof(proof_facts, nonce, sender_address) => {
24+
ProofManagerResponse::GetProof(
25+
self.get_proof(proof_facts, nonce, sender_address)
26+
.await
27+
.map_err(|e| ProofManagerError::ProofStorage(e.to_string())),
28+
)
29+
}
30+
ProofManagerRequest::ContainsProof(proof_facts, nonce, sender_address) => {
31+
ProofManagerResponse::ContainsProof(
32+
self.contains_proof(proof_facts, nonce, sender_address)
33+
.await
34+
.map_err(|e| ProofManagerError::ProofStorage(e.to_string())),
35+
)
36+
}
3137
}
3238
}
3339
}

crates/apollo_proof_manager/src/proof_manager.rs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use apollo_infra::component_definitions::{default_component_start_fn, ComponentS
66
use apollo_proof_manager_config::config::ProofManagerConfig;
77
use async_trait::async_trait;
88
use lru::LruCache;
9+
use starknet_api::core::{ContractAddress, Nonce};
910
use starknet_api::transaction::fields::{Proof, ProofFacts};
1011
use starknet_types_core::felt::Felt;
1112
use tracing::info;
@@ -71,48 +72,64 @@ impl ProofManager {
7172
Self { proof_storage, cache: ProofCache::new(config.cache_size) }
7273
}
7374

75+
fn make_storage_key(facts_hash: Felt, nonce: Nonce, sender_address: ContractAddress) -> Felt {
76+
// Simple addition of facts hash, nonce, and sender address.
77+
let nonce_felt = nonce.0;
78+
let sender_felt = *sender_address.key();
79+
facts_hash + nonce_felt + sender_felt
80+
}
81+
7482
pub async fn set_proof(
7583
&self,
7684
proof_facts: ProofFacts,
85+
nonce: Nonce,
86+
sender_address: ContractAddress,
7787
proof: Proof,
7888
) -> Result<(), FsProofStorageError> {
79-
if self.contains_proof(proof_facts.clone()).await? {
89+
let facts_hash = proof_facts.hash();
90+
let storage_key = Self::make_storage_key(facts_hash, nonce, sender_address);
91+
if self.contains_proof(proof_facts.clone(), nonce, sender_address).await? {
8092
return Ok(());
8193
}
82-
let facts_hash = proof_facts.hash();
83-
self.proof_storage.set_proof(facts_hash, proof.clone()).await?;
84-
self.cache.insert(facts_hash, proof);
94+
self.proof_storage.set_proof(storage_key, proof.clone()).await?;
95+
self.cache.insert(storage_key, proof);
8596
Ok(())
8697
}
8798

8899
pub async fn get_proof(
89100
&self,
90101
proof_facts: ProofFacts,
102+
nonce: Nonce,
103+
sender_address: ContractAddress,
91104
) -> Result<Option<Proof>, FsProofStorageError> {
92105
let facts_hash = proof_facts.hash();
106+
let storage_key = Self::make_storage_key(facts_hash, nonce, sender_address);
93107
// Check cache first.
94-
if let Some(proof) = self.cache.get(&facts_hash) {
108+
if let Some(proof) = self.cache.get(&storage_key) {
95109
return Ok(Some(proof));
96110
}
97111
// Fallback to filesystem.
98-
let proof = self.proof_storage.get_proof(facts_hash).await?;
112+
let proof = self.proof_storage.get_proof(storage_key).await?;
99113
if let Some(proof) = &proof {
100-
self.cache.insert(facts_hash, proof.clone());
114+
self.cache.insert(storage_key, proof.clone());
101115
}
102116
Ok(proof)
103117
}
104118

105119
pub async fn contains_proof(
106120
&self,
107121
proof_facts: ProofFacts,
122+
nonce: Nonce,
123+
sender_address: ContractAddress,
108124
) -> Result<bool, FsProofStorageError> {
109125
let facts_hash = proof_facts.hash();
126+
let storage_key = Self::make_storage_key(facts_hash, nonce, sender_address);
110127
// Check cache first.
111-
if self.cache.contains(&facts_hash) {
128+
if self.cache.contains(&storage_key) {
112129
return Ok(true);
113130
}
114131
// Fallback to filesystem.
115-
self.proof_storage.contains_proof(facts_hash).await
132+
self.proof_storage.contains_proof(storage_key).await
116133
}
117134
}
118135

crates/apollo_proof_manager_types/src/lib.rs

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use async_trait::async_trait;
1313
#[cfg(any(feature = "testing", test))]
1414
use mockall::automock;
1515
use serde::{Deserialize, Serialize};
16+
use starknet_api::core::{ContractAddress, Nonce};
1617
use starknet_api::transaction::fields::{Proof, ProofFacts};
1718
use strum::EnumVariantNames;
1819
use strum_macros::{AsRefStr, EnumDiscriminants, EnumIter, IntoStaticStr};
@@ -36,12 +37,24 @@ pub trait ProofManagerClient: Send + Sync {
3637
async fn set_proof(
3738
&self,
3839
proof_facts: ProofFacts,
40+
nonce: Nonce,
41+
sender_address: ContractAddress,
3942
proof: Proof,
4043
) -> ProofManagerClientResult<()>;
4144

42-
async fn get_proof(&self, proof_facts: ProofFacts) -> ProofManagerClientResult<Option<Proof>>;
45+
async fn get_proof(
46+
&self,
47+
proof_facts: ProofFacts,
48+
nonce: Nonce,
49+
sender_address: ContractAddress,
50+
) -> ProofManagerClientResult<Option<Proof>>;
4351

44-
async fn contains_proof(&self, proof_facts: ProofFacts) -> ProofManagerClientResult<bool>;
52+
async fn contains_proof(
53+
&self,
54+
proof_facts: ProofFacts,
55+
nonce: Nonce,
56+
sender_address: ContractAddress,
57+
) -> ProofManagerClientResult<bool>;
4558
}
4659

4760
#[derive(Clone, Debug, Error, Eq, PartialEq, Serialize, Deserialize)]
@@ -69,9 +82,9 @@ pub enum ProofManagerClientError {
6982
strum(serialize_all = "snake_case")
7083
)]
7184
pub enum ProofManagerRequest {
72-
SetProof(ProofFacts, Proof),
73-
GetProof(ProofFacts),
74-
ContainsProof(ProofFacts),
85+
SetProof(ProofFacts, Nonce, ContractAddress, Proof),
86+
GetProof(ProofFacts, Nonce, ContractAddress),
87+
ContainsProof(ProofFacts, Nonce, ContractAddress),
7588
}
7689
impl_debug_for_infra_requests_and_responses!(ProofManagerRequest);
7790
impl_labeled_request!(ProofManagerRequest, ProofManagerRequestLabelValue);
@@ -98,9 +111,11 @@ where
98111
async fn set_proof(
99112
&self,
100113
proof_facts: ProofFacts,
114+
nonce: Nonce,
115+
sender_address: ContractAddress,
101116
proof: Proof,
102117
) -> ProofManagerClientResult<()> {
103-
let request = ProofManagerRequest::SetProof(proof_facts, proof);
118+
let request = ProofManagerRequest::SetProof(proof_facts, nonce, sender_address, proof);
104119
handle_all_response_variants!(
105120
self,
106121
request,
@@ -112,8 +127,13 @@ where
112127
)
113128
}
114129

115-
async fn get_proof(&self, proof_facts: ProofFacts) -> ProofManagerClientResult<Option<Proof>> {
116-
let request = ProofManagerRequest::GetProof(proof_facts);
130+
async fn get_proof(
131+
&self,
132+
proof_facts: ProofFacts,
133+
nonce: Nonce,
134+
sender_address: ContractAddress,
135+
) -> ProofManagerClientResult<Option<Proof>> {
136+
let request = ProofManagerRequest::GetProof(proof_facts, nonce, sender_address);
117137
handle_all_response_variants!(
118138
self,
119139
request,
@@ -125,8 +145,13 @@ where
125145
)
126146
}
127147

128-
async fn contains_proof(&self, proof_facts: ProofFacts) -> ProofManagerClientResult<bool> {
129-
let request = ProofManagerRequest::ContainsProof(proof_facts);
148+
async fn contains_proof(
149+
&self,
150+
proof_facts: ProofFacts,
151+
nonce: Nonce,
152+
sender_address: ContractAddress,
153+
) -> ProofManagerClientResult<bool> {
154+
let request = ProofManagerRequest::ContainsProof(proof_facts, nonce, sender_address);
130155
handle_all_response_variants!(
131156
self,
132157
request,

0 commit comments

Comments
 (0)