Skip to content

Commit bbc8b8a

Browse files
authored
feat: add sequence number for replay protection (#252)
1 parent ea08f47 commit bbc8b8a

File tree

17 files changed

+171
-198
lines changed

17 files changed

+171
-198
lines changed

Cargo.lock

Lines changed: 12 additions & 100 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/contracts/core/src/handler/execute.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod attested;
2+
pub mod sequenced;
23
pub mod session_create;
34
pub mod session_set_pub_key;
45

crates/contracts/core/src/handler/execute/attested.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ use crate::{
1414
error::Error,
1515
handler::Handler,
1616
msg::execute::attested::{
17-
Attestation, Attested, AttestedMsgSansHandler, DcapAttestation, HasUserData,
18-
MockAttestation, Quote,
17+
Attestation, Attested, DcapAttestation, HasUserData, MockAttestation, MsgSansHandler, Quote,
1918
},
2019
state::CONFIG,
2120
};
@@ -181,7 +180,7 @@ where
181180
}
182181
}
183182

184-
impl<T> Handler for AttestedMsgSansHandler<T> {
183+
impl<T> Handler for MsgSansHandler<T> {
185184
fn handle(
186185
self,
187186
_deps: DepsMut<'_>,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response, StdResult, Uint64};
2+
3+
use crate::{
4+
error::Error, handler::Handler, msg::execute::sequenced::SequencedMsg, state::SEQUENCE_NUM,
5+
};
6+
7+
impl<T: Handler> Handler for SequencedMsg<T> {
8+
fn handle(self, deps: DepsMut<'_>, env: &Env, info: &MessageInfo) -> Result<Response, Error> {
9+
SEQUENCE_NUM.update(deps.storage, |mut counter| -> StdResult<_> {
10+
counter += Uint64::one();
11+
Ok(counter)
12+
})?;
13+
14+
self.0.handle(deps, env, info)
15+
}
16+
}

crates/contracts/core/src/handler/execute/session_set_pub_key.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
1-
use cosmwasm_std::{DepsMut, Env, HexBinary, MessageInfo, Response};
1+
use cosmwasm_std::{DepsMut, Env, HexBinary, MessageInfo, Response, Uint64};
22

33
use crate::{
4-
error::Error, handler::Handler, msg::execute::session_set_pub_key::SessionSetPubKey,
5-
state::SESSION,
4+
error::Error,
5+
handler::Handler,
6+
msg::execute::session_set_pub_key::SessionSetPubKey,
7+
state::{SEQUENCE_NUM, SESSION},
68
};
79

810
impl Handler for SessionSetPubKey {
911
fn handle(self, deps: DepsMut<'_>, _env: &Env, _info: &MessageInfo) -> Result<Response, Error> {
1012
let session = SESSION.load(deps.storage).map_err(Error::Std)?;
1113
let (nonce, pub_key) = self.into_tuple();
14+
1215
let session = session
1316
.with_pub_key(nonce, pub_key)
1417
.ok_or(Error::BadSessionTransition)?;
15-
1618
SESSION.save(deps.storage, &session).map_err(Error::Std)?;
1719

20+
let sequence_num = Uint64::new(0);
21+
SEQUENCE_NUM
22+
.save(deps.storage, &sequence_num)
23+
.map_err(Error::Std)?;
24+
1825
Ok(Response::new()
1926
.add_attribute("action", "session_set_pub_key")
2027
.add_attribute(

crates/contracts/core/src/msg/execute.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod attested;
2+
pub mod sequenced;
23
pub mod session_create;
34
pub mod session_set_pub_key;
45

crates/contracts/core/src/msg/execute/attested.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -222,16 +222,16 @@ impl Attestation for MockAttestation {
222222
}
223223

224224
#[derive(Clone, Debug, PartialEq)]
225-
pub struct AttestedMsgSansHandler<T>(pub T);
225+
pub struct MsgSansHandler<T>(pub T);
226226

227227
#[cw_serde]
228-
pub struct RawAttestedMsgSansHandler<T>(pub T);
228+
pub struct RawMsgSansHandler<T>(pub T);
229229

230-
impl<T: Serialize> HasDomainType for RawAttestedMsgSansHandler<T> {
231-
type DomainType = AttestedMsgSansHandler<T>;
230+
impl<T: Serialize> HasDomainType for RawMsgSansHandler<T> {
231+
type DomainType = MsgSansHandler<T>;
232232
}
233233

234-
impl<T> HasUserData for AttestedMsgSansHandler<T>
234+
impl<T> HasUserData for MsgSansHandler<T>
235235
where
236236
T: HasUserData,
237237
{
@@ -240,16 +240,16 @@ where
240240
}
241241
}
242242

243-
impl<T> TryFrom<RawAttestedMsgSansHandler<T>> for AttestedMsgSansHandler<T> {
243+
impl<T> TryFrom<RawMsgSansHandler<T>> for MsgSansHandler<T> {
244244
type Error = StdError;
245245

246-
fn try_from(value: RawAttestedMsgSansHandler<T>) -> Result<Self, Self::Error> {
246+
fn try_from(value: RawMsgSansHandler<T>) -> Result<Self, Self::Error> {
247247
Ok(Self(value.0))
248248
}
249249
}
250250

251-
impl<T> From<AttestedMsgSansHandler<T>> for RawAttestedMsgSansHandler<T> {
252-
fn from(value: AttestedMsgSansHandler<T>) -> Self {
251+
impl<T> From<MsgSansHandler<T>> for RawMsgSansHandler<T> {
252+
fn from(value: MsgSansHandler<T>) -> Self {
253253
Self(value.0)
254254
}
255255
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use cosmwasm_schema::cw_serde;
2+
use cosmwasm_std::StdError;
3+
use serde::Serialize;
4+
5+
use crate::msg::HasDomainType;
6+
7+
#[derive(Clone, Debug, PartialEq)]
8+
pub struct SequencedMsg<D>(pub D);
9+
10+
#[cw_serde]
11+
pub struct RawSequencedMsg<R>(pub R);
12+
13+
impl<R: Serialize + HasDomainType> HasDomainType for RawSequencedMsg<R> {
14+
type DomainType = SequencedMsg<R::DomainType>;
15+
}
16+
17+
impl<R: HasDomainType> TryFrom<RawSequencedMsg<R>> for SequencedMsg<R::DomainType> {
18+
type Error = StdError;
19+
20+
fn try_from(value: RawSequencedMsg<R>) -> Result<Self, Self::Error> {
21+
Ok(Self(value.0.try_into()?))
22+
}
23+
}
24+
25+
impl<R: HasDomainType> From<SequencedMsg<R::DomainType>> for RawSequencedMsg<R> {
26+
fn from(value: SequencedMsg<R::DomainType>) -> Self {
27+
Self(value.0.into())
28+
}
29+
}

crates/contracts/core/src/state.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ pub type TrustThreshold = (u64, u64);
1515
pub const CONFIG_KEY: &str = "quartz_config";
1616
pub const SESSION_KEY: &str = "quartz_session";
1717
pub const EPOCH_COUNTER_KEY: &str = "epoch_counter";
18+
pub const SEQUENCE_NUM_KEY: &str = "quartz_seq_num";
1819
pub const CONFIG: Item<RawConfig> = Item::new(CONFIG_KEY);
1920
pub const SESSION: Item<Session> = Item::new(SESSION_KEY);
2021
pub const EPOCH_COUNTER: Item<Uint64> = Item::new(EPOCH_COUNTER_KEY);
22+
pub const SEQUENCE_NUM: Item<Uint64> = Item::new(SEQUENCE_NUM_KEY);
2123

2224
#[derive(Clone, Debug, PartialEq)]
2325
pub struct Config {

crates/utils/cw-client/Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,3 @@ tonic.workspace = true
3131
cosmrs = { workspace = true, default-features = false, features = ["cosmwasm"] }
3232
cosmos-sdk-proto = { workspace = true, default-features = false, features = ["grpc", "grpc-transport"] }
3333
tendermint = { workspace = true, default-features = false }
34-
35-
[dev-dependencies]
36-
tokio.workspace = true
37-
transfers-contract = { path = "../../../examples/transfers/contracts" }

crates/utils/cw-client/src/cli.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ impl CwClient for CliClient {
106106
Ok(query_result)
107107
}
108108

109-
fn query_raw<R: DeserializeOwned + Default>(
109+
async fn query_raw<R: DeserializeOwned + Default>(
110110
&self,
111111
contract: &Self::Address,
112112
query: Self::RawQuery,

0 commit comments

Comments
 (0)