Skip to content

Commit

Permalink
Seq num consistency check
Browse files Browse the repository at this point in the history
  • Loading branch information
hu55a1n1 committed Jan 26, 2025
1 parent 5fe9d9a commit a735160
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 2 deletions.
20 changes: 20 additions & 0 deletions crates/enclave/core/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,23 @@ where
}
}
}

pub fn ensure_seq_num_consistency(
seq_num_in_store: u64,
seq_num_on_chain: u64,
pending_sequenced_requests: usize,
) -> Result<(), Status> {
if seq_num_on_chain < seq_num_in_store {
return Err(Status::failed_precondition("replay attempted"));
}

// make sure number of pending requests are equal to the diff b/w on-chain v/s in-mem seq num
let seq_num_diff = seq_num_on_chain - seq_num_in_store;
if seq_num_diff != pending_sequenced_requests as u64 {
return Err(Status::failed_precondition(&format!(
"seq_num_diff mismatch: num({seq_num_diff}) v/s diff({pending_sequenced_requests})"
)));

Check warning on line 81 in crates/enclave/core/src/handler.rs

View workflow job for this annotation

GitHub Actions / clippy

the borrowed expression implements the required traits

warning: the borrowed expression implements the required traits --> crates/enclave/core/src/handler.rs:79:48 | 79 | return Err(Status::failed_precondition(&format!( | ________________________________________________^ 80 | | "seq_num_diff mismatch: num({seq_num_diff}) v/s diff({pending_sequenced_requests})" 81 | | ))); | |_________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrows_for_generic_args = note: `#[warn(clippy::needless_borrows_for_generic_args)]` on by default help: change this to | 79 ~ return Err(Status::failed_precondition(format!( 80 + "seq_num_diff mismatch: num({seq_num_diff}) v/s diff({pending_sequenced_requests})" 81 ~ ))); |

Check warning on line 81 in crates/enclave/core/src/handler.rs

View workflow job for this annotation

GitHub Actions / clippy

the borrowed expression implements the required traits

warning: the borrowed expression implements the required traits --> crates/enclave/core/src/handler.rs:79:48 | 79 | return Err(Status::failed_precondition(&format!( | ________________________________________________^ 80 | | "seq_num_diff mismatch: num({seq_num_diff}) v/s diff({pending_sequenced_requests})" 81 | | ))); | |_________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrows_for_generic_args = note: `#[warn(clippy::needless_borrows_for_generic_args)]` on by default help: change this to | 79 ~ return Err(Status::failed_precondition(format!( 80 + "seq_num_diff mismatch: num({seq_num_diff}) v/s diff({pending_sequenced_requests})" 81 ~ ))); |
}

Ok(())
}
2 changes: 2 additions & 0 deletions crates/enclave/core/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ pub trait Store: Send + Sync + 'static {
) -> Result<Option<Self::Contract>, Self::Error>;
async fn get_nonce(&self) -> Result<Option<Nonce>, Self::Error>;
async fn set_nonce(&mut self, nonce: Nonce) -> Result<Option<Nonce>, Self::Error>;
async fn get_seq_num(&self) -> Result<u64, Self::Error>;
async fn inc_seq_num(&mut self, count: usize) -> Result<u64, Self::Error>;
}
12 changes: 12 additions & 0 deletions crates/enclave/core/src/store/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub struct DefaultStore {
config: Option<Config>,
contract: Option<AccountId>,
nonce: Option<Nonce>,
seq_num: u64,
}

impl DefaultStore {
Expand All @@ -17,6 +18,7 @@ impl DefaultStore {
config: Some(config),
contract: None,
nonce: None,
seq_num: 0,
}
}
}
Expand Down Expand Up @@ -55,4 +57,14 @@ impl Store for DefaultStore {
async fn set_nonce(&mut self, nonce: Nonce) -> Result<Option<Nonce>, Self::Error> {
Ok(self.nonce.replace(nonce))
}

async fn get_seq_num(&self) -> Result<u64, Self::Error> {
Ok(self.seq_num)
}

async fn inc_seq_num(&mut self, count: usize) -> Result<u64, Self::Error> {
let prev_seq_num = self.seq_num;
self.seq_num = self.seq_num + (count as u64);

Check warning on line 67 in crates/enclave/core/src/store/default.rs

View workflow job for this annotation

GitHub Actions / clippy

manual implementation of an assign operation

warning: manual implementation of an assign operation --> crates/enclave/core/src/store/default.rs:67:9 | 67 | self.seq_num = self.seq_num + (count as u64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `self.seq_num += (count as u64)` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern = note: `#[warn(clippy::assign_op_pattern)]` on by default

Check warning on line 67 in crates/enclave/core/src/store/default.rs

View workflow job for this annotation

GitHub Actions / clippy

manual implementation of an assign operation

warning: manual implementation of an assign operation --> crates/enclave/core/src/store/default.rs:67:9 | 67 | self.seq_num = self.seq_num + (count as u64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `self.seq_num += (count as u64)` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern = note: `#[warn(clippy::assign_op_pattern)]` on by default
Ok(prev_seq_num)
}
}
8 changes: 8 additions & 0 deletions crates/enclave/core/src/store/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,12 @@ where
async fn set_nonce(&mut self, nonce: Nonce) -> Result<Option<Nonce>, Self::Error> {
self.inner.write().await.set_nonce(nonce).await
}

async fn get_seq_num(&self) -> Result<u64, Self::Error> {
self.inner.read().await.get_seq_num().await
}

async fn inc_seq_num(&mut self, count: usize) -> Result<u64, Self::Error> {
self.inner.write().await.inc_seq_num(count).await
}
}
29 changes: 27 additions & 2 deletions examples/transfers/enclave/src/request/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ use std::collections::btree_map::Entry;

use cosmwasm_std::{Addr, HexBinary, Uint128};
use quartz_common::enclave::{
handler::Handler, key_manager::KeyManager, proof_of_publication::ProofOfPublication,
store::Store, DefaultSharedEnclave, Enclave,
handler::{ensure_seq_num_consistency, Handler},
key_manager::KeyManager,
proof_of_publication::ProofOfPublication,
store::Store,
DefaultSharedEnclave, Enclave,
};
use serde::{Deserialize, Serialize};
use tonic::Status;
Expand Down Expand Up @@ -65,6 +68,28 @@ impl Handler<DefaultSharedEnclave<()>> for UpdateRequest {
return Err(Status::failed_precondition("proof verification"));
}

// ensure sequence number consistency
// TODO: move this into the core?
let pending_sequenced_requests = message
.requests
.iter()
.filter(|req| matches!(req, TransferRequest::Transfer(_)))
.count();
if pending_sequenced_requests > 0 {
let seq_num = ctx
.store()
.await
.get_seq_num()
.await
.map_err(|_| Status::internal("store read error"))?;
ensure_seq_num_consistency(seq_num, message.seq_num, pending_sequenced_requests)?;
ctx.store()
.await
.inc_seq_num(pending_sequenced_requests)
.await
.map_err(|_| Status::internal("store read error"))?;
}

// Decrypt and deserialize the state
let mut state = match &message.state.to_vec()[..] {
&[0] => State::default(),
Expand Down

0 comments on commit a735160

Please sign in to comment.