Skip to content

Commit 9c402fd

Browse files
authored
Use a Timestamp and Duration newtype throughout the stack (#4368)
no more confusion about whether something is nanos or secs
2 parents 95e1c9d + 98348a4 commit 9c402fd

File tree

57 files changed

+418
-249
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+418
-249
lines changed

Cargo.lock

+6-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cosmwasm/ibc-union/app/ucs00-pingpong/src/msg.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use cosmwasm_schema::cw_serde;
22
use ethabi::{ParamType, Token};
33
use ibc_union_msg::msg::MsgSendPacket;
4-
use ibc_union_spec::{ChannelId, Timestamp};
4+
use ibc_union_spec::{ChannelId, Duration, Timestamp};
55

66
use crate::{state::Config, ContractError};
77

@@ -48,7 +48,8 @@ impl UCS00PingPong {
4848
source_channel_id: source_channel,
4949
timeout_height: 0,
5050
timeout_timestamp: current_timestamp
51-
+ Timestamp::from_secs(config.seconds_before_timeout),
51+
.plus_duration(Duration::from_secs(config.seconds_before_timeout))
52+
.expect("timeout overflow"),
5253
data: counterparty_packet.encode().into(),
5354
})
5455
}

cosmwasm/ibc-union/core/light-client-interface/src/lib.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use ibc_union_msg::lightclient::{
1111
MisbehaviourResponse, QueryMsg, Status, StorageWrites, UpdateStateResponse,
1212
VerifyCreationResponse, VerifyCreationResponseEvent,
1313
};
14-
use ibc_union_spec::ClientId;
14+
use ibc_union_spec::{ClientId, Timestamp};
1515
use unionlabs::{
1616
encoding::{Decode, DecodeAs, DecodeErrorOf, Encode, EncodeAs, Encoding, EthAbi},
1717
primitives::Bytes,
@@ -23,7 +23,8 @@ use crate::{msg::InitMsg, state::IbcHost};
2323
pub mod msg;
2424
pub mod state;
2525

26-
// TODO: Add #[source] to all variants
26+
pub use ibc_union_spec as spec;
27+
2728
#[derive(macros::Debug, thiserror::Error)]
2829
#[debug(bound())]
2930
pub enum DecodeError<T: IbcClient> {
@@ -275,7 +276,7 @@ pub trait IbcClient: Sized + 'static {
275276
) -> Result<(), IbcClientError<Self>>;
276277

277278
/// Get the timestamp
278-
fn get_timestamp(consensus_state: &Self::ConsensusState) -> u64;
279+
fn get_timestamp(consensus_state: &Self::ConsensusState) -> Timestamp;
279280

280281
/// Get the height
281282
fn get_latest_height(client_state: &Self::ClientState) -> u64;

cosmwasm/ibc-union/core/light-client-interface/src/msg.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// TODO: Move this into ibc_union_msg, and then reexport
2+
13
use cosmwasm_std::Addr;
24

35
#[derive(

cosmwasm/ibc-union/lightclient/arbitrum/src/client.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use cosmwasm_std::{Addr, Empty};
33
use ethereum_light_client::client::EthereumLightClient;
44
use ethereum_light_client_types::StorageProof;
55
use ibc_union_light_client::{
6-
ClientCreationResult, IbcClient, IbcClientCtx, IbcClientError, StateUpdate,
6+
spec::Timestamp, ClientCreationResult, IbcClient, IbcClientCtx, IbcClientError, StateUpdate,
77
};
88
use ibc_union_msg::lightclient::Status;
99
use unionlabs::encoding::Bincode;
@@ -86,7 +86,7 @@ impl IbcClient for ArbitrumLightClient {
8686
state_root: header.l2_header.state_root,
8787
ibc_storage_root: header.l2_ibc_account_proof.storage_root,
8888
// must be nanos
89-
timestamp: 1_000_000_000 * header.l2_header.timestamp,
89+
timestamp: Timestamp::from_secs(header.l2_header.timestamp),
9090
};
9191

9292
let new_latest_height = header
@@ -136,7 +136,7 @@ impl IbcClient for ArbitrumLightClient {
136136
Ok(ClientCreationResult::new())
137137
}
138138

139-
fn get_timestamp(consensus_state: &Self::ConsensusState) -> u64 {
139+
fn get_timestamp(consensus_state: &Self::ConsensusState) -> Timestamp {
140140
consensus_state.timestamp
141141
}
142142

cosmwasm/ibc-union/lightclient/berachain/src/client.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use berachain_light_client_types::{ClientState, ConsensusState, Header};
33
use cosmwasm_std::{Addr, Empty};
44
use ethereum_light_client_types::StorageProof;
55
use ibc_union_light_client::{
6-
ClientCreationResult, IbcClient, IbcClientCtx, IbcClientError, StateUpdate,
6+
spec::Timestamp, ClientCreationResult, IbcClient, IbcClientCtx, IbcClientError, StateUpdate,
77
};
88
use ibc_union_msg::lightclient::Status;
99
use tendermint_light_client::client::TendermintLightClient;
@@ -68,7 +68,7 @@ impl IbcClient for BerachainLightClient {
6868
Ok(())
6969
}
7070

71-
fn get_timestamp(consensus_state: &Self::ConsensusState) -> u64 {
71+
fn get_timestamp(consensus_state: &Self::ConsensusState) -> Timestamp {
7272
consensus_state.timestamp
7373
}
7474

@@ -146,7 +146,7 @@ impl IbcClient for BerachainLightClient {
146146
let update_height = header.execution_header.block_number;
147147

148148
let consensus_state = ConsensusState {
149-
timestamp: header.execution_header.timestamp,
149+
timestamp: Timestamp::from_secs(header.execution_header.timestamp),
150150
state_root: header.execution_header.state_root,
151151
storage_root: header.account_proof.storage_root,
152152
};

cosmwasm/ibc-union/lightclient/bob/src/client.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use cosmwasm_std::{Addr, Empty};
44
use ethereum_light_client::client::EthereumLightClient;
55
use ethereum_light_client_types::StorageProof;
66
use ibc_union_light_client::{
7-
ClientCreationResult, IbcClient, IbcClientCtx, IbcClientError, StateUpdate,
7+
spec::Timestamp, ClientCreationResult, IbcClient, IbcClientCtx, IbcClientError, StateUpdate,
88
};
99
use ibc_union_msg::lightclient::Status;
1010
use unionlabs::encoding::Bincode;
@@ -64,7 +64,7 @@ impl IbcClient for BobLightClient {
6464
Ok(())
6565
}
6666

67-
fn get_timestamp(consensus_state: &Self::ConsensusState) -> u64 {
67+
fn get_timestamp(consensus_state: &Self::ConsensusState) -> Timestamp {
6868
consensus_state.timestamp
6969
}
7070

@@ -121,7 +121,7 @@ impl IbcClient for BobLightClient {
121121
let update_height = header.l2_header.number.try_into().expect("impossible");
122122

123123
let consensus_state = ConsensusState {
124-
timestamp: 1_000_000_000 * header.l2_header.timestamp,
124+
timestamp: Timestamp::from_secs(header.l2_header.timestamp),
125125
state_root: header.l2_header.state_root,
126126
ibc_storage_root: header.l2_ibc_account_proof.storage_root,
127127
};

cosmwasm/ibc-union/lightclient/cometbls/src/client.rs

+14-18
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use ibc_union_light_client::{
99
ClientCreationResult, IbcClient, IbcClientCtx, IbcClientError, StateUpdate,
1010
};
1111
use ibc_union_msg::lightclient::Status;
12-
use ibc_union_spec::path::IBC_UNION_COSMWASM_COMMITMENT_PREFIX;
12+
use ibc_union_spec::{path::IBC_UNION_COSMWASM_COMMITMENT_PREFIX, Duration, Timestamp};
1313
use ics23::ibc_api::SDK_SPECS;
1414
use unionlabs::{
1515
encoding::Bincode,
@@ -98,7 +98,7 @@ impl<T: ZkpVerifier> IbcClient for CometblsLightClient<T> {
9898
.map_err(Into::<Error>::into)?)
9999
}
100100

101-
fn get_timestamp(consensus_state: &Self::ConsensusState) -> u64 {
101+
fn get_timestamp(consensus_state: &Self::ConsensusState) -> Timestamp {
102102
consensus_state.timestamp
103103
}
104104

@@ -123,7 +123,7 @@ impl<T: ZkpVerifier> IbcClient for CometblsLightClient<T> {
123123
if is_client_expired(
124124
consensus_state.timestamp,
125125
client_state.trusting_period,
126-
ctx.env.block.time.nanos(),
126+
Timestamp::from_nanos(ctx.env.block.time.nanos()),
127127
) {
128128
return Status::Expired;
129129
}
@@ -203,7 +203,7 @@ fn verify_header<T: ZkpVerifier>(
203203

204204
let trusted_timestamp = consensus_state.timestamp;
205205
// Normalized to nanoseconds to follow tendermint convention
206-
let untrusted_timestamp = header.signed_header.time.as_unix_nanos();
206+
let untrusted_timestamp = Timestamp::from_nanos(header.signed_header.time.as_unix_nanos());
207207

208208
if untrusted_timestamp <= trusted_timestamp {
209209
return Err(InvalidHeaderError::SignedHeaderTimestampMustBeMoreRecent {
@@ -216,23 +216,19 @@ fn verify_header<T: ZkpVerifier>(
216216
if is_client_expired(
217217
trusted_timestamp,
218218
client_state.trusting_period,
219-
ctx.env.block.time.nanos(),
219+
Timestamp::from_nanos(ctx.env.block.time.nanos()),
220220
) {
221221
return Err(InvalidHeaderError::HeaderExpired(consensus_state.timestamp).into());
222222
}
223223

224-
let max_clock_drift = ctx
225-
.env
226-
.block
227-
.time
228-
.nanos()
229-
.checked_add(client_state.max_clock_drift)
224+
let max_clock_drift_timestamp = Timestamp::from_nanos(ctx.env.block.time.nanos())
225+
.plus_duration(client_state.max_clock_drift)
230226
.ok_or(Error::MathOverflow)?;
231227

232-
if untrusted_timestamp >= max_clock_drift {
228+
if untrusted_timestamp >= max_clock_drift_timestamp {
233229
return Err(InvalidHeaderError::SignedHeaderCannotExceedMaxClockDrift {
234230
signed_timestamp: untrusted_timestamp,
235-
max_clock_drift,
231+
max_clock_drift_timestamp,
236232
}
237233
.into());
238234
}
@@ -301,7 +297,7 @@ fn update_state<T: ZkpVerifier>(
301297

302298
consensus_state.next_validators_hash = header.signed_header.next_validators_hash;
303299
// Normalized to nanoseconds to follow tendermint convention
304-
consensus_state.timestamp = header.signed_header.time.as_unix_nanos();
300+
consensus_state.timestamp = Timestamp::from_nanos(header.signed_header.time.as_unix_nanos());
305301

306302
let state_update = StateUpdate::new(untrusted_height.height(), consensus_state);
307303

@@ -314,11 +310,11 @@ fn update_state<T: ZkpVerifier>(
314310
}
315311

316312
fn is_client_expired(
317-
consensus_state_timestamp: u64,
318-
trusting_period: u64,
319-
current_block_time: u64,
313+
consensus_state_timestamp: Timestamp,
314+
trusting_period: Duration,
315+
current_block_time: Timestamp,
320316
) -> bool {
321-
if let Some(sum) = consensus_state_timestamp.checked_add(trusting_period) {
317+
if let Some(sum) = consensus_state_timestamp.plus_duration(trusting_period) {
322318
sum < current_block_time
323319
} else {
324320
true

cosmwasm/ibc-union/lightclient/cometbls/src/errors.rs

+22-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use cosmwasm_std::StdError;
22
use ibc_union_light_client::IbcClientError;
3+
use ibc_union_spec::Timestamp;
34
use unionlabs::{
45
ibc::core::client::height::Height,
56
primitives::{encoding::HexUnprefixed, H256},
@@ -9,24 +10,36 @@ use crate::{client::CometblsLightClient, zkp_verifier::ZkpVerifier};
910

1011
#[derive(thiserror::Error, Debug, Clone, PartialEq)]
1112
pub enum InvalidHeaderError {
12-
#[error("signed header's height ({signed_height}) must be greater than trusted height ({trusted_height})")]
13+
#[error(
14+
"signed header's height ({signed_height}) must be \
15+
greater than trusted height ({trusted_height})"
16+
)]
1317
SignedHeaderHeightMustBeMoreRecent {
1418
signed_height: u64,
1519
trusted_height: u64,
1620
},
17-
#[error("signed header's timestamp ({signed_timestamp}) must be greater than trusted timestamp ({trusted_timestamp})")]
21+
#[error(
22+
"signed header's timestamp ({signed_timestamp}) must be \
23+
greater than trusted timestamp ({trusted_timestamp})"
24+
)]
1825
SignedHeaderTimestampMustBeMoreRecent {
19-
signed_timestamp: u64,
20-
trusted_timestamp: u64,
26+
signed_timestamp: Timestamp,
27+
trusted_timestamp: Timestamp,
2128
},
2229
#[error("header with timestamp ({0}) is expired")]
23-
HeaderExpired(u64),
24-
#[error("signed header timestamp ({signed_timestamp}) cannot exceed the max clock drift ({max_clock_drift})")]
30+
HeaderExpired(Timestamp),
31+
#[error(
32+
"signed header timestamp ({signed_timestamp}) cannot \
33+
exceed the max clock drift ({max_clock_drift_timestamp})"
34+
)]
2535
SignedHeaderCannotExceedMaxClockDrift {
26-
signed_timestamp: u64,
27-
max_clock_drift: u64,
36+
signed_timestamp: Timestamp,
37+
max_clock_drift_timestamp: Timestamp,
2838
},
29-
#[error("the validators hash ({actual}) doesn't match the trusted validators hash ({expected}) for an adjacent block")]
39+
#[error(
40+
"the validators hash ({actual}) doesn't match the trusted \
41+
validators hash ({expected}) for an adjacent block"
42+
)]
3043
InvalidValidatorsHash {
3144
expected: H256<HexUnprefixed>,
3245
actual: H256<HexUnprefixed>,

0 commit comments

Comments
 (0)