Skip to content

Commit a3248f9

Browse files
authored
fix(relayer): use starknet block timestamp (#244)
* use starknet block timestamp * use ibc-rs timestamp * refactor for timestamp * src chan id is of a * avoid using expect in hermes components * fix error message * avoid expect in relayer comps
1 parent 76a83f4 commit a3248f9

File tree

10 files changed

+69
-56
lines changed

10 files changed

+69
-56
lines changed

relayer/crates/starknet-chain-components/src/impls/events/send_packet.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use ibc::core::channel::types::packet::Packet;
2020
use ibc::core::channel::types::timeout::{TimeoutHeight, TimeoutTimestamp};
2121
use ibc::core::client::types::Height;
2222
use ibc::core::host::types::error::{DecodingError, IdentifierError};
23-
use ibc::primitives::Timestamp;
2423
use starknet::core::types::Felt;
2524

2625
use crate::impls::events::UseStarknetEvents;
@@ -57,13 +56,11 @@ where
5756
.map(TimeoutHeight::At)
5857
.unwrap_or_else(|_| TimeoutHeight::Never);
5958

60-
let timeout_timestamp_on_b = (event.timeout_timestamp_on_b.timestamp > 0)
61-
.then(|| {
62-
TimeoutTimestamp::At(Timestamp::from_nanoseconds(
63-
event.timeout_timestamp_on_b.timestamp * 1_000_000_000,
64-
))
65-
})
66-
.unwrap_or(TimeoutTimestamp::Never);
59+
let timeout_timestamp_on_b = if event.timeout_timestamp_on_b.nanoseconds() > 0 {
60+
TimeoutTimestamp::At(event.timeout_timestamp_on_b)
61+
} else {
62+
TimeoutTimestamp::Never
63+
};
6764

6865
/*
6966
FIXME: the packet data format in Cairo is incompatible with the packet data on Cosmos.

relayer/crates/starknet-chain-components/src/impls/packet_fields.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ where
1414
+ HasChannelIdType<Counterparty, ChannelId = ChannelId>,
1515
{
1616
fn packet_src_channel_id(packet: &Packet) -> ChannelId {
17-
packet.chan_id_on_b.clone()
17+
packet.chan_id_on_a.clone()
1818
}
1919
}

relayer/crates/starknet-chain-components/src/impls/payload_builders/create_client.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ where
2727
> + HasCreateClientPayloadType<Counterparty, CreateClientPayload = StarknetCreateClientPayload>
2828
+ CanQueryChainStatus<ChainStatus = StarknetChainStatus>
2929
+ HasChainId<ChainId = ChainId>
30+
+ CanRaiseAsyncError<&'static str>
3031
+ CanRaiseAsyncError<ClientError>,
3132
{
3233
async fn build_create_client_payload(
@@ -40,7 +41,10 @@ where
4041
let consensus_state = WasmStarknetConsensusState {
4142
consensus_state: StarknetConsensusState {
4243
root: root.into(),
43-
time: Timestamp::now(),
44+
time: u64::try_from(chain_status.time.unix_timestamp_nanos())
45+
.ok()
46+
.map(Timestamp::from_nanoseconds)
47+
.ok_or_else(|| Chain::raise_error("invalid timestamp"))?,
4448
},
4549
};
4650

relayer/crates/starknet-chain-components/src/impls/payload_builders/update_client.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,20 @@ where
4040
.await
4141
.map_err(Chain::raise_error)?;
4242

43-
let block_hash = match block_info {
44-
MaybePendingBlockWithTxHashes::Block(block) => block.block_hash,
43+
let block = match block_info {
44+
MaybePendingBlockWithTxHashes::Block(block) => block,
4545
MaybePendingBlockWithTxHashes::PendingBlock(_block) => {
4646
return Err(Chain::raise_error("pending block is not supported"))
4747
}
4848
};
4949

50+
let block_hash = block.block_hash;
51+
5052
let root = Vec::from(block_hash.to_bytes_be());
5153

5254
let consensus_state = StarknetConsensusState {
5355
root: root.into(),
54-
time: Timestamp::now(),
56+
time: Timestamp::from_nanoseconds(block.timestamp * 1_000_000_000),
5557
};
5658

5759
let height = Height::new(0, *target_height).unwrap();

relayer/crates/starknet-chain-components/src/impls/queries/client_state.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ where
3737
+ HasBlobType<Blob = Vec<Felt>>
3838
+ HasEncoding<AsFelt, Encoding = Encoding>
3939
+ CanQueryContractAddress<symbol!("ibc_client_contract_address")>
40+
+ CanRaiseAsyncError<&'static str>
4041
+ CanRaiseAsyncError<Encoding::Error>,
4142
Counterparty: HasClientStateType<Chain, ClientState = CometClientState>,
4243
Encoding: CanEncode<ViaCairo, u64>
@@ -57,10 +58,10 @@ where
5758
let client_id_seq = client_id
5859
.as_str()
5960
.rsplit_once('-')
60-
.expect("valid client id")
61+
.ok_or_else(|| Chain::raise_error("invalid client id"))?
6162
.1
6263
.parse::<u64>()
63-
.expect("valid sequence");
64+
.map_err(|_| Chain::raise_error("invalid sequence"))?;
6465

6566
let calldata = encoding
6667
.encode(&client_id_seq)

relayer/crates/starknet-chain-components/src/impls/queries/consensus_state.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ where
4545
+ HasEncoding<AsFelt, Encoding = Encoding>
4646
+ CanQueryContractAddress<symbol!("ibc_client_contract_address")>
4747
+ CanRaiseAsyncError<ConsensusStateNotFound>
48+
+ CanRaiseAsyncError<&'static str>
4849
+ CanRaiseAsyncError<Encoding::Error>,
4950
Counterparty:
5051
HasConsensusStateType<Chain, ConsensusState = CometConsensusState> + HasHeightFields,
@@ -72,10 +73,10 @@ where
7273
let client_id_seq = client_id
7374
.as_str()
7475
.rsplit_once('-')
75-
.expect("valid client id")
76+
.ok_or_else(|| Chain::raise_error("invalid client id"))?
7677
.1
7778
.parse::<u64>()
78-
.expect("valid sequence");
79+
.map_err(|_| Chain::raise_error("invalid sequence"))?;
7980

8081
let calldata = encoding
8182
.encode(&(client_id_seq, height.clone()))

relayer/crates/starknet-chain-components/src/impls/queries/status.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ where
2828
MaybePendingBlockWithTxHashes::Block(block) => Ok(StarknetChainStatus {
2929
height: block.block_number,
3030
block_hash: block.block_hash,
31-
time: Time::now(),
31+
time: i64::try_from(block.timestamp)
32+
.ok()
33+
.and_then(|ts| Time::from_unix_timestamp(ts, 0).ok())
34+
.ok_or_else(|| Chain::raise_error("invalid timestamp"))?,
3235
}),
3336
MaybePendingBlockWithTxHashes::PendingBlock(_) => Err(Chain::raise_error(
3437
"expected finalized block, but given pending block",

relayer/crates/starknet-chain-components/src/types/client_id.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,23 @@ pub struct EncodeClientId;
1010

1111
impl<Encoding, Strategy> MutEncoder<Encoding, Strategy, ClientId> for EncodeClientId
1212
where
13-
Encoding: CanEncodeMut<Strategy, Product![Felt, u64]>,
13+
Encoding: CanEncodeMut<Strategy, Product![Felt, u64]> + CanRaiseError<&'static str>,
1414
{
1515
fn encode_mut(
1616
encoding: &Encoding,
1717
value: &ClientId,
1818
buffer: &mut Encoding::EncodeBuffer,
1919
) -> Result<(), Encoding::Error> {
2020
// FIXME: add `sequence_number` method at `ibc-rs`
21-
let (client_type, sequence) = value.as_str().rsplit_once('-').expect("valid client id");
22-
let seq_u64 = sequence.parse::<u64>().expect("valid sequence");
23-
let client_type_felt = string_to_felt(client_type).expect("valid client type");
21+
let (client_type, sequence) = value
22+
.as_str()
23+
.rsplit_once('-')
24+
.ok_or_else(|| Encoding::raise_error("invalid client id"))?;
25+
let seq_u64 = sequence
26+
.parse::<u64>()
27+
.map_err(|_| Encoding::raise_error("invalid sequence"))?;
28+
let client_type_felt = string_to_felt(client_type)
29+
.ok_or_else(|| Encoding::raise_error("invalid client type"))?;
2430
encoding.encode_mut(&product![client_type_felt, seq_u64], buffer)?;
2531
Ok(())
2632
}
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,34 @@
1-
use cgp::core::component::UseContext;
21
use cgp::prelude::*;
3-
use hermes_encoding_components::impls::encode_mut::combine::CombineEncoders;
4-
use hermes_encoding_components::impls::encode_mut::field::EncodeField;
5-
use hermes_encoding_components::impls::encode_mut::from::DecodeFrom;
6-
use hermes_encoding_components::traits::decode_mut::MutDecoderComponent;
7-
use hermes_encoding_components::traits::encode_mut::MutEncoderComponent;
8-
use hermes_encoding_components::traits::transform::Transformer;
9-
10-
#[derive(Debug, Clone, HasField)]
11-
pub struct Timestamp {
12-
pub timestamp: u64,
13-
}
2+
use hermes_encoding_components::traits::decode_mut::{CanDecodeMut, MutDecoder};
3+
use hermes_encoding_components::traits::encode_mut::{CanEncodeMut, MutEncoder};
4+
pub use ibc::primitives::Timestamp;
145

156
pub struct EncodeTimestamp;
167

17-
delegate_components! {
18-
EncodeTimestamp {
19-
MutEncoderComponent: CombineEncoders<
20-
Product![
21-
EncodeField<symbol!("timestamp"), UseContext>,
22-
],
23-
>,
24-
MutDecoderComponent: DecodeFrom<Self, UseContext>,
8+
impl<Encoding, Strategy> MutEncoder<Encoding, Strategy, Timestamp> for EncodeTimestamp
9+
where
10+
Encoding: CanEncodeMut<Strategy, Product![u64]>,
11+
{
12+
fn encode_mut(
13+
encoding: &Encoding,
14+
value: &Timestamp,
15+
buffer: &mut Encoding::EncodeBuffer,
16+
) -> Result<(), Encoding::Error> {
17+
let unix_secs = value.nanoseconds() / 1_000_000_000;
18+
encoding.encode_mut(&product![unix_secs], buffer)?;
19+
Ok(())
2520
}
2621
}
2722

28-
impl Transformer for EncodeTimestamp {
29-
type From = u64;
30-
type To = Timestamp;
31-
32-
fn transform(timestamp: Self::From) -> Timestamp {
33-
Timestamp { timestamp }
23+
impl<Encoding, Strategy> MutDecoder<Encoding, Strategy, Timestamp> for EncodeTimestamp
24+
where
25+
Encoding: CanDecodeMut<Strategy, Product![u64]>,
26+
{
27+
fn decode_mut<'a>(
28+
encoding: &Encoding,
29+
buffer: &mut Encoding::DecodeBuffer<'a>,
30+
) -> Result<Timestamp, Encoding::Error> {
31+
let product![unix_secs] = encoding.decode_mut(buffer)?;
32+
Ok(Timestamp::from_nanoseconds(unix_secs * 1_000_000_000))
3433
}
3534
}

relayer/crates/starknet-integration-tests/src/tests/ics20.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -536,10 +536,10 @@ fn test_starknet_ics20_contract() -> Result<(), Error> {
536536
revision_number: 0,
537537
revision_height: 0,
538538
},
539-
timeout_timestamp_on_b: Timestamp {
540-
timestamp: u64::try_from(current_starknet_time.unix_timestamp()).unwrap()
541-
+ 1800,
542-
},
539+
timeout_timestamp_on_b: Timestamp::from_nanoseconds(
540+
u64::try_from(current_starknet_time.unix_timestamp() + 1800).unwrap()
541+
* 1_000_000_000,
542+
),
543543
}
544544
};
545545

@@ -628,10 +628,10 @@ fn test_starknet_ics20_contract() -> Result<(), Error> {
628628
revision_number: 0,
629629
revision_height: 0,
630630
},
631-
timeout_timestamp_on_b: Timestamp {
632-
timestamp: u64::try_from(current_starknet_time.unix_timestamp()).unwrap()
633-
+ 1800,
634-
},
631+
timeout_timestamp_on_b: Timestamp::from_nanoseconds(
632+
u64::try_from(current_starknet_time.unix_timestamp() + 1800).unwrap()
633+
* 1_000_000_000,
634+
),
635635
}
636636
};
637637

0 commit comments

Comments
 (0)