From 93e73c547458bc4ef2b08200faa36687832a4f4e Mon Sep 17 00:00:00 2001 From: Davirain Date: Thu, 20 Apr 2023 17:20:17 +0800 Subject: [PATCH 01/35] Add solo machine client state and consensus state along with header and misbehavior. --- .../clients/ics06_solomachine/client_state.rs | 75 +++++++++++++++++++ .../ics06_solomachine/consensus_state.rs | 1 + .../src/clients/ics06_solomachine/error.rs | 28 +++++++ .../src/clients/ics06_solomachine/header.rs | 1 + .../clients/ics06_solomachine/misbehaviour.rs | 1 + .../ibc/src/clients/ics06_solomachine/mod.rs | 5 ++ crates/ibc/src/clients/mod.rs | 1 + crates/ibc/src/lib.rs | 2 +- 8 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 crates/ibc/src/clients/ics06_solomachine/client_state.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/consensus_state.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/error.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/header.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/mod.rs diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs new file mode 100644 index 000000000..32a043299 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -0,0 +1,75 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::core::ics02_client::error::ClientError; +use crate::prelude::*; +use ibc_proto::google::protobuf::Any; +use ibc_proto::ibc::lightclients::solomachine::v1::ClientState as RawSolClientState; +use ibc_proto::protobuf::Protobuf; +use prost::Message; + +pub const SOLOMACHINE_CLIENT_STATE_TYPE_URL: &str = "/ibc.lightclients.solomachine.v1.ClientState"; + +/// ClientState defines a solo machine client that tracks the current consensus +/// state and if the client is frozen. +#[derive(Clone, PartialEq)] +pub struct ClientState { + /// latest sequence of the client state + pub sequence: u64, + /// frozen sequence of the solo machine + pub frozen_sequence: u64, + // pub consensus_state: ::core::option::Option, + /// when set to true, will allow governance to update a solo machine client. + /// The client will be unfrozen if it is frozen. + pub allow_update_after_proposal: bool, +} + +impl Protobuf for ClientState {} + +impl TryFrom for ClientState { + type Error = Error; + + fn try_from(raw: RawSolClientState) -> Result { + todo!() + } +} + +impl From for RawSolClientState { + fn from(value: ClientState) -> Self { + todo!() + } +} + +impl Protobuf for ClientState {} + +impl TryFrom for ClientState { + type Error = ClientError; + + fn try_from(raw: Any) -> Result { + use bytes::Buf; + use core::ops::Deref; + + fn decode_client_state(buf: B) -> Result { + RawSolClientState::decode(buf) + .map_err(Error::Decode)? + .try_into() + } + + match raw.type_url.as_str() { + SOLOMACHINE_CLIENT_STATE_TYPE_URL => { + decode_client_state(raw.value.deref()).map_err(Into::into) + } + _ => Err(ClientError::UnknownClientStateType { + client_state_type: raw.type_url, + }), + } + } +} + +impl From for Any { + fn from(client_state: ClientState) -> Self { + Any { + type_url: SOLOMACHINE_CLIENT_STATE_TYPE_URL.to_string(), + value: Protobuf::::encode_vec(&client_state) + .expect("encoding to `Any` from `TmClientState`"), + } + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs @@ -0,0 +1 @@ + diff --git a/crates/ibc/src/clients/ics06_solomachine/error.rs b/crates/ibc/src/clients/ics06_solomachine/error.rs new file mode 100644 index 000000000..69c08cb99 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/error.rs @@ -0,0 +1,28 @@ +use crate::prelude::*; + +use crate::core::ics02_client::error::ClientError; +use crate::core::ics24_host::identifier::{ChainId, ClientId}; +use crate::Height; +use core::time::Duration; + +use displaydoc::Display; + +#[derive(Debug, Display)] +pub enum Error { + /// dummy error + Dummy, + /// decode error: `{0}` + Decode(prost::DecodeError), +} + +impl From for ClientError { + fn from(e: Error) -> Self { + Self::ClientSpecific { + description: e.to_string(), + } + } +} + +pub(crate) trait IntoResult { + fn into_result(self) -> Result; +} diff --git a/crates/ibc/src/clients/ics06_solomachine/header.rs b/crates/ibc/src/clients/ics06_solomachine/header.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/header.rs @@ -0,0 +1 @@ + diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs @@ -0,0 +1 @@ + diff --git a/crates/ibc/src/clients/ics06_solomachine/mod.rs b/crates/ibc/src/clients/ics06_solomachine/mod.rs new file mode 100644 index 000000000..acf45238c --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/mod.rs @@ -0,0 +1,5 @@ +pub mod client_state; +pub mod consensus_state; +pub mod error; +pub mod header; +pub mod misbehaviour; diff --git a/crates/ibc/src/clients/mod.rs b/crates/ibc/src/clients/mod.rs index 65ea910b1..b8be6f723 100644 --- a/crates/ibc/src/clients/mod.rs +++ b/crates/ibc/src/clients/mod.rs @@ -1,3 +1,4 @@ //! Implementations of client verification algorithms for specific types of chains. +pub mod ics06_solomachine; pub mod ics07_tendermint; diff --git a/crates/ibc/src/lib.rs b/crates/ibc/src/lib.rs index ff8f36ad4..a847be08f 100644 --- a/crates/ibc/src/lib.rs +++ b/crates/ibc/src/lib.rs @@ -3,7 +3,7 @@ // #![cfg_attr(not(test), deny(clippy::unwrap_used))] #![no_std] #![deny( - warnings, + // warnings, trivial_casts, trivial_numeric_casts, unused_import_braces, From f49f128e3b5513bf9fac3bbd2a25e4db89b06bc9 Mon Sep 17 00:00:00 2001 From: Davirain Date: Thu, 20 Apr 2023 17:25:01 +0800 Subject: [PATCH 02/35] Add consensus state to solo machine client state --- .../clients/ics06_solomachine/client_state.rs | 3 +- .../ics06_solomachine/consensus_state.rs | 75 +++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index 32a043299..a7e2d29a9 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -1,3 +1,4 @@ +use crate::clients::ics06_solomachine::consensus_state::ConsensusState; use crate::clients::ics06_solomachine::error::Error; use crate::core::ics02_client::error::ClientError; use crate::prelude::*; @@ -16,7 +17,7 @@ pub struct ClientState { pub sequence: u64, /// frozen sequence of the solo machine pub frozen_sequence: u64, - // pub consensus_state: ::core::option::Option, + pub consensus_state: Option, /// when set to true, will allow governance to update a solo machine client. /// The client will be unfrozen if it is frozen. pub allow_update_after_proposal: bool, diff --git a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs index 8b1378917..8924e6ea5 100644 --- a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs @@ -1 +1,76 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::core::ics02_client::error::ClientError; +use crate::prelude::*; +use ibc_proto::google::protobuf::Any; +use ibc_proto::ibc::lightclients::solomachine::v1::ConsensusState as RawSolConsensusState; +use ibc_proto::protobuf::Protobuf; +use prost::Message; +pub const SOLOMACHINE_CONSENSUS_STATE_TYPE_URL: &str = + "/ibc.lightclients.solomachine.v1.ConsensusState"; + +/// ConsensusState defines a solo machine consensus state. The sequence of a +/// consensus state is contained in the "height" key used in storing the +/// consensus state. +#[derive(Clone, PartialEq)] +pub struct ConsensusState { + /// public key of the solo machine + pub public_key: Option, + /// diversifier allows the same public key to be re-used across different solo + /// machine clients (potentially on different chains) without being considered + /// misbehaviour. + pub diversifier: ::prost::alloc::string::String, + pub timestamp: u64, +} + +impl Protobuf for ConsensusState {} + +impl TryFrom for ConsensusState { + type Error = Error; + + fn try_from(raw: RawSolConsensusState) -> Result { + todo!() + } +} + +impl From for RawSolConsensusState { + fn from(value: ConsensusState) -> Self { + todo!() + } +} + +impl Protobuf for ConsensusState {} + +impl TryFrom for ConsensusState { + type Error = ClientError; + + fn try_from(raw: Any) -> Result { + use bytes::Buf; + use core::ops::Deref; + + fn decode_consensus_state(buf: B) -> Result { + RawSolConsensusState::decode(buf) + .map_err(Error::Decode)? + .try_into() + } + + match raw.type_url.as_str() { + SOLOMACHINE_CONSENSUS_STATE_TYPE_URL => { + decode_consensus_state(raw.value.deref()).map_err(Into::into) + } + _ => Err(ClientError::UnknownConsensusStateType { + consensus_state_type: raw.type_url, + }), + } + } +} + +impl From for Any { + fn from(consensus_state: ConsensusState) -> Self { + Any { + type_url: SOLOMACHINE_CONSENSUS_STATE_TYPE_URL.to_string(), + value: Protobuf::::encode_vec(&consensus_state) + .expect("encoding to `Any` from `TmConsensusState`"), + } + } +} From 61021f65e87907fd5abd9193f2a794ad5c986c58 Mon Sep 17 00:00:00 2001 From: Davirain Date: Thu, 20 Apr 2023 17:28:50 +0800 Subject: [PATCH 03/35] Add Solo Machine consensus header type and decoding, encoding methods. --- .../src/clients/ics06_solomachine/header.rs | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/crates/ibc/src/clients/ics06_solomachine/header.rs b/crates/ibc/src/clients/ics06_solomachine/header.rs index 8b1378917..cc43f4d72 100644 --- a/crates/ibc/src/clients/ics06_solomachine/header.rs +++ b/crates/ibc/src/clients/ics06_solomachine/header.rs @@ -1 +1,68 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::core::ics02_client::error::ClientError; +use crate::prelude::*; +use bytes::Buf; +use ibc_proto::google::protobuf::Any; +use ibc_proto::ibc::lightclients::solomachine::v1::Header as RawSolHeader; +use ibc_proto::protobuf::Protobuf; +use prost::Message; +pub const SOLOMACHINE_HEADER_TYPE_URL: &str = "/ibc.lightclients.solomachine.v1.Header"; + +/// Header defines a solo machine consensus header +#[derive(Clone, PartialEq)] +pub struct Header { + /// sequence to update solo machine public key at + pub sequence: u64, + pub timestamp: u64, + pub signature: Vec, + pub new_public_key: Option, + pub new_diversifier: String, +} + +impl Protobuf for Header {} + +impl TryFrom for Header { + type Error = Error; + + fn try_from(raw: RawSolHeader) -> Result { + todo!() + } +} + +impl Protobuf for Header {} + +impl TryFrom for Header { + type Error = ClientError; + + fn try_from(raw: Any) -> Result { + use core::ops::Deref; + + match raw.type_url.as_str() { + SOLOMACHINE_HEADER_TYPE_URL => decode_header(raw.value.deref()).map_err(Into::into), + _ => Err(ClientError::UnknownHeaderType { + header_type: raw.type_url, + }), + } + } +} + +impl From
for Any { + fn from(header: Header) -> Self { + Any { + type_url: SOLOMACHINE_HEADER_TYPE_URL.to_string(), + value: Protobuf::::encode_vec(&header) + .expect("encoding to `Any` from `TmHeader`"), + } + } +} + +pub fn decode_header(buf: B) -> Result { + RawSolHeader::decode(buf).map_err(Error::Decode)?.try_into() +} + +impl From
for RawSolHeader { + fn from(value: Header) -> Self { + todo!() + } +} From dbaf5693c7c822706a0b3a8097977235ad89bfd1 Mon Sep 17 00:00:00 2001 From: Davirain Date: Thu, 20 Apr 2023 18:29:48 +0800 Subject: [PATCH 04/35] Update ICS06 solo machine to use `RawSol` prefix and add `DataType` enum. --- .../clients/ics06_solomachine/client_state.rs | 2 +- .../ics06_solomachine/consensus_state.rs | 2 +- .../clients/ics06_solomachine/data_type.rs | 43 +++++++++ .../clients/ics06_solomachine/misbehaviour.rs | 87 +++++++++++++++++++ .../misbehaviour/signature_and_data.rs | 31 +++++++ .../ibc/src/clients/ics06_solomachine/mod.rs | 1 + 6 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 crates/ibc/src/clients/ics06_solomachine/data_type.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index a7e2d29a9..c8b6ee4b8 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -70,7 +70,7 @@ impl From for Any { Any { type_url: SOLOMACHINE_CLIENT_STATE_TYPE_URL.to_string(), value: Protobuf::::encode_vec(&client_state) - .expect("encoding to `Any` from `TmClientState`"), + .expect("encoding to `Any` from `RawSolClientState`"), } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs index 8924e6ea5..0cc9fd36c 100644 --- a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs @@ -70,7 +70,7 @@ impl From for Any { Any { type_url: SOLOMACHINE_CONSENSUS_STATE_TYPE_URL.to_string(), value: Protobuf::::encode_vec(&consensus_state) - .expect("encoding to `Any` from `TmConsensusState`"), + .expect("encoding to `Any` from `RawSolConsensusState`"), } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/data_type.rs b/crates/ibc/src/clients/ics06_solomachine/data_type.rs new file mode 100644 index 000000000..d2f729174 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/data_type.rs @@ -0,0 +1,43 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::prelude::*; +use ibc_proto::ibc::lightclients::solomachine::v1::DataType as RawDataType; + +/// DataType defines the type of solo machine proof being created. This is done +/// to preserve uniqueness of different data sign byte encodings. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum DataType { + /// Default State + UninitializedUnspecified, + /// Data type for client state verification + ClientState, + /// Data type for consensus state verification + ConsensusState, + /// Data type for connection state verification + ConnectionState, + /// Data type for channel state verification + ChannelState, + /// Data type for packet commitment verification + PacketCommitment, + /// Data type for packet acknowledgement verification + PacketAcknowledgement, + /// Data type for packet receipt absence verification + PacketReceiptAbsence, + /// Data type for next sequence recv verification + NextSequenceRecv, + /// Data type for header verification + Header, +} + +impl TryFrom for DataType { + type Error = Error; + + fn try_from(raw: RawDataType) -> Result { + todo!() + } +} + +impl From for RawDataType { + fn from(value: DataType) -> Self { + todo!() + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs index 8b1378917..bbfd07d4c 100644 --- a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs @@ -1 +1,88 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::core::ics02_client::error::ClientError; +use crate::prelude::*; +use bytes::Buf; +use ibc_proto::google::protobuf::Any; +use ibc_proto::ibc::lightclients::solomachine::v1::Misbehaviour as RawSolMisbehaviour; +use ibc_proto::protobuf::Protobuf; +use prost::Message; +pub mod signature_and_data; + +use signature_and_data::SignatureAndData; + +pub const SOLOMACHINE_MISBEHAVIOUR_TYPE_URL: &str = "/ibc.lightclients.solomachine.v1.Misbehaviour"; + +/// Misbehaviour defines misbehaviour for a solo machine which consists +/// of a sequence and two signatures over different messages at that sequence. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq)] +pub struct Misbehaviour { + pub client_id: String, + pub sequence: u64, + pub signature_one: Option, + pub signature_two: Option, +} + +impl Protobuf for Misbehaviour {} + +impl TryFrom for Misbehaviour { + type Error = Error; + + fn try_from(raw: RawSolMisbehaviour) -> Result { + todo!() + } +} + +impl From for RawSolMisbehaviour { + fn from(value: Misbehaviour) -> Self { + todo!() + } +} + +impl Protobuf for Misbehaviour {} + +impl TryFrom for Misbehaviour { + type Error = ClientError; + + fn try_from(raw: Any) -> Result { + use core::ops::Deref; + + fn decode_misbehaviour(buf: B) -> Result { + RawSolMisbehaviour::decode(buf) + .map_err(Error::Decode)? + .try_into() + } + + match raw.type_url.as_str() { + SOLOMACHINE_MISBEHAVIOUR_TYPE_URL => { + decode_misbehaviour(raw.value.deref()).map_err(Into::into) + } + _ => Err(ClientError::UnknownMisbehaviourType { + misbehaviour_type: raw.type_url, + }), + } + } +} + +impl From for Any { + fn from(misbehaviour: Misbehaviour) -> Self { + Any { + type_url: SOLOMACHINE_MISBEHAVIOUR_TYPE_URL.to_string(), + value: Protobuf::::encode_vec(&misbehaviour) + .expect("encoding to `Any` from `RawSolMisbehaviour`"), + } + } +} + +pub fn decode_misbehaviour(buf: B) -> Result { + RawSolMisbehaviour::decode(buf) + .map_err(Error::Decode)? + .try_into() +} + +impl core::fmt::Display for Misbehaviour { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + todo!() + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs new file mode 100644 index 000000000..3717c8222 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs @@ -0,0 +1,31 @@ +use crate::clients::ics06_solomachine::data_type::DataType; +use crate::clients::ics06_solomachine::error::Error; +use crate::prelude::*; +use ibc_proto::ibc::lightclients::solomachine::v1::SignatureAndData as RawSignatureAndData; +use ibc_proto::protobuf::Protobuf; + +/// SignatureAndData contains a signature and the data signed over to create that +/// signature. +#[derive(Clone, PartialEq)] +pub struct SignatureAndData { + pub signature: Vec, + pub data_type: DataType, + pub data: Vec, + pub timestamp: u64, +} + +impl Protobuf for SignatureAndData {} + +impl TryFrom for SignatureAndData { + type Error = Error; + + fn try_from(raw: RawSignatureAndData) -> Result { + todo!() + } +} + +impl From for RawSignatureAndData { + fn from(value: SignatureAndData) -> Self { + todo!() + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/mod.rs b/crates/ibc/src/clients/ics06_solomachine/mod.rs index acf45238c..7097616e9 100644 --- a/crates/ibc/src/clients/ics06_solomachine/mod.rs +++ b/crates/ibc/src/clients/ics06_solomachine/mod.rs @@ -1,5 +1,6 @@ pub mod client_state; pub mod consensus_state; +pub mod data_type; pub mod error; pub mod header; pub mod misbehaviour; From 60974756bcb7fc6086c6f56222533b0420af4232 Mon Sep 17 00:00:00 2001 From: Davirain Date: Fri, 21 Apr 2023 10:25:39 +0800 Subject: [PATCH 05/35] Reformatting and updating `ics06_solomachine` client to resolve bugs and improve performance. --- .../clients/ics06_solomachine/client_state.rs | 1 + .../ics06_solomachine/consensus_state.rs | 3 +- .../clients/ics06_solomachine/data_type.rs | 43 -------- .../src/clients/ics06_solomachine/header.rs | 1 + .../clients/ics06_solomachine/misbehaviour.rs | 2 +- .../misbehaviour/signature_and_data.rs | 3 +- .../ibc/src/clients/ics06_solomachine/mod.rs | 2 +- .../src/clients/ics06_solomachine/types.rs | 101 ++++++++++++++++++ 8 files changed, 109 insertions(+), 47 deletions(-) delete mode 100644 crates/ibc/src/clients/ics06_solomachine/data_type.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/types.rs diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index c8b6ee4b8..d50364dd3 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -11,6 +11,7 @@ pub const SOLOMACHINE_CLIENT_STATE_TYPE_URL: &str = "/ibc.lightclients.solomachi /// ClientState defines a solo machine client that tracks the current consensus /// state and if the client is frozen. +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, PartialEq)] pub struct ClientState { /// latest sequence of the client state diff --git a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs index 0cc9fd36c..d463fbfb1 100644 --- a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs @@ -12,6 +12,7 @@ pub const SOLOMACHINE_CONSENSUS_STATE_TYPE_URL: &str = /// ConsensusState defines a solo machine consensus state. The sequence of a /// consensus state is contained in the "height" key used in storing the /// consensus state. +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, PartialEq)] pub struct ConsensusState { /// public key of the solo machine @@ -19,7 +20,7 @@ pub struct ConsensusState { /// diversifier allows the same public key to be re-used across different solo /// machine clients (potentially on different chains) without being considered /// misbehaviour. - pub diversifier: ::prost::alloc::string::String, + pub diversifier: String, pub timestamp: u64, } diff --git a/crates/ibc/src/clients/ics06_solomachine/data_type.rs b/crates/ibc/src/clients/ics06_solomachine/data_type.rs deleted file mode 100644 index d2f729174..000000000 --- a/crates/ibc/src/clients/ics06_solomachine/data_type.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::clients::ics06_solomachine::error::Error; -use crate::prelude::*; -use ibc_proto::ibc::lightclients::solomachine::v1::DataType as RawDataType; - -/// DataType defines the type of solo machine proof being created. This is done -/// to preserve uniqueness of different data sign byte encodings. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub enum DataType { - /// Default State - UninitializedUnspecified, - /// Data type for client state verification - ClientState, - /// Data type for consensus state verification - ConsensusState, - /// Data type for connection state verification - ConnectionState, - /// Data type for channel state verification - ChannelState, - /// Data type for packet commitment verification - PacketCommitment, - /// Data type for packet acknowledgement verification - PacketAcknowledgement, - /// Data type for packet receipt absence verification - PacketReceiptAbsence, - /// Data type for next sequence recv verification - NextSequenceRecv, - /// Data type for header verification - Header, -} - -impl TryFrom for DataType { - type Error = Error; - - fn try_from(raw: RawDataType) -> Result { - todo!() - } -} - -impl From for RawDataType { - fn from(value: DataType) -> Self { - todo!() - } -} diff --git a/crates/ibc/src/clients/ics06_solomachine/header.rs b/crates/ibc/src/clients/ics06_solomachine/header.rs index cc43f4d72..61a48b3ba 100644 --- a/crates/ibc/src/clients/ics06_solomachine/header.rs +++ b/crates/ibc/src/clients/ics06_solomachine/header.rs @@ -10,6 +10,7 @@ use prost::Message; pub const SOLOMACHINE_HEADER_TYPE_URL: &str = "/ibc.lightclients.solomachine.v1.Header"; /// Header defines a solo machine consensus header +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, PartialEq)] pub struct Header { /// sequence to update solo machine public key at diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs index bbfd07d4c..6d103e244 100644 --- a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs @@ -15,7 +15,7 @@ pub const SOLOMACHINE_MISBEHAVIOUR_TYPE_URL: &str = "/ibc.lightclients.solomachi /// Misbehaviour defines misbehaviour for a solo machine which consists /// of a sequence and two signatures over different messages at that sequence. -#[allow(clippy::derive_partial_eq_without_eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, PartialEq)] pub struct Misbehaviour { pub client_id: String, diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs index 3717c8222..cd87b31c6 100644 --- a/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs @@ -1,11 +1,12 @@ -use crate::clients::ics06_solomachine::data_type::DataType; use crate::clients::ics06_solomachine::error::Error; +use crate::clients::ics06_solomachine::types::DataType; use crate::prelude::*; use ibc_proto::ibc::lightclients::solomachine::v1::SignatureAndData as RawSignatureAndData; use ibc_proto::protobuf::Protobuf; /// SignatureAndData contains a signature and the data signed over to create that /// signature. +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, PartialEq)] pub struct SignatureAndData { pub signature: Vec, diff --git a/crates/ibc/src/clients/ics06_solomachine/mod.rs b/crates/ibc/src/clients/ics06_solomachine/mod.rs index 7097616e9..d95084862 100644 --- a/crates/ibc/src/clients/ics06_solomachine/mod.rs +++ b/crates/ibc/src/clients/ics06_solomachine/mod.rs @@ -1,6 +1,6 @@ pub mod client_state; pub mod consensus_state; -pub mod data_type; pub mod error; pub mod header; pub mod misbehaviour; +pub mod types; diff --git a/crates/ibc/src/clients/ics06_solomachine/types.rs b/crates/ibc/src/clients/ics06_solomachine/types.rs new file mode 100644 index 000000000..73735aec5 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/types.rs @@ -0,0 +1,101 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::prelude::*; +use ibc_proto::ibc::lightclients::solomachine::v1::DataType as RawDataType; +use ibc_proto::ibc::lightclients::solomachine::v1::SignBytes as RawSignBytes; +use ibc_proto::ibc::lightclients::solomachine::v1::TimestampedSignatureData as RawTimestampedSignatureData; +use ibc_proto::protobuf::Protobuf; + +/// DataType defines the type of solo machine proof being created. This is done +/// to preserve uniqueness of different data sign byte encodings. +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum DataType { + /// Default State + UninitializedUnspecified, + /// Data type for client state verification + ClientState, + /// Data type for consensus state verification + ConsensusState, + /// Data type for connection state verification + ConnectionState, + /// Data type for channel state verification + ChannelState, + /// Data type for packet commitment verification + PacketCommitment, + /// Data type for packet acknowledgement verification + PacketAcknowledgement, + /// Data type for packet receipt absence verification + PacketReceiptAbsence, + /// Data type for next sequence recv verification + NextSequenceRecv, + /// Data type for header verification + Header, +} + +impl TryFrom for DataType { + type Error = Error; + + fn try_from(raw: RawDataType) -> Result { + todo!() + } +} + +impl From for RawDataType { + fn from(value: DataType) -> Self { + todo!() + } +} + +/// TimestampedSignatureData contains the signature data and the timestamp of the +/// signature. +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Clone, PartialEq)] +pub struct TimestampedSignatureData { + pub signature_data: Vec, + pub timestamp: u64, +} + +impl Protobuf for TimestampedSignatureData {} + +impl TryFrom for TimestampedSignatureData { + type Error = Error; + + fn try_from(raw: RawTimestampedSignatureData) -> Result { + todo!() + } +} + +impl From for RawTimestampedSignatureData { + fn from(value: TimestampedSignatureData) -> Self { + todo!() + } +} + +/// SignBytes defines the signed bytes used for signature verification. +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Clone, PartialEq)] +pub struct SignBytes { + pub sequence: u64, + pub timestamp: u64, + pub diversifier: String, + /// type of the data used + pub data_type: i32, + /// marshaled data + pub data: Vec, +} + +// impl Protobuf for SignBytes {} + +impl TryFrom for SignBytes { + type Error = Error; + + fn try_from(raw: RawSignBytes) -> Result { + todo!() + } +} + +impl From for RawTimestampedSignatureData { + fn from(value: SignBytes) -> Self { + todo!() + } +} From d2ab9fcb534fcf0cbe4dc004fbd1b8f466da2de2 Mon Sep 17 00:00:00 2001 From: Davirain Date: Fri, 21 Apr 2023 11:14:53 +0800 Subject: [PATCH 06/35] add types --- .../src/clients/ics06_solomachine/types.rs | 69 ++++--------------- .../types/channel_state_data.rs | 28 ++++++++ .../types/client_stata_data.rs | 28 ++++++++ .../types/connection_state_data.rs | 30 ++++++++ .../types/consensus_state_data.rs | 30 ++++++++ .../ics06_solomachine/types/header_data.rs | 31 +++++++++ .../types/next_sequence_recv_data.rs | 29 ++++++++ .../types/packet_acknowledgement_data.rs | 28 ++++++++ .../types/packet_commitment_data.rs | 28 ++++++++ .../types/packet_receipt_absence_data.rs | 27 ++++++++ .../ics06_solomachine/types/sign_bytes.rs | 34 +++++++++ .../types/timestamped_signature_data.rs | 29 ++++++++ 12 files changed, 334 insertions(+), 57 deletions(-) create mode 100644 crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/types/header_data.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/types/next_sequence_recv_data.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/types/packet_acknowledgement_data.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/types/packet_commitment_data.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs diff --git a/crates/ibc/src/clients/ics06_solomachine/types.rs b/crates/ibc/src/clients/ics06_solomachine/types.rs index 73735aec5..d54575deb 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types.rs @@ -1,9 +1,18 @@ use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; use ibc_proto::ibc::lightclients::solomachine::v1::DataType as RawDataType; -use ibc_proto::ibc::lightclients::solomachine::v1::SignBytes as RawSignBytes; -use ibc_proto::ibc::lightclients::solomachine::v1::TimestampedSignatureData as RawTimestampedSignatureData; -use ibc_proto::protobuf::Protobuf; + +pub mod channel_state_data; +pub mod client_stata_data; +pub mod connection_state_data; +pub mod consensus_state_data; +pub mod header_data; +pub mod next_sequence_recv_data; +pub mod packet_acknowledgement_data; +pub mod packet_commitment_data; +pub mod packet_receipt_absence_data; +pub mod sign_bytes; +pub mod timestamped_signature_data; /// DataType defines the type of solo machine proof being created. This is done /// to preserve uniqueness of different data sign byte encodings. @@ -45,57 +54,3 @@ impl From for RawDataType { todo!() } } - -/// TimestampedSignatureData contains the signature data and the timestamp of the -/// signature. -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, PartialEq)] -pub struct TimestampedSignatureData { - pub signature_data: Vec, - pub timestamp: u64, -} - -impl Protobuf for TimestampedSignatureData {} - -impl TryFrom for TimestampedSignatureData { - type Error = Error; - - fn try_from(raw: RawTimestampedSignatureData) -> Result { - todo!() - } -} - -impl From for RawTimestampedSignatureData { - fn from(value: TimestampedSignatureData) -> Self { - todo!() - } -} - -/// SignBytes defines the signed bytes used for signature verification. -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, PartialEq)] -pub struct SignBytes { - pub sequence: u64, - pub timestamp: u64, - pub diversifier: String, - /// type of the data used - pub data_type: i32, - /// marshaled data - pub data: Vec, -} - -// impl Protobuf for SignBytes {} - -impl TryFrom for SignBytes { - type Error = Error; - - fn try_from(raw: RawSignBytes) -> Result { - todo!() - } -} - -impl From for RawTimestampedSignatureData { - fn from(value: SignBytes) -> Self { - todo!() - } -} diff --git a/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs new file mode 100644 index 000000000..836a4cc93 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs @@ -0,0 +1,28 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::core::ics04_channel::channel::ChannelEnd; +use crate::prelude::*; +use ibc_proto::ibc::lightclients::solomachine::v1::ChannelStateData as RawChannelStateData; +use ibc_proto::protobuf::Protobuf; + +/// ChannelStateData returns the SignBytes data for channel state +/// verification. +#[derive(Clone, PartialEq)] +pub struct ChannelStateData { + pub path: Vec, + pub channel: Option, +} +impl Protobuf for ChannelStateData {} + +impl TryFrom for ChannelStateData { + type Error = Error; + + fn try_from(raw: RawChannelStateData) -> Result { + todo!() + } +} + +impl From for RawChannelStateData { + fn from(value: ChannelStateData) -> Self { + todo!() + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs new file mode 100644 index 000000000..a99cff820 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs @@ -0,0 +1,28 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::prelude::*; +use ibc_proto::google::protobuf::Any; +use ibc_proto::ibc::lightclients::solomachine::v1::ClientStateData as RawClientStateData; +use ibc_proto::protobuf::Protobuf; + +/// ClientStateData returns the SignBytes data for client state verification. +#[derive(Clone, PartialEq)] +pub struct ClientStateData { + pub path: Vec, + pub client_state: Option, +} + +impl Protobuf for ClientStateData {} + +impl TryFrom for ClientStateData { + type Error = Error; + + fn try_from(raw: RawClientStateData) -> Result { + todo!() + } +} + +impl From for RawClientStateData { + fn from(value: ClientStateData) -> Self { + todo!() + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs new file mode 100644 index 000000000..dc6f1fcec --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs @@ -0,0 +1,30 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::core::ics03_connection::connection::ConnectionEnd; +use crate::prelude::*; +use ibc_proto::ibc::lightclients::solomachine::v1::ConnectionStateData as RawConnectionStateData; +use ibc_proto::protobuf::Protobuf; + +/// ConnectionStateData returns the SignBytes data for connection state +/// verification. +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Clone, PartialEq)] +pub struct ConnectionStateData { + pub path: Vec, + pub connection: Option, +} + +impl Protobuf for ConnectionStateData {} + +impl TryFrom for ConnectionStateData { + type Error = Error; + + fn try_from(raw: RawConnectionStateData) -> Result { + todo!() + } +} + +impl From for RawConnectionStateData { + fn from(value: ConnectionStateData) -> Self { + todo!() + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs new file mode 100644 index 000000000..eca0bf847 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs @@ -0,0 +1,30 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::prelude::*; +use ibc_proto::google::protobuf::Any; +use ibc_proto::ibc::lightclients::solomachine::v1::ConsensusStateData as RawConsensusStateData; +use ibc_proto::protobuf::Protobuf; + +/// ConsensusStateData returns the SignBytes data for consensus state +/// verification. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq)] +pub struct ConsensusStateData { + pub path: Vec, + pub consensus_state: Option, +} + +impl Protobuf for ConsensusStateData {} + +impl TryFrom for ConsensusStateData { + type Error = Error; + + fn try_from(raw: RawConsensusStateData) -> Result { + todo!() + } +} + +impl From for RawConsensusStateData { + fn from(value: ConsensusStateData) -> Self { + todo!() + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs new file mode 100644 index 000000000..7bdcac6e4 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs @@ -0,0 +1,31 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::prelude::*; +use ibc_proto::google::protobuf::Any; +use ibc_proto::ibc::lightclients::solomachine::v1::HeaderData as RawHeaderData; +use ibc_proto::protobuf::Protobuf; + +/// HeaderData returns the SignBytes data for update verification. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq)] +pub struct HeaderData { + /// header public key + pub new_pub_key: Option, + /// header diversifier + pub new_diversifier: String, +} + +impl Protobuf for HeaderData {} + +impl TryFrom for HeaderData { + type Error = Error; + + fn try_from(raw: RawHeaderData) -> Result { + todo!() + } +} + +impl From for RawHeaderData { + fn from(value: HeaderData) -> Self { + todo!() + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/types/next_sequence_recv_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/next_sequence_recv_data.rs new file mode 100644 index 000000000..ef7fb8402 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/types/next_sequence_recv_data.rs @@ -0,0 +1,29 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::prelude::*; +use ibc_proto::ibc::lightclients::solomachine::v1::NextSequenceRecvData as RawNextSequenceRecvData; +use ibc_proto::protobuf::Protobuf; + +/// NextSequenceRecvData returns the SignBytes data for verification of the next +/// sequence to be received. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq)] +pub struct NextSequenceRecvData { + pub path: Vec, + pub next_seq_recv: u64, +} + +impl Protobuf for NextSequenceRecvData {} + +impl TryFrom for NextSequenceRecvData { + type Error = Error; + + fn try_from(raw: RawNextSequenceRecvData) -> Result { + todo!() + } +} + +impl From for RawNextSequenceRecvData { + fn from(value: NextSequenceRecvData) -> Self { + todo!() + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/types/packet_acknowledgement_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/packet_acknowledgement_data.rs new file mode 100644 index 000000000..826fe8121 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/types/packet_acknowledgement_data.rs @@ -0,0 +1,28 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::prelude::*; +use ibc_proto::ibc::lightclients::solomachine::v1::PacketAcknowledgementData as RawPacketAcknowledgementData; +use ibc_proto::protobuf::Protobuf; + +/// PacketAcknowledgementData returns the SignBytes data for acknowledgement +/// verification. +#[derive(Clone, PartialEq)] +pub struct PacketAcknowledgementData { + pub path: Vec, + pub acknowledgement: Vec, +} + +impl Protobuf for PacketAcknowledgementData {} + +impl TryFrom for PacketAcknowledgementData { + type Error = Error; + + fn try_from(raw: RawPacketAcknowledgementData) -> Result { + todo!() + } +} + +impl From for RawPacketAcknowledgementData { + fn from(value: PacketAcknowledgementData) -> Self { + todo!() + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/types/packet_commitment_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/packet_commitment_data.rs new file mode 100644 index 000000000..dc7196b99 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/types/packet_commitment_data.rs @@ -0,0 +1,28 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::prelude::*; +use ibc_proto::ibc::lightclients::solomachine::v1::PacketCommitmentData as RawPacketCommitmentData; +use ibc_proto::protobuf::Protobuf; + +/// PacketCommitmentData returns the SignBytes data for packet commitment +/// verification. +#[derive(Clone, PartialEq)] +pub struct PacketCommitmentData { + pub path: Vec, + pub commitment: Vec, +} + +impl Protobuf for PacketCommitmentData {} + +impl TryFrom for PacketCommitmentData { + type Error = Error; + + fn try_from(raw: RawPacketCommitmentData) -> Result { + todo!() + } +} + +impl From for RawPacketCommitmentData { + fn from(value: PacketCommitmentData) -> Self { + todo!() + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs new file mode 100644 index 000000000..becf4d558 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs @@ -0,0 +1,27 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::prelude::*; +use ibc_proto::ibc::lightclients::solomachine::v1::PacketReceiptAbsenceData as RawPacketReceiptAbsenceData; +use ibc_proto::protobuf::Protobuf; + +/// PacketReceiptAbsenceData returns the SignBytes data for +/// packet receipt absence verification. +#[derive(Clone, PartialEq)] +pub struct PacketReceiptAbsenceData { + pub path: Vec, +} + +impl Protobuf for PacketReceiptAbsenceData {} + +impl TryFrom for PacketReceiptAbsenceData { + type Error = Error; + + fn try_from(raw: RawPacketReceiptAbsenceData) -> Result { + todo!() + } +} + +impl From for RawPacketReceiptAbsenceData { + fn from(value: PacketReceiptAbsenceData) -> Self { + todo!() + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs b/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs new file mode 100644 index 000000000..a44ffb55a --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs @@ -0,0 +1,34 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::prelude::*; +use ibc_proto::ibc::lightclients::solomachine::v1::SignBytes as RawSignBytes; +use ibc_proto::ibc::lightclients::solomachine::v1::TimestampedSignatureData as RawTimestampedSignatureData; +// use ibc_proto::protobuf::Protobuf; + +/// SignBytes defines the signed bytes used for signature verification. +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Clone, PartialEq)] +pub struct SignBytes { + pub sequence: u64, + pub timestamp: u64, + pub diversifier: String, + /// type of the data used + pub data_type: i32, + /// marshaled data + pub data: Vec, +} + +// impl Protobuf for SignBytes {} + +impl TryFrom for SignBytes { + type Error = Error; + + fn try_from(raw: RawSignBytes) -> Result { + todo!() + } +} + +impl From for RawTimestampedSignatureData { + fn from(value: SignBytes) -> Self { + todo!() + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs new file mode 100644 index 000000000..6c8e4c13b --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs @@ -0,0 +1,29 @@ +use crate::clients::ics06_solomachine::error::Error; +use crate::prelude::*; +use ibc_proto::ibc::lightclients::solomachine::v1::TimestampedSignatureData as RawTimestampedSignatureData; +use ibc_proto::protobuf::Protobuf; + +/// TimestampedSignatureData contains the signature data and the timestamp of the +/// signature. +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Clone, PartialEq)] +pub struct TimestampedSignatureData { + pub signature_data: Vec, + pub timestamp: u64, +} + +impl Protobuf for TimestampedSignatureData {} + +impl TryFrom for TimestampedSignatureData { + type Error = Error; + + fn try_from(raw: RawTimestampedSignatureData) -> Result { + todo!() + } +} + +impl From for RawTimestampedSignatureData { + fn from(value: TimestampedSignatureData) -> Self { + todo!() + } +} From a0eb598f67dcd2f54748532dbf76b788cf46584a Mon Sep 17 00:00:00 2001 From: Davirain Date: Fri, 21 Apr 2023 11:45:33 +0800 Subject: [PATCH 07/35] refactor: use SoloMachineConsensusState in ics06_solomachine/client_state.rs and implement Ics2ClientState for ClientState class. --- .../clients/ics06_solomachine/client_state.rs | 176 +++++++++++++++++- .../ics06_solomachine/consensus_state.rs | 14 +- .../src/clients/ics06_solomachine/header.rs | 25 +++ .../ibc/src/clients/ics06_solomachine/mod.rs | 10 + 4 files changed, 221 insertions(+), 4 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index d50364dd3..b380746fd 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -1,8 +1,21 @@ -use crate::clients::ics06_solomachine::consensus_state::ConsensusState; +use crate::clients::ics06_solomachine::consensus_state::ConsensusState as SoloMachineConsensusState; use crate::clients::ics06_solomachine::error::Error; +use crate::core::ics02_client::client_state::{ClientState as Ics2ClientState, UpdatedState}; +use crate::core::ics02_client::client_type::ClientType; +use crate::core::ics02_client::consensus_state::ConsensusState; use crate::core::ics02_client::error::ClientError; +use crate::core::ics02_client::msgs::update_client::UpdateKind; +use crate::core::ics23_commitment::commitment::{ + CommitmentPrefix, CommitmentProofBytes, CommitmentRoot, +}; +use crate::core::ics24_host::identifier::{ChainId, ClientId}; +use crate::core::ics24_host::Path; +use crate::core::{ExecutionContext, ValidationContext}; use crate::prelude::*; +use crate::Height; +use core::time::Duration; use ibc_proto::google::protobuf::Any; +use ibc_proto::ibc::core::commitment::v1::MerkleProof as RawMerkleProof; use ibc_proto::ibc::lightclients::solomachine::v1::ClientState as RawSolClientState; use ibc_proto::protobuf::Protobuf; use prost::Message; @@ -12,18 +25,175 @@ pub const SOLOMACHINE_CLIENT_STATE_TYPE_URL: &str = "/ibc.lightclients.solomachi /// ClientState defines a solo machine client that tracks the current consensus /// state and if the client is frozen. #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Debug)] pub struct ClientState { /// latest sequence of the client state pub sequence: u64, /// frozen sequence of the solo machine pub frozen_sequence: u64, - pub consensus_state: Option, + pub consensus_state: Option, /// when set to true, will allow governance to update a solo machine client. /// The client will be unfrozen if it is frozen. pub allow_update_after_proposal: bool, } +impl Ics2ClientState for ClientState { + /// Return the chain identifier which this client is serving (i.e., the client is verifying + /// consensus states from this chain). + fn chain_id(&self) -> ChainId { + todo!() + } + + /// Type of client associated with this state (eg. Tendermint) + fn client_type(&self) -> ClientType { + todo!() + } + + /// Latest height the client was updated to + fn latest_height(&self) -> Height { + todo!() + } + + /// Check if the given proof has a valid height for the client + fn validate_proof_height(&self, proof_height: Height) -> Result<(), ClientError> { + todo!() + } + + /// Assert that the client is not frozen + fn confirm_not_frozen(&self) -> Result<(), ClientError> { + todo!() + } + + /// Check if the state is expired when `elapsed` time has passed since the latest consensus + /// state timestamp + fn expired(&self, elapsed: Duration) -> bool { + todo!() + } + + /// Helper function to verify the upgrade client procedure. + /// Resets all fields except the blockchain-specific ones, + /// and updates the given fields. + fn zero_custom_fields(&mut self) { + todo!() + } + + fn initialise(&self, consensus_state: Any) -> Result, ClientError> { + todo!() + } + + /// verify_client_message must verify a client_message. A client_message + /// could be a Header, Misbehaviour. It must handle each type of + /// client_message appropriately. Calls to check_for_misbehaviour, + /// update_state, and update_state_on_misbehaviour will assume that the + /// content of the client_message has been verified and can be trusted. An + /// error should be returned if the client_message fails to verify. + fn verify_client_message( + &self, + ctx: &dyn ValidationContext, + client_id: &ClientId, + client_message: Any, + update_kind: &UpdateKind, + ) -> Result<(), ClientError> { + todo!() + } + + /// Checks for evidence of a misbehaviour in Header or Misbehaviour type. It + /// assumes the client_message has already been verified. + fn check_for_misbehaviour( + &self, + ctx: &dyn ValidationContext, + client_id: &ClientId, + client_message: Any, + update_kind: &UpdateKind, + ) -> Result { + todo!() + } + + /// Updates and stores as necessary any associated information for an IBC + /// client, such as the ClientState and corresponding ConsensusState. Upon + /// successful update, a list of consensus heights is returned. It assumes + /// the client_message has already been verified. + /// + /// Post-condition: on success, the return value MUST contain at least one + /// height. + fn update_state( + &self, + ctx: &mut dyn ExecutionContext, + client_id: &ClientId, + client_message: Any, + update_kind: &UpdateKind, + ) -> Result, ClientError> { + todo!() + } + + /// update_state_on_misbehaviour should perform appropriate state changes on + /// a client state given that misbehaviour has been detected and verified + fn update_state_on_misbehaviour( + &self, + ctx: &mut dyn ExecutionContext, + client_id: &ClientId, + client_message: Any, + update_kind: &UpdateKind, + ) -> Result<(), ClientError> { + todo!() + } + + /// Verify the upgraded client and consensus states and validate proofs + /// against the given root. + /// + /// NOTE: proof heights are not included as upgrade to a new revision is + /// expected to pass only on the last height committed by the current + /// revision. Clients are responsible for ensuring that the planned last + /// height of the current revision is somehow encoded in the proof + /// verification process. This is to ensure that no premature upgrades + /// occur, since upgrade plans committed to by the counterparty may be + /// cancelled or modified before the last planned height. + fn verify_upgrade_client( + &self, + upgraded_client_state: Any, + upgraded_consensus_state: Any, + proof_upgrade_client: RawMerkleProof, + proof_upgrade_consensus_state: RawMerkleProof, + root: &CommitmentRoot, + ) -> Result<(), ClientError> { + todo!() + } + + // Update the client state and consensus state in the store with the upgraded ones. + fn update_state_with_upgrade_client( + &self, + upgraded_client_state: Any, + upgraded_consensus_state: Any, + ) -> Result { + todo!() + } + + // Verify_membership is a generic proof verification method which verifies a + // proof of the existence of a value at a given Path. + fn verify_membership( + &self, + prefix: &CommitmentPrefix, + proof: &CommitmentProofBytes, + root: &CommitmentRoot, + path: Path, + value: Vec, + ) -> Result<(), ClientError> { + todo!() + } + + // Verify_non_membership is a generic proof verification method which + // verifies the absence of a given commitment. + fn verify_non_membership( + &self, + prefix: &CommitmentPrefix, + proof: &CommitmentProofBytes, + root: &CommitmentRoot, + path: Path, + ) -> Result<(), ClientError> { + todo!() + } +} + impl Protobuf for ClientState {} impl TryFrom for ClientState { diff --git a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs index d463fbfb1..252bc6124 100644 --- a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs @@ -1,6 +1,8 @@ use crate::clients::ics06_solomachine::error::Error; use crate::core::ics02_client::error::ClientError; +use crate::core::ics23_commitment::commitment::CommitmentRoot; use crate::prelude::*; +use crate::timestamp::Timestamp; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::lightclients::solomachine::v1::ConsensusState as RawSolConsensusState; use ibc_proto::protobuf::Protobuf; @@ -13,7 +15,7 @@ pub const SOLOMACHINE_CONSENSUS_STATE_TYPE_URL: &str = /// consensus state is contained in the "height" key used in storing the /// consensus state. #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Debug)] pub struct ConsensusState { /// public key of the solo machine pub public_key: Option, @@ -24,6 +26,16 @@ pub struct ConsensusState { pub timestamp: u64, } +impl crate::core::ics02_client::consensus_state::ConsensusState for ConsensusState { + fn root(&self) -> &CommitmentRoot { + todo!() + } + + fn timestamp(&self) -> Timestamp { + todo!() + } +} + impl Protobuf for ConsensusState {} impl TryFrom for ConsensusState { diff --git a/crates/ibc/src/clients/ics06_solomachine/header.rs b/crates/ibc/src/clients/ics06_solomachine/header.rs index 61a48b3ba..770bef814 100644 --- a/crates/ibc/src/clients/ics06_solomachine/header.rs +++ b/crates/ibc/src/clients/ics06_solomachine/header.rs @@ -1,7 +1,10 @@ use crate::clients::ics06_solomachine::error::Error; use crate::core::ics02_client::error::ClientError; use crate::prelude::*; +use crate::timestamp::Timestamp; +use crate::Height; use bytes::Buf; +use core::fmt::{Display, Error as FmtError, Formatter}; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::lightclients::solomachine::v1::Header as RawSolHeader; use ibc_proto::protobuf::Protobuf; @@ -21,6 +24,28 @@ pub struct Header { pub new_diversifier: String, } +impl core::fmt::Debug for Header { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { + todo!() + } +} + +impl Display for Header { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { + todo!() + } +} + +impl crate::core::ics02_client::header::Header for Header { + fn height(&self) -> Height { + todo!() + } + + fn timestamp(&self) -> Timestamp { + todo!() + } +} + impl Protobuf for Header {} impl TryFrom for Header { diff --git a/crates/ibc/src/clients/ics06_solomachine/mod.rs b/crates/ibc/src/clients/ics06_solomachine/mod.rs index d95084862..81eb536ca 100644 --- a/crates/ibc/src/clients/ics06_solomachine/mod.rs +++ b/crates/ibc/src/clients/ics06_solomachine/mod.rs @@ -1,6 +1,16 @@ +use alloc::string::ToString; + +use crate::core::ics02_client::client_type::ClientType; + pub mod client_state; pub mod consensus_state; pub mod error; pub mod header; pub mod misbehaviour; pub mod types; + +pub(crate) const SOLOMACHINE_CLIENT_TYPE: &str = "07-solomachine"; + +pub fn client_type() -> ClientType { + ClientType::new(SOLOMACHINE_CLIENT_TYPE.to_string()) +} From 67918e8e1bd15f8bb3ed0d69168e9c8c71d31096 Mon Sep 17 00:00:00 2001 From: Davirain Date: Sun, 23 Apr 2023 10:17:18 +0800 Subject: [PATCH 08/35] refactor(client_state): add new methods to implement ClientState interface more cleanly. --- .../clients/ics06_solomachine/client_state.rs | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index b380746fd..d18d0edb6 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -28,15 +28,38 @@ pub const SOLOMACHINE_CLIENT_STATE_TYPE_URL: &str = "/ibc.lightclients.solomachi #[derive(Clone, PartialEq, Debug)] pub struct ClientState { /// latest sequence of the client state - pub sequence: u64, + pub sequence: Height, /// frozen sequence of the solo machine - pub frozen_sequence: u64, + pub frozen_sequence: Option, pub consensus_state: Option, /// when set to true, will allow governance to update a solo machine client. /// The client will be unfrozen if it is frozen. pub allow_update_after_proposal: bool, } +impl ClientState { + /// Create a new ClientState Instance. + pub fn new( + sequence: Height, + frozen_sequence: Option, + consensus_state: Option, + allow_update_after_proposal: bool, + ) -> Self { + Self { + sequence, + frozen_sequence, + consensus_state, + allow_update_after_proposal, + } + } + + /// Return exported.Height to satisfy ClientState interface + /// Revision number is always 0 for a solo-machine. + pub fn latest_height(&self) -> Height { + self.sequence + } +} + impl Ics2ClientState for ClientState { /// Return the chain identifier which this client is serving (i.e., the client is verifying /// consensus states from this chain). @@ -44,14 +67,14 @@ impl Ics2ClientState for ClientState { todo!() } - /// Type of client associated with this state (eg. Tendermint) + /// ClientType is Solo Machine. fn client_type(&self) -> ClientType { - todo!() + super::client_type() } - /// Latest height the client was updated to + /// latest_height returns the latest sequence number. fn latest_height(&self) -> Height { - todo!() + self.latest_height() } /// Check if the given proof has a valid height for the client @@ -61,7 +84,12 @@ impl Ics2ClientState for ClientState { /// Assert that the client is not frozen fn confirm_not_frozen(&self) -> Result<(), ClientError> { - todo!() + if let Some(frozen_height) = self.frozen_sequence { + return Err(ClientError::ClientFrozen { + description: format!("the client is frozen at height {frozen_height}"), + }); + } + Ok(()) } /// Check if the state is expired when `elapsed` time has passed since the latest consensus @@ -73,8 +101,9 @@ impl Ics2ClientState for ClientState { /// Helper function to verify the upgrade client procedure. /// Resets all fields except the blockchain-specific ones, /// and updates the given fields. + // ref: https://github.com/cosmos/ibc-go/blob/fa9418f5ba39de38d995ec83d9abd289dfab5f9f/modules/light-clients/06-solomachine/client_state.go#L75 fn zero_custom_fields(&mut self) { - todo!() + // zero_custom_fields is not implemented for solo machine } fn initialise(&self, consensus_state: Any) -> Result, ClientError> { From 031c0fe0a493a326894c4069b4017598e88f53e1 Mon Sep 17 00:00:00 2001 From: Davirain Date: Sun, 23 Apr 2023 11:52:28 +0800 Subject: [PATCH 09/35] refactor: Clean up Cargo.toml dependencies and implement public_key and a basic validation function. --- crates/ibc/Cargo.toml | 20 +--------- .../ics06_solomachine/consensus_state.rs | 37 ++++++++++++++++++- .../src/clients/ics06_solomachine/error.rs | 2 + 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/crates/ibc/Cargo.toml b/crates/ibc/Cargo.toml index 3df70fa3e..8e78355ee 100644 --- a/crates/ibc/Cargo.toml +++ b/crates/ibc/Cargo.toml @@ -18,24 +18,7 @@ all-features = true [features] default = ["std"] -std = [ - "ibc-proto/std", - "ics23/std", - "serde/std", - "serde_json/std", - "erased-serde/std", - "tracing/std", - "prost/std", - "bytes/std", - "subtle-encoding/std", - "sha2/std", - "displaydoc/std", - "num-traits/std", - "uint/std", - "primitive-types/std", - "tendermint/clock", - "tendermint/std", -] +std = ["ibc-proto/std", "ics23/std", "serde/std", "serde_json/std", "erased-serde/std", "tracing/std", "prost/std", "bytes/std", "subtle-encoding/std", "sha2/std", "displaydoc/std", "num-traits/std", "uint/std", "primitive-types/std", "tendermint/clock", "tendermint/std"] parity-scale-codec = ["dep:parity-scale-codec", "dep:scale-info"] borsh = ["dep:borsh"] @@ -78,6 +61,7 @@ scale-info = { version = "2.1.2", default-features = false, features = ["derive" borsh = {version = "0.10.0", default-features = false, optional = true } parking_lot = { version = "0.12.1", default-features = false, optional = true } cfg-if = { version = "1.0.0", optional = true } +cosmrs = "0.13.0" [dependencies.tendermint] version = "0.29" diff --git a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs index 252bc6124..94ae85714 100644 --- a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs @@ -7,6 +7,7 @@ use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::lightclients::solomachine::v1::ConsensusState as RawSolConsensusState; use ibc_proto::protobuf::Protobuf; use prost::Message; +use tendermint_proto::crypto::public_key; pub const SOLOMACHINE_CONSENSUS_STATE_TYPE_URL: &str = "/ibc.lightclients.solomachine.v1.ConsensusState"; @@ -23,7 +24,39 @@ pub struct ConsensusState { /// machine clients (potentially on different chains) without being considered /// misbehaviour. pub diversifier: String, - pub timestamp: u64, + pub timestamp: Timestamp, +} + +impl ConsensusState { + pub fn new(public_key: Option, diversifier: String, timestamp: Timestamp) -> Self { + Self { + public_key, + diversifier, + timestamp, + } + } + + pub fn valida_basic(&self) -> Result<(), Error> { + todo!() + } + + // GetPubKey unmarshals the public key into a cryptotypes.PubKey type. + // An error is returned if the public key is nil or the cached value + // is not a PubKey. + + // publicKey, ok := cs.PublicKey.GetCachedValue().(cryptotypes.PubKey) + // if !ok { + // return nil, errorsmod.Wrap(clienttypes.ErrInvalidConsensus, "consensus state PublicKey is not cryptotypes.PubKey") + // } + + // return publicKey, nil + // } + pub fn public_key(&self) -> Result<(), Error> { + if self.public_key.is_none() { + return Err(Error::EmptyConsensusStatePublicKey); + } + todo!() + } } impl crate::core::ics02_client::consensus_state::ConsensusState for ConsensusState { @@ -32,7 +65,7 @@ impl crate::core::ics02_client::consensus_state::ConsensusState for ConsensusSta } fn timestamp(&self) -> Timestamp { - todo!() + self.timestamp } } diff --git a/crates/ibc/src/clients/ics06_solomachine/error.rs b/crates/ibc/src/clients/ics06_solomachine/error.rs index 69c08cb99..c8ffb7d76 100644 --- a/crates/ibc/src/clients/ics06_solomachine/error.rs +++ b/crates/ibc/src/clients/ics06_solomachine/error.rs @@ -13,6 +13,8 @@ pub enum Error { Dummy, /// decode error: `{0}` Decode(prost::DecodeError), + /// consensus state PublicKey is None + EmptyConsensusStatePublicKey, } impl From for ClientError { From cf28e11a304ea6163f5880bf75d33ece5771c152 Mon Sep 17 00:00:00 2001 From: Davirain Date: Tue, 25 Apr 2023 11:06:02 +0800 Subject: [PATCH 10/35] Refactor SoloMachine client_state and consensus_state implementations. --- .../clients/ics06_solomachine/client_state.rs | 31 +++++++++++++++++-- .../ics06_solomachine/consensus_state.rs | 1 - .../src/clients/ics06_solomachine/error.rs | 2 ++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index d18d0edb6..002b97254 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -229,13 +229,40 @@ impl TryFrom for ClientState { type Error = Error; fn try_from(raw: RawSolClientState) -> Result { - todo!() + let sequence = Height::new(0, raw.sequence).map_err(Error::InvalidHeight)?; + let frozen_sequence = if raw.frozen_sequence == 0 { + None + } else { + Some(Height::new(0, raw.frozen_sequence).map_err(Error::InvalidHeight)?) + }; + + let consensus_state: Option = + raw.consensus_state.map(TryInto::try_into).transpose()?; + + Ok(Self { + sequence, + frozen_sequence, + consensus_state, + allow_update_after_proposal: raw.allow_update_after_proposal, + }) } } impl From for RawSolClientState { fn from(value: ClientState) -> Self { - todo!() + let sequence = value.sequence.revision_height(); + let frozen_sequence = if let Some(seq) = value.frozen_sequence { + seq.revision_height() + } else { + 0 + }; + let consensus_state = value.consensus_state.map(Into::into); + Self { + sequence, + frozen_sequence, + consensus_state, + allow_update_after_proposal: value.allow_update_after_proposal, + } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs index 94ae85714..965ac01b6 100644 --- a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs @@ -7,7 +7,6 @@ use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::lightclients::solomachine::v1::ConsensusState as RawSolConsensusState; use ibc_proto::protobuf::Protobuf; use prost::Message; -use tendermint_proto::crypto::public_key; pub const SOLOMACHINE_CONSENSUS_STATE_TYPE_URL: &str = "/ibc.lightclients.solomachine.v1.ConsensusState"; diff --git a/crates/ibc/src/clients/ics06_solomachine/error.rs b/crates/ibc/src/clients/ics06_solomachine/error.rs index c8ffb7d76..79dfd40c2 100644 --- a/crates/ibc/src/clients/ics06_solomachine/error.rs +++ b/crates/ibc/src/clients/ics06_solomachine/error.rs @@ -15,6 +15,8 @@ pub enum Error { Decode(prost::DecodeError), /// consensus state PublicKey is None EmptyConsensusStatePublicKey, + /// invlid height + InvalidHeight(ClientError), } impl From for ClientError { From 39e29c96e5d3a6172aaec44ad8128b8eaf041b96 Mon Sep 17 00:00:00 2001 From: Davirain Date: Tue, 25 Apr 2023 11:59:21 +0800 Subject: [PATCH 11/35] refactor: Refactor code in ics06_solomachine folder --- .../src/clients/ics06_solomachine/error.rs | 11 +-- .../src/clients/ics06_solomachine/header.rs | 21 +++--- .../clients/ics06_solomachine/misbehaviour.rs | 35 ++++++++-- .../misbehaviour/signature_and_data.rs | 22 +++++- .../src/clients/ics06_solomachine/types.rs | 69 +++++++++++++++++-- 5 files changed, 129 insertions(+), 29 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/error.rs b/crates/ibc/src/clients/ics06_solomachine/error.rs index 79dfd40c2..b0d6c123d 100644 --- a/crates/ibc/src/clients/ics06_solomachine/error.rs +++ b/crates/ibc/src/clients/ics06_solomachine/error.rs @@ -1,10 +1,7 @@ use crate::prelude::*; use crate::core::ics02_client::error::ClientError; -use crate::core::ics24_host::identifier::{ChainId, ClientId}; -use crate::Height; -use core::time::Duration; - +use crate::timestamp::ParseTimestampError; use displaydoc::Display; #[derive(Debug, Display)] @@ -17,6 +14,12 @@ pub enum Error { EmptyConsensusStatePublicKey, /// invlid height InvalidHeight(ClientError), + /// invalid raw client id: `{client_id}` + InvalidRawClientId { client_id: String }, + /// unknow data type: `{0}` + UnknownDataType(i32), + /// prase time error + ParseTimeError(ParseTimestampError), } impl From for ClientError { diff --git a/crates/ibc/src/clients/ics06_solomachine/header.rs b/crates/ibc/src/clients/ics06_solomachine/header.rs index 770bef814..0fbb6b0fe 100644 --- a/crates/ibc/src/clients/ics06_solomachine/header.rs +++ b/crates/ibc/src/clients/ics06_solomachine/header.rs @@ -9,7 +9,6 @@ use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::lightclients::solomachine::v1::Header as RawSolHeader; use ibc_proto::protobuf::Protobuf; use prost::Message; - pub const SOLOMACHINE_HEADER_TYPE_URL: &str = "/ibc.lightclients.solomachine.v1.Header"; /// Header defines a solo machine consensus header @@ -17,8 +16,8 @@ pub const SOLOMACHINE_HEADER_TYPE_URL: &str = "/ibc.lightclients.solomachine.v1. #[derive(Clone, PartialEq)] pub struct Header { /// sequence to update solo machine public key at - pub sequence: u64, - pub timestamp: u64, + pub sequence: Height, + pub timestamp: Timestamp, pub signature: Vec, pub new_public_key: Option, pub new_diversifier: String, @@ -38,11 +37,11 @@ impl Display for Header { impl crate::core::ics02_client::header::Header for Header { fn height(&self) -> Height { - todo!() + self.sequence } fn timestamp(&self) -> Timestamp { - todo!() + self.timestamp } } @@ -56,6 +55,12 @@ impl TryFrom for Header { } } +impl From
for RawSolHeader { + fn from(value: Header) -> Self { + todo!() + } +} + impl Protobuf for Header {} impl TryFrom for Header { @@ -86,9 +91,3 @@ impl From
for Any { pub fn decode_header(buf: B) -> Result { RawSolHeader::decode(buf).map_err(Error::Decode)?.try_into() } - -impl From
for RawSolHeader { - fn from(value: Header) -> Self { - todo!() - } -} diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs index 6d103e244..3588e4c42 100644 --- a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs @@ -1,6 +1,7 @@ use crate::clients::ics06_solomachine::error::Error; use crate::core::ics02_client::error::ClientError; -use crate::prelude::*; +use crate::core::ics24_host::identifier::ClientId; +use crate::{prelude::*, Height}; use bytes::Buf; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::lightclients::solomachine::v1::Misbehaviour as RawSolMisbehaviour; @@ -18,8 +19,8 @@ pub const SOLOMACHINE_MISBEHAVIOUR_TYPE_URL: &str = "/ibc.lightclients.solomachi #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, PartialEq)] pub struct Misbehaviour { - pub client_id: String, - pub sequence: u64, + pub client_id: ClientId, + pub sequence: Height, pub signature_one: Option, pub signature_two: Option, } @@ -30,13 +31,37 @@ impl TryFrom for Misbehaviour { type Error = Error; fn try_from(raw: RawSolMisbehaviour) -> Result { - todo!() + let client_id: ClientId = raw + .client_id + .parse() + .map_err(|_| Error::InvalidRawClientId { + client_id: raw.client_id.clone(), + })?; + let sequence = Height::new(0, raw.sequence).map_err(Error::InvalidHeight)?; + let signature_one: Option = + raw.signature_one.map(TryInto::try_into).transpose()?; + let signature_two: Option = + raw.signature_two.map(TryInto::try_into).transpose()?; + Ok(Self { + client_id, + sequence, + signature_one, + signature_two, + }) } } impl From for RawSolMisbehaviour { fn from(value: Misbehaviour) -> Self { - todo!() + let client_id = value.client_id.to_string(); + let sequence = value.sequence.revision_height(); + + Self { + client_id, + sequence, + signature_one: value.signature_one.map(Into::into), + signature_two: value.signature_two.map(Into::into), + } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs index cd87b31c6..4fe168d97 100644 --- a/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs @@ -1,6 +1,7 @@ use crate::clients::ics06_solomachine::error::Error; use crate::clients::ics06_solomachine::types::DataType; use crate::prelude::*; +use crate::timestamp::Timestamp; use ibc_proto::ibc::lightclients::solomachine::v1::SignatureAndData as RawSignatureAndData; use ibc_proto::protobuf::Protobuf; @@ -12,7 +13,7 @@ pub struct SignatureAndData { pub signature: Vec, pub data_type: DataType, pub data: Vec, - pub timestamp: u64, + pub timestamp: Timestamp, } impl Protobuf for SignatureAndData {} @@ -21,12 +22,27 @@ impl TryFrom for SignatureAndData { type Error = Error; fn try_from(raw: RawSignatureAndData) -> Result { - todo!() + let signature = raw.signature; + let data_type = DataType::try_from(raw.data_type)?; + let data = raw.data; + let timestamp = + Timestamp::from_nanoseconds(raw.timestamp).map_err(Error::ParseTimeError)?; + Ok(Self { + signature, + data_type, + data, + timestamp, + }) } } impl From for RawSignatureAndData { fn from(value: SignatureAndData) -> Self { - todo!() + Self { + signature: value.signature, + data_type: i32::from(value.data_type), + data: value.data, + timestamp: value.timestamp.nanoseconds(), + } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types.rs b/crates/ibc/src/clients/ics06_solomachine/types.rs index d54575deb..76b1f6c93 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types.rs @@ -41,16 +41,73 @@ pub enum DataType { Header, } -impl TryFrom for DataType { - type Error = Error; - - fn try_from(raw: RawDataType) -> Result { - todo!() +impl From for DataType { + fn from(raw: RawDataType) -> Self { + match raw { + RawDataType::UninitializedUnspecified => Self::UninitializedUnspecified, + RawDataType::ClientState => Self::ClientState, + RawDataType::ConsensusState => Self::ConsensusState, + RawDataType::ConnectionState => Self::ConnectionState, + RawDataType::ChannelState => Self::ChannelState, + RawDataType::PacketCommitment => Self::PacketCommitment, + RawDataType::PacketAcknowledgement => Self::PacketAcknowledgement, + RawDataType::PacketReceiptAbsence => Self::PacketReceiptAbsence, + RawDataType::NextSequenceRecv => Self::NextSequenceRecv, + RawDataType::Header => Self::Header, + } } } impl From for RawDataType { fn from(value: DataType) -> Self { - todo!() + match value { + DataType::UninitializedUnspecified => Self::UninitializedUnspecified, + DataType::ClientState => Self::ClientState, + DataType::ConsensusState => Self::ConsensusState, + DataType::ConnectionState => Self::ConnectionState, + DataType::ChannelState => Self::ChannelState, + DataType::PacketCommitment => Self::PacketCommitment, + DataType::PacketAcknowledgement => Self::PacketAcknowledgement, + DataType::PacketReceiptAbsence => Self::PacketReceiptAbsence, + DataType::NextSequenceRecv => Self::NextSequenceRecv, + DataType::Header => Self::Header, + } + } +} + +impl TryFrom for DataType { + type Error = Error; + fn try_from(value: i32) -> Result { + let data_type = match value { + 0 => Self::UninitializedUnspecified, + 1 => Self::ClientState, + 2 => Self::ConsensusState, + 3 => Self::ConnectionState, + 4 => Self::ChannelState, + 5 => Self::PacketCommitment, + 6 => Self::PacketAcknowledgement, + 7 => Self::PacketReceiptAbsence, + 8 => Self::NextSequenceRecv, + 9 => Self::Header, + i => return Err(Error::UnknownDataType(i)), + }; + Ok(data_type) + } +} + +impl From for i32 { + fn from(value: DataType) -> Self { + match value { + DataType::UninitializedUnspecified => 0, + DataType::ClientState => 1, + DataType::ConsensusState => 2, + DataType::ConnectionState => 3, + DataType::ChannelState => 4, + DataType::PacketCommitment => 5, + DataType::PacketAcknowledgement => 6, + DataType::PacketReceiptAbsence => 7, + DataType::NextSequenceRecv => 8, + DataType::Header => 9, + } } } From c789909ee4326186f5136598a2e1faf97203110b Mon Sep 17 00:00:00 2001 From: Davirain Date: Tue, 25 Apr 2023 20:06:39 +0800 Subject: [PATCH 12/35] Refactor ICS06 Solomachine client, consensus and packet handling --- .../src/clients/ics06_solomachine/error.rs | 3 +++ .../types/channel_state_data.rs | 14 ++++++++-- .../types/client_stata_data.rs | 5 ++-- .../types/consensus_state_data.rs | 5 ++-- .../types/next_sequence_recv_data.rs | 10 +++++-- .../types/packet_acknowledgement_data.rs | 10 +++++-- .../types/packet_commitment_data.rs | 10 +++++-- .../ics06_solomachine/types/sign_bytes.rs | 26 ++++++++++++++----- .../types/timestamped_signature_data.rs | 13 +++++++--- 9 files changed, 75 insertions(+), 21 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/error.rs b/crates/ibc/src/clients/ics06_solomachine/error.rs index b0d6c123d..8035c94e7 100644 --- a/crates/ibc/src/clients/ics06_solomachine/error.rs +++ b/crates/ibc/src/clients/ics06_solomachine/error.rs @@ -1,3 +1,4 @@ +use crate::core::ics04_channel::error::ChannelError; use crate::prelude::*; use crate::core::ics02_client::error::ClientError; @@ -20,6 +21,8 @@ pub enum Error { UnknownDataType(i32), /// prase time error ParseTimeError(ParseTimestampError), + /// Channel error: `{0}` + ChannelError(ChannelError), } impl From for ClientError { diff --git a/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs index 836a4cc93..12a39888e 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs @@ -17,12 +17,22 @@ impl TryFrom for ChannelStateData { type Error = Error; fn try_from(raw: RawChannelStateData) -> Result { - todo!() + Ok(Self { + path: raw.path, + channel: raw + .channel + .map(TryInto::try_into) + .transpose() + .map_err(Error::ChannelError)?, + }) } } impl From for RawChannelStateData { fn from(value: ChannelStateData) -> Self { - todo!() + Self { + path: value.path, + channel: value.channel.map(Into::into), + } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs index a99cff820..107f35347 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs @@ -1,6 +1,6 @@ +use crate::clients::ics06_solomachine::client_state::ClientState; use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; -use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::lightclients::solomachine::v1::ClientStateData as RawClientStateData; use ibc_proto::protobuf::Protobuf; @@ -8,7 +8,8 @@ use ibc_proto::protobuf::Protobuf; #[derive(Clone, PartialEq)] pub struct ClientStateData { pub path: Vec, - pub client_state: Option, + // Ics06 solomachine client state + pub client_state: Option, } impl Protobuf for ClientStateData {} diff --git a/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs index eca0bf847..f2f702bb3 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs @@ -1,6 +1,6 @@ +use crate::clients::ics06_solomachine::consensus_state::ConsensusState; use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; -use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::lightclients::solomachine::v1::ConsensusStateData as RawConsensusStateData; use ibc_proto::protobuf::Protobuf; @@ -10,7 +10,8 @@ use ibc_proto::protobuf::Protobuf; #[derive(Clone, PartialEq)] pub struct ConsensusStateData { pub path: Vec, - pub consensus_state: Option, + // ics06 solomachine client consensus state + pub consensus_state: Option, } impl Protobuf for ConsensusStateData {} diff --git a/crates/ibc/src/clients/ics06_solomachine/types/next_sequence_recv_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/next_sequence_recv_data.rs index ef7fb8402..2c83d9c65 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/next_sequence_recv_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/next_sequence_recv_data.rs @@ -18,12 +18,18 @@ impl TryFrom for NextSequenceRecvData { type Error = Error; fn try_from(raw: RawNextSequenceRecvData) -> Result { - todo!() + Ok(Self { + path: raw.path, + next_seq_recv: raw.next_seq_recv, + }) } } impl From for RawNextSequenceRecvData { fn from(value: NextSequenceRecvData) -> Self { - todo!() + Self { + path: value.path, + next_seq_recv: value.next_seq_recv, + } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/packet_acknowledgement_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/packet_acknowledgement_data.rs index 826fe8121..56a712846 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/packet_acknowledgement_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/packet_acknowledgement_data.rs @@ -17,12 +17,18 @@ impl TryFrom for PacketAcknowledgementData { type Error = Error; fn try_from(raw: RawPacketAcknowledgementData) -> Result { - todo!() + Ok(Self { + path: raw.path, + acknowledgement: raw.acknowledgement, + }) } } impl From for RawPacketAcknowledgementData { fn from(value: PacketAcknowledgementData) -> Self { - todo!() + Self { + path: value.path, + acknowledgement: value.acknowledgement, + } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/packet_commitment_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/packet_commitment_data.rs index dc7196b99..1c13aae2c 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/packet_commitment_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/packet_commitment_data.rs @@ -17,12 +17,18 @@ impl TryFrom for PacketCommitmentData { type Error = Error; fn try_from(raw: RawPacketCommitmentData) -> Result { - todo!() + Ok(Self { + path: raw.path, + commitment: raw.commitment, + }) } } impl From for RawPacketCommitmentData { fn from(value: PacketCommitmentData) -> Self { - todo!() + Self { + path: value.path, + commitment: value.commitment, + } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs b/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs index a44ffb55a..1736df266 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs @@ -1,7 +1,9 @@ use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; +use crate::timestamp::Timestamp; use ibc_proto::ibc::lightclients::solomachine::v1::SignBytes as RawSignBytes; -use ibc_proto::ibc::lightclients::solomachine::v1::TimestampedSignatureData as RawTimestampedSignatureData; + +use super::DataType; // use ibc_proto::protobuf::Protobuf; /// SignBytes defines the signed bytes used for signature verification. @@ -9,10 +11,10 @@ use ibc_proto::ibc::lightclients::solomachine::v1::TimestampedSignatureData as R #[derive(Clone, PartialEq)] pub struct SignBytes { pub sequence: u64, - pub timestamp: u64, + pub timestamp: Timestamp, pub diversifier: String, /// type of the data used - pub data_type: i32, + pub data_type: DataType, /// marshaled data pub data: Vec, } @@ -23,12 +25,24 @@ impl TryFrom for SignBytes { type Error = Error; fn try_from(raw: RawSignBytes) -> Result { - todo!() + Ok(Self { + sequence: raw.sequence, + timestamp: Timestamp::from_nanoseconds(raw.timestamp).map_err(Error::ParseTimeError)?, + diversifier: raw.diversifier, + data_type: DataType::try_from(raw.data_type)?, + data: raw.data, + }) } } -impl From for RawTimestampedSignatureData { +impl From for RawSignBytes { fn from(value: SignBytes) -> Self { - todo!() + Self { + sequence: value.sequence, + timestamp: value.timestamp.nanoseconds(), + diversifier: value.diversifier, + data_type: i32::from(value.data_type), + data: value.data, + } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs index 6c8e4c13b..6120d4a96 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs @@ -1,5 +1,6 @@ use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; +use crate::timestamp::Timestamp; use ibc_proto::ibc::lightclients::solomachine::v1::TimestampedSignatureData as RawTimestampedSignatureData; use ibc_proto::protobuf::Protobuf; @@ -9,7 +10,7 @@ use ibc_proto::protobuf::Protobuf; #[derive(Clone, PartialEq)] pub struct TimestampedSignatureData { pub signature_data: Vec, - pub timestamp: u64, + pub timestamp: Timestamp, } impl Protobuf for TimestampedSignatureData {} @@ -18,12 +19,18 @@ impl TryFrom for TimestampedSignatureData { type Error = Error; fn try_from(raw: RawTimestampedSignatureData) -> Result { - todo!() + Ok(Self { + signature_data: raw.signature_data, + timestamp: Timestamp::from_nanoseconds(raw.timestamp).map_err(Error::ParseTimeError)?, + }) } } impl From for RawTimestampedSignatureData { fn from(value: TimestampedSignatureData) -> Self { - todo!() + Self { + signature_data: value.signature_data, + timestamp: value.timestamp.nanoseconds(), + } } } From 4a33419a3486279a4acbd36bc6c30b885713c2fd Mon Sep 17 00:00:00 2001 From: Davirain Date: Tue, 9 May 2023 16:54:51 +0800 Subject: [PATCH 13/35] Update Cargo.toml --- crates/ibc/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ibc/Cargo.toml b/crates/ibc/Cargo.toml index 8e78355ee..4424a4632 100644 --- a/crates/ibc/Cargo.toml +++ b/crates/ibc/Cargo.toml @@ -35,7 +35,7 @@ mocks-no-std = ["cfg-if"] [dependencies] # Proto definitions for all IBC-related interfaces, e.g., connections or channels. -ibc-proto = { version = "0.26.0", default-features = false, features = ["parity-scale-codec", "borsh"] } +ibc-proto = { default-features = false, features = ["parity-scale-codec", "borsh"], git = "https://github.com/octopus-network/ibc-proto-rs.git", rev = "e9fb075d666bf49e491e3d338e5af98aa7b2b73e"} ics23 = { version = "0.9.0", default-features = false, features = ["host-functions"] } time = { version = ">=0.3.0, <0.3.21", default-features = false } serde_derive = { version = "1.0.104", default-features = false, optional = true } @@ -61,7 +61,7 @@ scale-info = { version = "2.1.2", default-features = false, features = ["derive" borsh = {version = "0.10.0", default-features = false, optional = true } parking_lot = { version = "0.12.1", default-features = false, optional = true } cfg-if = { version = "1.0.0", optional = true } -cosmrs = "0.13.0" +cosmrs = { version = "0.14", default-features = false, git = "https://github.com/octopus-network/cosmos-rust.git", branch = "new-proto" } [dependencies.tendermint] version = "0.29" From 4e87748f3241d31f42d01f15f8738c6c1a320ca7 Mon Sep 17 00:00:00 2001 From: Davirain Date: Tue, 9 May 2023 17:40:09 +0800 Subject: [PATCH 14/35] refactor(ibc): Update dependencies and fix import errors in ics06_solomachine module --- crates/ibc/Cargo.toml | 4 ++-- .../ibc/src/clients/ics06_solomachine/client_state.rs | 10 ++++------ .../src/clients/ics06_solomachine/consensus_state.rs | 5 ++--- crates/ibc/src/clients/ics06_solomachine/error.rs | 2 +- crates/ibc/src/clients/ics06_solomachine/header.rs | 5 ++--- .../ibc/src/clients/ics06_solomachine/misbehaviour.rs | 3 +-- .../misbehaviour/signature_and_data.rs | 2 +- crates/ibc/src/clients/ics06_solomachine/mod.rs | 2 +- .../src/clients/ics06_solomachine/types/sign_bytes.rs | 2 +- .../types/timestamped_signature_data.rs | 2 +- 10 files changed, 16 insertions(+), 21 deletions(-) diff --git a/crates/ibc/Cargo.toml b/crates/ibc/Cargo.toml index b8e5038fe..08e489eb8 100644 --- a/crates/ibc/Cargo.toml +++ b/crates/ibc/Cargo.toml @@ -35,7 +35,7 @@ mocks-no-std = ["cfg-if"] [dependencies] # Proto definitions for all IBC-related interfaces, e.g., connections or channels. -ibc-proto = { default-features = false, features = ["parity-scale-codec", "borsh"], git = "https://github.com/octopus-network/ibc-proto-rs.git", rev = "e9fb075d666bf49e491e3d338e5af98aa7b2b73e"} +ibc-proto = {version = "0.29.0", default-features = false, features = ["parity-scale-codec", "borsh"] } ics23 = { version = "0.9.0", default-features = false, features = ["host-functions"] } time = { version = ">=0.3.0, <0.3.21", default-features = false } serde_derive = { version = "1.0.104", default-features = false, optional = true } @@ -61,7 +61,7 @@ scale-info = { version = "2.1.2", default-features = false, features = ["derive" borsh = {version = "0.10.0", default-features = false, optional = true } parking_lot = { version = "0.12.1", default-features = false, optional = true } cfg-if = { version = "1.0.0", optional = true } -cosmrs = { version = "0.14", default-features = false, git = "https://github.com/octopus-network/cosmos-rust.git", branch = "new-proto" } +cosmrs = { version = "0.13" } [dependencies.tendermint] version = "0.30" diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index 002b97254..407adc2d6 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -1,15 +1,15 @@ use crate::clients::ics06_solomachine::consensus_state::ConsensusState as SoloMachineConsensusState; use crate::clients::ics06_solomachine::error::Error; +use crate::core::ics02_client::client_state::UpdateKind; use crate::core::ics02_client::client_state::{ClientState as Ics2ClientState, UpdatedState}; use crate::core::ics02_client::client_type::ClientType; use crate::core::ics02_client::consensus_state::ConsensusState; use crate::core::ics02_client::error::ClientError; -use crate::core::ics02_client::msgs::update_client::UpdateKind; use crate::core::ics23_commitment::commitment::{ CommitmentPrefix, CommitmentProofBytes, CommitmentRoot, }; use crate::core::ics24_host::identifier::{ChainId, ClientId}; -use crate::core::ics24_host::Path; +use crate::core::ics24_host::path::Path; use crate::core::{ExecutionContext, ValidationContext}; use crate::prelude::*; use crate::Height; @@ -149,8 +149,7 @@ impl Ics2ClientState for ClientState { &self, ctx: &mut dyn ExecutionContext, client_id: &ClientId, - client_message: Any, - update_kind: &UpdateKind, + header: Any, ) -> Result, ClientError> { todo!() } @@ -296,8 +295,7 @@ impl From for Any { fn from(client_state: ClientState) -> Self { Any { type_url: SOLOMACHINE_CLIENT_STATE_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&client_state) - .expect("encoding to `Any` from `RawSolClientState`"), + value: Protobuf::::encode_vec(&client_state), } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs index 965ac01b6..296628cf8 100644 --- a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs @@ -1,8 +1,8 @@ use crate::clients::ics06_solomachine::error::Error; use crate::core::ics02_client::error::ClientError; use crate::core::ics23_commitment::commitment::CommitmentRoot; +use crate::core::timestamp::Timestamp; use crate::prelude::*; -use crate::timestamp::Timestamp; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::lightclients::solomachine::v1::ConsensusState as RawSolConsensusState; use ibc_proto::protobuf::Protobuf; @@ -114,8 +114,7 @@ impl From for Any { fn from(consensus_state: ConsensusState) -> Self { Any { type_url: SOLOMACHINE_CONSENSUS_STATE_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&consensus_state) - .expect("encoding to `Any` from `RawSolConsensusState`"), + value: Protobuf::::encode_vec(&consensus_state), } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/error.rs b/crates/ibc/src/clients/ics06_solomachine/error.rs index 8035c94e7..027d9d5e6 100644 --- a/crates/ibc/src/clients/ics06_solomachine/error.rs +++ b/crates/ibc/src/clients/ics06_solomachine/error.rs @@ -2,7 +2,7 @@ use crate::core::ics04_channel::error::ChannelError; use crate::prelude::*; use crate::core::ics02_client::error::ClientError; -use crate::timestamp::ParseTimestampError; +use crate::core::timestamp::ParseTimestampError; use displaydoc::Display; #[derive(Debug, Display)] diff --git a/crates/ibc/src/clients/ics06_solomachine/header.rs b/crates/ibc/src/clients/ics06_solomachine/header.rs index 0fbb6b0fe..e4e206788 100644 --- a/crates/ibc/src/clients/ics06_solomachine/header.rs +++ b/crates/ibc/src/clients/ics06_solomachine/header.rs @@ -1,7 +1,7 @@ use crate::clients::ics06_solomachine::error::Error; use crate::core::ics02_client::error::ClientError; +use crate::core::timestamp::Timestamp; use crate::prelude::*; -use crate::timestamp::Timestamp; use crate::Height; use bytes::Buf; use core::fmt::{Display, Error as FmtError, Formatter}; @@ -82,8 +82,7 @@ impl From
for Any { fn from(header: Header) -> Self { Any { type_url: SOLOMACHINE_HEADER_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&header) - .expect("encoding to `Any` from `TmHeader`"), + value: Protobuf::::encode_vec(&header), } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs index 3588e4c42..4a276fcef 100644 --- a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs @@ -94,8 +94,7 @@ impl From for Any { fn from(misbehaviour: Misbehaviour) -> Self { Any { type_url: SOLOMACHINE_MISBEHAVIOUR_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&misbehaviour) - .expect("encoding to `Any` from `RawSolMisbehaviour`"), + value: Protobuf::::encode_vec(&misbehaviour), } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs index 4fe168d97..ba9d481b4 100644 --- a/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs @@ -1,7 +1,7 @@ use crate::clients::ics06_solomachine::error::Error; use crate::clients::ics06_solomachine::types::DataType; +use crate::core::timestamp::Timestamp; use crate::prelude::*; -use crate::timestamp::Timestamp; use ibc_proto::ibc::lightclients::solomachine::v1::SignatureAndData as RawSignatureAndData; use ibc_proto::protobuf::Protobuf; diff --git a/crates/ibc/src/clients/ics06_solomachine/mod.rs b/crates/ibc/src/clients/ics06_solomachine/mod.rs index 81eb536ca..33c146f26 100644 --- a/crates/ibc/src/clients/ics06_solomachine/mod.rs +++ b/crates/ibc/src/clients/ics06_solomachine/mod.rs @@ -12,5 +12,5 @@ pub mod types; pub(crate) const SOLOMACHINE_CLIENT_TYPE: &str = "07-solomachine"; pub fn client_type() -> ClientType { - ClientType::new(SOLOMACHINE_CLIENT_TYPE.to_string()) + ClientType::from(SOLOMACHINE_CLIENT_TYPE.to_string()) } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs b/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs index 1736df266..95aa63392 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs @@ -1,6 +1,6 @@ use crate::clients::ics06_solomachine::error::Error; +use crate::core::timestamp::Timestamp; use crate::prelude::*; -use crate::timestamp::Timestamp; use ibc_proto::ibc::lightclients::solomachine::v1::SignBytes as RawSignBytes; use super::DataType; diff --git a/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs index 6120d4a96..5356740eb 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs @@ -1,6 +1,6 @@ use crate::clients::ics06_solomachine::error::Error; +use crate::core::timestamp::Timestamp; use crate::prelude::*; -use crate::timestamp::Timestamp; use ibc_proto::ibc::lightclients::solomachine::v1::TimestampedSignatureData as RawTimestampedSignatureData; use ibc_proto::protobuf::Protobuf; From dd58a94815ccd7d5b3261d5b5f7c00133758a1fe Mon Sep 17 00:00:00 2001 From: Davirain Date: Wed, 10 May 2023 15:36:00 +0800 Subject: [PATCH 15/35] Add new IBC Proto version v0.29.0 from the new-proto-v0.29.0 branch. --- crates/ibc/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ibc/Cargo.toml b/crates/ibc/Cargo.toml index 08e489eb8..558692a23 100644 --- a/crates/ibc/Cargo.toml +++ b/crates/ibc/Cargo.toml @@ -35,7 +35,7 @@ mocks-no-std = ["cfg-if"] [dependencies] # Proto definitions for all IBC-related interfaces, e.g., connections or channels. -ibc-proto = {version = "0.29.0", default-features = false, features = ["parity-scale-codec", "borsh"] } +ibc-proto = {version = "0.29.0", default-features = false, features = ["parity-scale-codec", "borsh"], git = "https://github.com/octopus-network/ibc-proto-rs.git", branch = "new-proto-v0.29.0" } ics23 = { version = "0.9.0", default-features = false, features = ["host-functions"] } time = { version = ">=0.3.0, <0.3.21", default-features = false } serde_derive = { version = "1.0.104", default-features = false, optional = true } From 0d64b86b7354cb20b88622546a6550b9e23dee90 Mon Sep 17 00:00:00 2001 From: Davirain Date: Thu, 11 May 2023 20:53:54 +0800 Subject: [PATCH 16/35] Add 'cosmrs' v0.12.0, disable default feature, and point git to octopus-network/cosmos-rust repo (new-proto-v0.12.0 branch). --- crates/ibc/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ibc/Cargo.toml b/crates/ibc/Cargo.toml index 558692a23..e59f27969 100644 --- a/crates/ibc/Cargo.toml +++ b/crates/ibc/Cargo.toml @@ -18,7 +18,7 @@ all-features = true [features] default = ["std"] -std = ["ibc-proto/std", "ics23/std", "serde/std", "serde_json/std", "erased-serde/std", "tracing/std", "prost/std", "bytes/std", "subtle-encoding/std", "sha2/std", "displaydoc/std", "num-traits/std", "uint/std", "primitive-types/std", "tendermint/clock", "tendermint/std"] +std = ["ibc-proto/std", "ics23/std", "serde/std", "serde_json/std", "erased-serde/std", "tracing/std", "prost/std", "bytes/std", "subtle-encoding/std", "sha2/std", "displaydoc/std", "num-traits/std", "uint/std", "primitive-types/std", "tendermint/clock", "tendermint/std", "cosmrs/std"] parity-scale-codec = ["dep:parity-scale-codec", "dep:scale-info"] borsh = ["dep:borsh"] @@ -61,7 +61,7 @@ scale-info = { version = "2.1.2", default-features = false, features = ["derive" borsh = {version = "0.10.0", default-features = false, optional = true } parking_lot = { version = "0.12.1", default-features = false, optional = true } cfg-if = { version = "1.0.0", optional = true } -cosmrs = { version = "0.13" } +cosmrs = { version = "0.12.0", default-feature = false, git = "https://github.com/octopus-network/cosmos-rust.git", branch = "new-proto-v0.12.0" } [dependencies.tendermint] version = "0.30" From b37184ae0a6497b4ef2f268c3ad0d35849a6d579 Mon Sep 17 00:00:00 2001 From: Davirain Date: Thu, 11 May 2023 21:29:53 +0800 Subject: [PATCH 17/35] Updated ibc_proto to v2 and added a boolean `is_frozen` to `ClientState`. Updated the proto file imports in all related files. --- .../clients/ics06_solomachine/client_state.rs | 27 +++++++------------ .../ics06_solomachine/consensus_state.rs | 2 +- .../src/clients/ics06_solomachine/header.rs | 2 +- .../clients/ics06_solomachine/misbehaviour.rs | 2 +- .../misbehaviour/signature_and_data.rs | 2 +- .../src/clients/ics06_solomachine/types.rs | 2 +- .../types/channel_state_data.rs | 2 +- .../types/client_stata_data.rs | 2 +- .../types/connection_state_data.rs | 2 +- .../types/consensus_state_data.rs | 2 +- .../ics06_solomachine/types/header_data.rs | 2 +- .../types/next_sequence_recv_data.rs | 2 +- .../types/packet_acknowledgement_data.rs | 2 +- .../types/packet_commitment_data.rs | 2 +- .../types/packet_receipt_absence_data.rs | 2 +- .../ics06_solomachine/types/sign_bytes.rs | 2 +- .../types/timestamped_signature_data.rs | 2 +- 17 files changed, 25 insertions(+), 34 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index 407adc2d6..7f30ffdad 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -16,7 +16,7 @@ use crate::Height; use core::time::Duration; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::commitment::v1::MerkleProof as RawMerkleProof; -use ibc_proto::ibc::lightclients::solomachine::v1::ClientState as RawSolClientState; +use ibc_proto::ibc::lightclients::solomachine::v2::ClientState as RawSolClientState; use ibc_proto::protobuf::Protobuf; use prost::Message; @@ -30,7 +30,7 @@ pub struct ClientState { /// latest sequence of the client state pub sequence: Height, /// frozen sequence of the solo machine - pub frozen_sequence: Option, + pub is_frozen: bool, pub consensus_state: Option, /// when set to true, will allow governance to update a solo machine client. /// The client will be unfrozen if it is frozen. @@ -41,13 +41,13 @@ impl ClientState { /// Create a new ClientState Instance. pub fn new( sequence: Height, - frozen_sequence: Option, + is_frozen: bool, consensus_state: Option, allow_update_after_proposal: bool, ) -> Self { Self { sequence, - frozen_sequence, + is_frozen, consensus_state, allow_update_after_proposal, } @@ -84,9 +84,9 @@ impl Ics2ClientState for ClientState { /// Assert that the client is not frozen fn confirm_not_frozen(&self) -> Result<(), ClientError> { - if let Some(frozen_height) = self.frozen_sequence { + if self.is_frozen { return Err(ClientError::ClientFrozen { - description: format!("the client is frozen at height {frozen_height}"), + description: format!("the client is frozen"), }); } Ok(()) @@ -229,18 +229,13 @@ impl TryFrom for ClientState { fn try_from(raw: RawSolClientState) -> Result { let sequence = Height::new(0, raw.sequence).map_err(Error::InvalidHeight)?; - let frozen_sequence = if raw.frozen_sequence == 0 { - None - } else { - Some(Height::new(0, raw.frozen_sequence).map_err(Error::InvalidHeight)?) - }; let consensus_state: Option = raw.consensus_state.map(TryInto::try_into).transpose()?; Ok(Self { sequence, - frozen_sequence, + is_frozen: raw.is_frozen, consensus_state, allow_update_after_proposal: raw.allow_update_after_proposal, }) @@ -250,15 +245,11 @@ impl TryFrom for ClientState { impl From for RawSolClientState { fn from(value: ClientState) -> Self { let sequence = value.sequence.revision_height(); - let frozen_sequence = if let Some(seq) = value.frozen_sequence { - seq.revision_height() - } else { - 0 - }; + let consensus_state = value.consensus_state.map(Into::into); Self { sequence, - frozen_sequence, + is_frozen: value.is_frozen, consensus_state, allow_update_after_proposal: value.allow_update_after_proposal, } diff --git a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs index 296628cf8..c4069d4f1 100644 --- a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs @@ -4,7 +4,7 @@ use crate::core::ics23_commitment::commitment::CommitmentRoot; use crate::core::timestamp::Timestamp; use crate::prelude::*; use ibc_proto::google::protobuf::Any; -use ibc_proto::ibc::lightclients::solomachine::v1::ConsensusState as RawSolConsensusState; +use ibc_proto::ibc::lightclients::solomachine::v2::ConsensusState as RawSolConsensusState; use ibc_proto::protobuf::Protobuf; use prost::Message; diff --git a/crates/ibc/src/clients/ics06_solomachine/header.rs b/crates/ibc/src/clients/ics06_solomachine/header.rs index e4e206788..f48fa8936 100644 --- a/crates/ibc/src/clients/ics06_solomachine/header.rs +++ b/crates/ibc/src/clients/ics06_solomachine/header.rs @@ -6,7 +6,7 @@ use crate::Height; use bytes::Buf; use core::fmt::{Display, Error as FmtError, Formatter}; use ibc_proto::google::protobuf::Any; -use ibc_proto::ibc::lightclients::solomachine::v1::Header as RawSolHeader; +use ibc_proto::ibc::lightclients::solomachine::v2::Header as RawSolHeader; use ibc_proto::protobuf::Protobuf; use prost::Message; pub const SOLOMACHINE_HEADER_TYPE_URL: &str = "/ibc.lightclients.solomachine.v1.Header"; diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs index 4a276fcef..184c48c20 100644 --- a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs @@ -4,7 +4,7 @@ use crate::core::ics24_host::identifier::ClientId; use crate::{prelude::*, Height}; use bytes::Buf; use ibc_proto::google::protobuf::Any; -use ibc_proto::ibc::lightclients::solomachine::v1::Misbehaviour as RawSolMisbehaviour; +use ibc_proto::ibc::lightclients::solomachine::v2::Misbehaviour as RawSolMisbehaviour; use ibc_proto::protobuf::Protobuf; use prost::Message; diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs index ba9d481b4..24ceb9012 100644 --- a/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs @@ -2,7 +2,7 @@ use crate::clients::ics06_solomachine::error::Error; use crate::clients::ics06_solomachine::types::DataType; use crate::core::timestamp::Timestamp; use crate::prelude::*; -use ibc_proto::ibc::lightclients::solomachine::v1::SignatureAndData as RawSignatureAndData; +use ibc_proto::ibc::lightclients::solomachine::v2::SignatureAndData as RawSignatureAndData; use ibc_proto::protobuf::Protobuf; /// SignatureAndData contains a signature and the data signed over to create that diff --git a/crates/ibc/src/clients/ics06_solomachine/types.rs b/crates/ibc/src/clients/ics06_solomachine/types.rs index 76b1f6c93..54f84a544 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types.rs @@ -1,6 +1,6 @@ use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; -use ibc_proto::ibc::lightclients::solomachine::v1::DataType as RawDataType; +use ibc_proto::ibc::lightclients::solomachine::v2::DataType as RawDataType; pub mod channel_state_data; pub mod client_stata_data; diff --git a/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs index 12a39888e..7b27ef73c 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs @@ -1,7 +1,7 @@ use crate::clients::ics06_solomachine::error::Error; use crate::core::ics04_channel::channel::ChannelEnd; use crate::prelude::*; -use ibc_proto::ibc::lightclients::solomachine::v1::ChannelStateData as RawChannelStateData; +use ibc_proto::ibc::lightclients::solomachine::v2::ChannelStateData as RawChannelStateData; use ibc_proto::protobuf::Protobuf; /// ChannelStateData returns the SignBytes data for channel state diff --git a/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs index 107f35347..6dc8288fa 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs @@ -1,7 +1,7 @@ use crate::clients::ics06_solomachine::client_state::ClientState; use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; -use ibc_proto::ibc::lightclients::solomachine::v1::ClientStateData as RawClientStateData; +use ibc_proto::ibc::lightclients::solomachine::v2::ClientStateData as RawClientStateData; use ibc_proto::protobuf::Protobuf; /// ClientStateData returns the SignBytes data for client state verification. diff --git a/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs index dc6f1fcec..712c5522f 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs @@ -1,7 +1,7 @@ use crate::clients::ics06_solomachine::error::Error; use crate::core::ics03_connection::connection::ConnectionEnd; use crate::prelude::*; -use ibc_proto::ibc::lightclients::solomachine::v1::ConnectionStateData as RawConnectionStateData; +use ibc_proto::ibc::lightclients::solomachine::v2::ConnectionStateData as RawConnectionStateData; use ibc_proto::protobuf::Protobuf; /// ConnectionStateData returns the SignBytes data for connection state diff --git a/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs index f2f702bb3..78ba4de2f 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs @@ -1,7 +1,7 @@ use crate::clients::ics06_solomachine::consensus_state::ConsensusState; use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; -use ibc_proto::ibc::lightclients::solomachine::v1::ConsensusStateData as RawConsensusStateData; +use ibc_proto::ibc::lightclients::solomachine::v2::ConsensusStateData as RawConsensusStateData; use ibc_proto::protobuf::Protobuf; /// ConsensusStateData returns the SignBytes data for consensus state diff --git a/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs index 7bdcac6e4..8d1aec34d 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs @@ -1,7 +1,7 @@ use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; use ibc_proto::google::protobuf::Any; -use ibc_proto::ibc::lightclients::solomachine::v1::HeaderData as RawHeaderData; +use ibc_proto::ibc::lightclients::solomachine::v2::HeaderData as RawHeaderData; use ibc_proto::protobuf::Protobuf; /// HeaderData returns the SignBytes data for update verification. diff --git a/crates/ibc/src/clients/ics06_solomachine/types/next_sequence_recv_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/next_sequence_recv_data.rs index 2c83d9c65..3b1e4e4bc 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/next_sequence_recv_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/next_sequence_recv_data.rs @@ -1,6 +1,6 @@ use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; -use ibc_proto::ibc::lightclients::solomachine::v1::NextSequenceRecvData as RawNextSequenceRecvData; +use ibc_proto::ibc::lightclients::solomachine::v2::NextSequenceRecvData as RawNextSequenceRecvData; use ibc_proto::protobuf::Protobuf; /// NextSequenceRecvData returns the SignBytes data for verification of the next diff --git a/crates/ibc/src/clients/ics06_solomachine/types/packet_acknowledgement_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/packet_acknowledgement_data.rs index 56a712846..6b3d7398a 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/packet_acknowledgement_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/packet_acknowledgement_data.rs @@ -1,6 +1,6 @@ use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; -use ibc_proto::ibc::lightclients::solomachine::v1::PacketAcknowledgementData as RawPacketAcknowledgementData; +use ibc_proto::ibc::lightclients::solomachine::v2::PacketAcknowledgementData as RawPacketAcknowledgementData; use ibc_proto::protobuf::Protobuf; /// PacketAcknowledgementData returns the SignBytes data for acknowledgement diff --git a/crates/ibc/src/clients/ics06_solomachine/types/packet_commitment_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/packet_commitment_data.rs index 1c13aae2c..20f506ea0 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/packet_commitment_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/packet_commitment_data.rs @@ -1,6 +1,6 @@ use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; -use ibc_proto::ibc::lightclients::solomachine::v1::PacketCommitmentData as RawPacketCommitmentData; +use ibc_proto::ibc::lightclients::solomachine::v2::PacketCommitmentData as RawPacketCommitmentData; use ibc_proto::protobuf::Protobuf; /// PacketCommitmentData returns the SignBytes data for packet commitment diff --git a/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs index becf4d558..7a37850de 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs @@ -1,6 +1,6 @@ use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; -use ibc_proto::ibc::lightclients::solomachine::v1::PacketReceiptAbsenceData as RawPacketReceiptAbsenceData; +use ibc_proto::ibc::lightclients::solomachine::v2::PacketReceiptAbsenceData as RawPacketReceiptAbsenceData; use ibc_proto::protobuf::Protobuf; /// PacketReceiptAbsenceData returns the SignBytes data for diff --git a/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs b/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs index 95aa63392..a12ca48df 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs @@ -1,7 +1,7 @@ use crate::clients::ics06_solomachine::error::Error; use crate::core::timestamp::Timestamp; use crate::prelude::*; -use ibc_proto::ibc::lightclients::solomachine::v1::SignBytes as RawSignBytes; +use ibc_proto::ibc::lightclients::solomachine::v2::SignBytes as RawSignBytes; use super::DataType; // use ibc_proto::protobuf::Protobuf; diff --git a/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs index 5356740eb..28df633f4 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/timestamped_signature_data.rs @@ -1,7 +1,7 @@ use crate::clients::ics06_solomachine::error::Error; use crate::core::timestamp::Timestamp; use crate::prelude::*; -use ibc_proto::ibc::lightclients::solomachine::v1::TimestampedSignatureData as RawTimestampedSignatureData; +use ibc_proto::ibc::lightclients::solomachine::v2::TimestampedSignatureData as RawTimestampedSignatureData; use ibc_proto::protobuf::Protobuf; /// TimestampedSignatureData contains the signature data and the timestamp of the From ea86c555469352f5bdc3a7564aeef2da579c0c8b Mon Sep 17 00:00:00 2001 From: Davirain Date: Fri, 12 May 2023 10:24:22 +0800 Subject: [PATCH 18/35] fix(ibc): Public Key type inconsistency in ICS06 SoloMachine --- crates/ibc/Cargo.toml | 1 + .../ics06_solomachine/consensus_state.rs | 53 ++++++++++++------- .../src/clients/ics06_solomachine/error.rs | 8 +++ 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/crates/ibc/Cargo.toml b/crates/ibc/Cargo.toml index e59f27969..bba464c25 100644 --- a/crates/ibc/Cargo.toml +++ b/crates/ibc/Cargo.toml @@ -62,6 +62,7 @@ borsh = {version = "0.10.0", default-features = false, optional = true } parking_lot = { version = "0.12.1", default-features = false, optional = true } cfg-if = { version = "1.0.0", optional = true } cosmrs = { version = "0.12.0", default-feature = false, git = "https://github.com/octopus-network/cosmos-rust.git", branch = "new-proto-v0.12.0" } +eyre = { version = "0.6", default-features = false } [dependencies.tendermint] version = "0.30" diff --git a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs index c4069d4f1..a663ae496 100644 --- a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs @@ -3,6 +3,7 @@ use crate::core::ics02_client::error::ClientError; use crate::core::ics23_commitment::commitment::CommitmentRoot; use crate::core::timestamp::Timestamp; use crate::prelude::*; +use cosmrs::crypto::PublicKey; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::lightclients::solomachine::v2::ConsensusState as RawSolConsensusState; use ibc_proto::protobuf::Protobuf; @@ -18,7 +19,7 @@ pub const SOLOMACHINE_CONSENSUS_STATE_TYPE_URL: &str = #[derive(Clone, PartialEq, Debug)] pub struct ConsensusState { /// public key of the solo machine - pub public_key: Option, + pub public_key: PublicKey, /// diversifier allows the same public key to be re-used across different solo /// machine clients (potentially on different chains) without being considered /// misbehaviour. @@ -27,7 +28,7 @@ pub struct ConsensusState { } impl ConsensusState { - pub fn new(public_key: Option, diversifier: String, timestamp: Timestamp) -> Self { + pub fn new(public_key: PublicKey, diversifier: String, timestamp: Timestamp) -> Self { Self { public_key, diversifier, @@ -36,25 +37,24 @@ impl ConsensusState { } pub fn valida_basic(&self) -> Result<(), Error> { - todo!() + if self.timestamp.into_tm_time().is_none() { + return Err(Error::TimeStampIsEmpty); + } + + if !self.diversifier.is_empty() && self.diversifier.trim().is_empty() { + return Err(Error::DriversifierContainOnlySpaces); + } + + let _ = self.public_key(); + + Ok(()) } // GetPubKey unmarshals the public key into a cryptotypes.PubKey type. // An error is returned if the public key is nil or the cached value // is not a PubKey. - - // publicKey, ok := cs.PublicKey.GetCachedValue().(cryptotypes.PubKey) - // if !ok { - // return nil, errorsmod.Wrap(clienttypes.ErrInvalidConsensus, "consensus state PublicKey is not cryptotypes.PubKey") - // } - - // return publicKey, nil - // } - pub fn public_key(&self) -> Result<(), Error> { - if self.public_key.is_none() { - return Err(Error::EmptyConsensusStatePublicKey); - } - todo!() + pub fn public_key(&self) -> PublicKey { + self.public_key } } @@ -74,13 +74,30 @@ impl TryFrom for ConsensusState { type Error = Error; fn try_from(raw: RawSolConsensusState) -> Result { - todo!() + let public_key = PublicKey::try_from(raw.public_key.ok_or(Error::PublicKeyIsEmpty)?) + .map_err(Error::PublicKeyParseFailed)?; + let timestamp = + Timestamp::from_nanoseconds(raw.timestamp).map_err(Error::ParseTimeError)?; + Ok(Self { + public_key, + diversifier: raw.diversifier, + timestamp, + }) } } impl From for RawSolConsensusState { fn from(value: ConsensusState) -> Self { - todo!() + let public_key = value + .public_key + .to_any() + .expect("conver public key to any enver failed"); + let timestamp = value.timestamp.nanoseconds(); + Self { + public_key: Some(public_key), + diversifier: value.diversifier, + timestamp, + } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/error.rs b/crates/ibc/src/clients/ics06_solomachine/error.rs index 027d9d5e6..a616c3a90 100644 --- a/crates/ibc/src/clients/ics06_solomachine/error.rs +++ b/crates/ibc/src/clients/ics06_solomachine/error.rs @@ -23,6 +23,14 @@ pub enum Error { ParseTimeError(ParseTimestampError), /// Channel error: `{0}` ChannelError(ChannelError), + /// timestamp cannot be 0 + TimeStampIsEmpty, + /// diversifier cannot contain only spaces + DriversifierContainOnlySpaces, + /// public key parsed failed: `{0}` + PublicKeyParseFailed(eyre::ErrReport), + /// public key is empty + PublicKeyIsEmpty, } impl From for ClientError { From b431817f7b86f7ba7b64a023a9756389ceb08f0a Mon Sep 17 00:00:00 2001 From: Davirain Date: Fri, 12 May 2023 10:40:04 +0800 Subject: [PATCH 19/35] Add SoloMachineConsensusState to ClientState and implement get timestamp method --- .../clients/ics06_solomachine/client_state.rs | 21 ++++++++++++------- .../ics06_solomachine/consensus_state.rs | 1 + .../src/clients/ics06_solomachine/error.rs | 2 ++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index 7f30ffdad..f5725815d 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -10,6 +10,7 @@ use crate::core::ics23_commitment::commitment::{ }; use crate::core::ics24_host::identifier::{ChainId, ClientId}; use crate::core::ics24_host::path::Path; +use crate::core::timestamp::Timestamp; use crate::core::{ExecutionContext, ValidationContext}; use crate::prelude::*; use crate::Height; @@ -31,7 +32,7 @@ pub struct ClientState { pub sequence: Height, /// frozen sequence of the solo machine pub is_frozen: bool, - pub consensus_state: Option, + pub consensus_state: SoloMachineConsensusState, /// when set to true, will allow governance to update a solo machine client. /// The client will be unfrozen if it is frozen. pub allow_update_after_proposal: bool, @@ -42,7 +43,7 @@ impl ClientState { pub fn new( sequence: Height, is_frozen: bool, - consensus_state: Option, + consensus_state: SoloMachineConsensusState, allow_update_after_proposal: bool, ) -> Self { Self { @@ -58,6 +59,11 @@ impl ClientState { pub fn latest_height(&self) -> Height { self.sequence } + + // GetTimestampAtHeight returns the timestamp in nanoseconds of the consensus state at the given height. + pub fn time_stamp(&self) -> Timestamp { + self.consensus_state.timestamp + } } impl Ics2ClientState for ClientState { @@ -86,7 +92,7 @@ impl Ics2ClientState for ClientState { fn confirm_not_frozen(&self) -> Result<(), ClientError> { if self.is_frozen { return Err(ClientError::ClientFrozen { - description: format!("the client is frozen"), + description: "the client is frozen".into(), }); } Ok(()) @@ -230,8 +236,10 @@ impl TryFrom for ClientState { fn try_from(raw: RawSolClientState) -> Result { let sequence = Height::new(0, raw.sequence).map_err(Error::InvalidHeight)?; - let consensus_state: Option = - raw.consensus_state.map(TryInto::try_into).transpose()?; + let consensus_state: SoloMachineConsensusState = raw + .consensus_state + .ok_or(Error::ConsensusStateIsEmpty)? + .try_into()?; Ok(Self { sequence, @@ -246,11 +254,10 @@ impl From for RawSolClientState { fn from(value: ClientState) -> Self { let sequence = value.sequence.revision_height(); - let consensus_state = value.consensus_state.map(Into::into); Self { sequence, is_frozen: value.is_frozen, - consensus_state, + consensus_state: Some(value.consensus_state.into()), allow_update_after_proposal: value.allow_update_after_proposal, } } diff --git a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs index a663ae496..16d0a82a3 100644 --- a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs @@ -36,6 +36,7 @@ impl ConsensusState { } } + // ValidateBasic defines basic validation for the solo machine consensus state. pub fn valida_basic(&self) -> Result<(), Error> { if self.timestamp.into_tm_time().is_none() { return Err(Error::TimeStampIsEmpty); diff --git a/crates/ibc/src/clients/ics06_solomachine/error.rs b/crates/ibc/src/clients/ics06_solomachine/error.rs index a616c3a90..f113393c7 100644 --- a/crates/ibc/src/clients/ics06_solomachine/error.rs +++ b/crates/ibc/src/clients/ics06_solomachine/error.rs @@ -31,6 +31,8 @@ pub enum Error { PublicKeyParseFailed(eyre::ErrReport), /// public key is empty PublicKeyIsEmpty, + /// consensus state is empty + ConsensusStateIsEmpty, } impl From for ClientError { From 80acaa8c97da73ecedf143862a6f9e2de664527a Mon Sep 17 00:00:00 2001 From: Davirain Date: Fri, 12 May 2023 10:47:43 +0800 Subject: [PATCH 20/35] Add support for frozen client state (#123) --- .../clients/ics06_solomachine/client_state.rs | 45 ++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index f5725815d..c8b8d6790 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -10,6 +10,7 @@ use crate::core::ics23_commitment::commitment::{ }; use crate::core::ics24_host::identifier::{ChainId, ClientId}; use crate::core::ics24_host::path::Path; +use crate::core::ics24_host::path::{ClientConsensusStatePath, ClientStatePath, ClientUpgradePath}; use crate::core::timestamp::Timestamp; use crate::core::{ExecutionContext, ValidationContext}; use crate::prelude::*; @@ -54,6 +55,13 @@ impl ClientState { } } + pub fn with_frozen(self) -> Self { + Self { + is_frozen: true, + ..self + } + } + /// Return exported.Height to satisfy ClientState interface /// Revision number is always 0 for a solo-machine. pub fn latest_height(&self) -> Height { @@ -107,13 +115,14 @@ impl Ics2ClientState for ClientState { /// Helper function to verify the upgrade client procedure. /// Resets all fields except the blockchain-specific ones, /// and updates the given fields. - // ref: https://github.com/cosmos/ibc-go/blob/fa9418f5ba39de38d995ec83d9abd289dfab5f9f/modules/light-clients/06-solomachine/client_state.go#L75 fn zero_custom_fields(&mut self) { - // zero_custom_fields is not implemented for solo machine + // ref: https://github.com/cosmos/ibc-go/blob/f32b1052e1357949e6a67685d355c7bcc6242b84/modules/light-clients/06-solomachine/client_state.go#L76 + panic!("ZeroCustomFields is not implemented as the solo machine implementation does not support upgrades.") } fn initialise(&self, consensus_state: Any) -> Result, ClientError> { - todo!() + SoloMachineConsensusState::try_from(consensus_state) + .map(SoloMachineConsensusState::into_box) } /// verify_client_message must verify a client_message. A client_message @@ -129,7 +138,17 @@ impl Ics2ClientState for ClientState { client_message: Any, update_kind: &UpdateKind, ) -> Result<(), ClientError> { - todo!() + match update_kind { + UpdateKind::UpdateClient => { + // let header = TmHeader::try_from(client_message)?; + // self.verify_header(ctx, client_id, header) + } + UpdateKind::SubmitMisbehaviour => { + // let misbehaviour = TmMisbehaviour::try_from(client_message)?; + // self.verify_misbehaviour(ctx, client_id, misbehaviour) + } + } + Ok(()) } /// Checks for evidence of a misbehaviour in Header or Misbehaviour type. It @@ -141,7 +160,17 @@ impl Ics2ClientState for ClientState { client_message: Any, update_kind: &UpdateKind, ) -> Result { - todo!() + match update_kind { + UpdateKind::UpdateClient => { + // let header = TmHeader::try_from(client_message)?; + // self.check_for_misbehaviour_update_client(ctx, client_id, header) + } + UpdateKind::SubmitMisbehaviour => { + // let misbehaviour = TmMisbehaviour::try_from(client_message)?; + // self.check_for_misbehaviour_misbehavior(&misbehaviour) + } + } + Ok(true) } /// Updates and stores as necessary any associated information for an IBC @@ -169,7 +198,11 @@ impl Ics2ClientState for ClientState { client_message: Any, update_kind: &UpdateKind, ) -> Result<(), ClientError> { - todo!() + let frozen_client_state = self.clone().with_frozen().into_box(); + + ctx.store_client_state(ClientStatePath::new(client_id), frozen_client_state)?; + + Ok(()) } /// Verify the upgraded client and consensus states and validate proofs From 0c79b37bfe606a63c1db9dadc235b1f3fb600fdc Mon Sep 17 00:00:00 2001 From: Davirain Date: Fri, 12 May 2023 10:53:05 +0800 Subject: [PATCH 21/35] refactor: Cleaning up ICS06 Solo Machine commit state implementation and adding error handling. --- .../clients/ics06_solomachine/client_state.rs | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index c8b8d6790..45b204201 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -217,22 +217,25 @@ impl Ics2ClientState for ClientState { /// cancelled or modified before the last planned height. fn verify_upgrade_client( &self, - upgraded_client_state: Any, - upgraded_consensus_state: Any, - proof_upgrade_client: RawMerkleProof, - proof_upgrade_consensus_state: RawMerkleProof, - root: &CommitmentRoot, + _upgraded_client_state: Any, + _upgraded_consensus_state: Any, + _proof_upgrade_client: RawMerkleProof, + _proof_upgrade_consensus_state: RawMerkleProof, + _root: &CommitmentRoot, ) -> Result<(), ClientError> { - todo!() + Ok(()) } // Update the client state and consensus state in the store with the upgraded ones. fn update_state_with_upgrade_client( &self, - upgraded_client_state: Any, - upgraded_consensus_state: Any, + _upgraded_client_state: Any, + _upgraded_consensus_state: Any, ) -> Result { - todo!() + // ref: https://github.com/cosmos/ibc-go/blob/f32b1052e1357949e6a67685d355c7bcc6242b84/modules/light-clients/06-solomachine/client_state.go#L99 + Err(ClientError::Other { + description: "cannot upgrade solomachine client".into(), + }) } // Verify_membership is a generic proof verification method which verifies a From a0da3ea394466064ac4ca5547598f86700486364 Mon Sep 17 00:00:00 2001 From: Davirain Date: Fri, 12 May 2023 10:54:56 +0800 Subject: [PATCH 22/35] Adjust IBC client_state.rs file to handle ClientError and todo(davirian). --- .../clients/ics06_solomachine/client_state.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index 45b204201..9233144be 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -93,7 +93,13 @@ impl Ics2ClientState for ClientState { /// Check if the given proof has a valid height for the client fn validate_proof_height(&self, proof_height: Height) -> Result<(), ClientError> { - todo!() + if self.latest_height() < proof_height { + return Err(ClientError::InvalidProofHeight { + latest_height: self.latest_height(), + proof_height, + }); + } + Ok(()) } /// Assert that the client is not frozen @@ -108,8 +114,9 @@ impl Ics2ClientState for ClientState { /// Check if the state is expired when `elapsed` time has passed since the latest consensus /// state timestamp - fn expired(&self, elapsed: Duration) -> bool { - todo!() + fn expired(&self, _elapsed: Duration) -> bool { + // todo(davirian) + false } /// Helper function to verify the upgrade client procedure. @@ -195,8 +202,8 @@ impl Ics2ClientState for ClientState { &self, ctx: &mut dyn ExecutionContext, client_id: &ClientId, - client_message: Any, - update_kind: &UpdateKind, + _client_message: Any, + _update_kind: &UpdateKind, ) -> Result<(), ClientError> { let frozen_client_state = self.clone().with_frozen().into_box(); From 851796649ea4bafa749d81416dd429b51dbb6f44 Mon Sep 17 00:00:00 2001 From: Davirain Date: Fri, 12 May 2023 11:23:19 +0800 Subject: [PATCH 23/35] feat: Add proof.rs file and verify_signature function to ics06_solomachine module. --- crates/ibc/src/clients/ics06_solomachine/mod.rs | 1 + crates/ibc/src/clients/ics06_solomachine/proof.rs | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 crates/ibc/src/clients/ics06_solomachine/proof.rs diff --git a/crates/ibc/src/clients/ics06_solomachine/mod.rs b/crates/ibc/src/clients/ics06_solomachine/mod.rs index 33c146f26..750a87b74 100644 --- a/crates/ibc/src/clients/ics06_solomachine/mod.rs +++ b/crates/ibc/src/clients/ics06_solomachine/mod.rs @@ -7,6 +7,7 @@ pub mod consensus_state; pub mod error; pub mod header; pub mod misbehaviour; +pub mod proof; pub mod types; pub(crate) const SOLOMACHINE_CLIENT_TYPE: &str = "07-solomachine"; diff --git a/crates/ibc/src/clients/ics06_solomachine/proof.rs b/crates/ibc/src/clients/ics06_solomachine/proof.rs new file mode 100644 index 000000000..51e1ac765 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/proof.rs @@ -0,0 +1,8 @@ +use alloc::string::String; +use alloc::vec::Vec; +use cosmrs::crypto::PublicKey; +// use cosmrs::tx::SignatureBytes; + +pub fn verify_signature(publik_key: PublicKey, sign_bytes: Vec) -> Result<(), String> { + todo!() +} From 53d761a8e508cad595ac9e00273190b711d624d6 Mon Sep 17 00:00:00 2001 From: Davirain Date: Fri, 12 May 2023 15:58:35 +0800 Subject: [PATCH 24/35] Update client_state.rs --- crates/ibc/src/clients/ics06_solomachine/client_state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index 9233144be..ae15f019c 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -10,7 +10,7 @@ use crate::core::ics23_commitment::commitment::{ }; use crate::core::ics24_host::identifier::{ChainId, ClientId}; use crate::core::ics24_host::path::Path; -use crate::core::ics24_host::path::{ClientConsensusStatePath, ClientStatePath, ClientUpgradePath}; +use crate::core::ics24_host::path::{ClientConsensusStatePath, ClientStatePath}; use crate::core::timestamp::Timestamp; use crate::core::{ExecutionContext, ValidationContext}; use crate::prelude::*; From f8ebe15a5102680a8549ace22943e815eaecdc3c Mon Sep 17 00:00:00 2001 From: Davirain Date: Fri, 12 May 2023 16:00:45 +0800 Subject: [PATCH 25/35] Update cosmos-rust branch to new-proto-v0.12.0-rc in Cargo.toml. --- crates/ibc/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ibc/Cargo.toml b/crates/ibc/Cargo.toml index b3b8b3ad8..23c869f2d 100644 --- a/crates/ibc/Cargo.toml +++ b/crates/ibc/Cargo.toml @@ -58,7 +58,7 @@ scale-info = { version = "2.1.2", default-features = false, features = ["derive" borsh = {version = "0.10.0", default-features = false, optional = true } parking_lot = { version = "0.12.1", default-features = false, optional = true } cfg-if = { version = "1.0.0", optional = true } -cosmrs = { version = "0.12.0", default-feature = false, git = "https://github.com/octopus-network/cosmos-rust.git", branch = "new-proto-v0.12.0" } +cosmrs = { version = "0.12.0", default-feature = false, git = "https://github.com/octopus-network/cosmos-rust.git", branch = "new-proto-v0.12.0-rc" } eyre = { version = "0.6", default-features = false } [dependencies.tendermint] From 23c6ea661ec3d4ce98ff8c06a6a6d83fa7c30967 Mon Sep 17 00:00:00 2001 From: Davirain Date: Fri, 12 May 2023 16:13:00 +0800 Subject: [PATCH 26/35] Refactor solomachine client_state to remove unused variables and functions --- .../clients/ics06_solomachine/client_state.rs | 38 +++++++++---------- .../src/clients/ics06_solomachine/header.rs | 8 ++-- .../clients/ics06_solomachine/misbehaviour.rs | 2 +- .../src/clients/ics06_solomachine/proof.rs | 2 +- .../types/client_stata_data.rs | 4 +- .../types/connection_state_data.rs | 4 +- .../types/consensus_state_data.rs | 4 +- .../ics06_solomachine/types/header_data.rs | 4 +- .../types/packet_receipt_absence_data.rs | 4 +- 9 files changed, 35 insertions(+), 35 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index ae15f019c..e2aad32bc 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -9,8 +9,8 @@ use crate::core::ics23_commitment::commitment::{ CommitmentPrefix, CommitmentProofBytes, CommitmentRoot, }; use crate::core::ics24_host::identifier::{ChainId, ClientId}; +use crate::core::ics24_host::path::ClientStatePath; use crate::core::ics24_host::path::Path; -use crate::core::ics24_host::path::{ClientConsensusStatePath, ClientStatePath}; use crate::core::timestamp::Timestamp; use crate::core::{ExecutionContext, ValidationContext}; use crate::prelude::*; @@ -140,9 +140,9 @@ impl Ics2ClientState for ClientState { /// error should be returned if the client_message fails to verify. fn verify_client_message( &self, - ctx: &dyn ValidationContext, - client_id: &ClientId, - client_message: Any, + _ctx: &dyn ValidationContext, + _client_id: &ClientId, + _client_message: Any, update_kind: &UpdateKind, ) -> Result<(), ClientError> { match update_kind { @@ -162,9 +162,9 @@ impl Ics2ClientState for ClientState { /// assumes the client_message has already been verified. fn check_for_misbehaviour( &self, - ctx: &dyn ValidationContext, - client_id: &ClientId, - client_message: Any, + _ctx: &dyn ValidationContext, + _client_id: &ClientId, + _client_message: Any, update_kind: &UpdateKind, ) -> Result { match update_kind { @@ -189,9 +189,9 @@ impl Ics2ClientState for ClientState { /// height. fn update_state( &self, - ctx: &mut dyn ExecutionContext, - client_id: &ClientId, - header: Any, + _ctx: &mut dyn ExecutionContext, + _client_id: &ClientId, + _header: Any, ) -> Result, ClientError> { todo!() } @@ -249,11 +249,11 @@ impl Ics2ClientState for ClientState { // proof of the existence of a value at a given Path. fn verify_membership( &self, - prefix: &CommitmentPrefix, - proof: &CommitmentProofBytes, - root: &CommitmentRoot, - path: Path, - value: Vec, + _prefix: &CommitmentPrefix, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _path: Path, + _value: Vec, ) -> Result<(), ClientError> { todo!() } @@ -262,10 +262,10 @@ impl Ics2ClientState for ClientState { // verifies the absence of a given commitment. fn verify_non_membership( &self, - prefix: &CommitmentPrefix, - proof: &CommitmentProofBytes, - root: &CommitmentRoot, - path: Path, + _prefix: &CommitmentPrefix, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _path: Path, ) -> Result<(), ClientError> { todo!() } diff --git a/crates/ibc/src/clients/ics06_solomachine/header.rs b/crates/ibc/src/clients/ics06_solomachine/header.rs index f48fa8936..3886b8d9c 100644 --- a/crates/ibc/src/clients/ics06_solomachine/header.rs +++ b/crates/ibc/src/clients/ics06_solomachine/header.rs @@ -24,13 +24,13 @@ pub struct Header { } impl core::fmt::Debug for Header { - fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { + fn fmt(&self, _f: &mut Formatter<'_>) -> Result<(), FmtError> { todo!() } } impl Display for Header { - fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { + fn fmt(&self, _f: &mut Formatter<'_>) -> Result<(), FmtError> { todo!() } } @@ -50,13 +50,13 @@ impl Protobuf for Header {} impl TryFrom for Header { type Error = Error; - fn try_from(raw: RawSolHeader) -> Result { + fn try_from(_raw: RawSolHeader) -> Result { todo!() } } impl From
for RawSolHeader { - fn from(value: Header) -> Self { + fn from(_value: Header) -> Self { todo!() } } diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs index 184c48c20..23822b13b 100644 --- a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs @@ -106,7 +106,7 @@ pub fn decode_misbehaviour(buf: B) -> Result { } impl core::fmt::Display for Misbehaviour { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { todo!() } } diff --git a/crates/ibc/src/clients/ics06_solomachine/proof.rs b/crates/ibc/src/clients/ics06_solomachine/proof.rs index 51e1ac765..eb896e5fd 100644 --- a/crates/ibc/src/clients/ics06_solomachine/proof.rs +++ b/crates/ibc/src/clients/ics06_solomachine/proof.rs @@ -3,6 +3,6 @@ use alloc::vec::Vec; use cosmrs::crypto::PublicKey; // use cosmrs::tx::SignatureBytes; -pub fn verify_signature(publik_key: PublicKey, sign_bytes: Vec) -> Result<(), String> { +pub fn verify_signature(_publik_key: PublicKey, _sign_bytes: Vec) -> Result<(), String> { todo!() } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs index 6dc8288fa..4a5fe8181 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs @@ -17,13 +17,13 @@ impl Protobuf for ClientStateData {} impl TryFrom for ClientStateData { type Error = Error; - fn try_from(raw: RawClientStateData) -> Result { + fn try_from(_raw: RawClientStateData) -> Result { todo!() } } impl From for RawClientStateData { - fn from(value: ClientStateData) -> Self { + fn from(_value: ClientStateData) -> Self { todo!() } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs index 712c5522f..c918fbcab 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs @@ -18,13 +18,13 @@ impl Protobuf for ConnectionStateData {} impl TryFrom for ConnectionStateData { type Error = Error; - fn try_from(raw: RawConnectionStateData) -> Result { + fn try_from(_raw: RawConnectionStateData) -> Result { todo!() } } impl From for RawConnectionStateData { - fn from(value: ConnectionStateData) -> Self { + fn from(_value: ConnectionStateData) -> Self { todo!() } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs index 78ba4de2f..3ac146d24 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs @@ -19,13 +19,13 @@ impl Protobuf for ConsensusStateData {} impl TryFrom for ConsensusStateData { type Error = Error; - fn try_from(raw: RawConsensusStateData) -> Result { + fn try_from(_raw: RawConsensusStateData) -> Result { todo!() } } impl From for RawConsensusStateData { - fn from(value: ConsensusStateData) -> Self { + fn from(_value: ConsensusStateData) -> Self { todo!() } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs index 8d1aec34d..6cf46a363 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs @@ -19,13 +19,13 @@ impl Protobuf for HeaderData {} impl TryFrom for HeaderData { type Error = Error; - fn try_from(raw: RawHeaderData) -> Result { + fn try_from(_raw: RawHeaderData) -> Result { todo!() } } impl From for RawHeaderData { - fn from(value: HeaderData) -> Self { + fn from(_value: HeaderData) -> Self { todo!() } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs index 7a37850de..e5c1a829d 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs @@ -15,13 +15,13 @@ impl Protobuf for PacketReceiptAbsenceData {} impl TryFrom for PacketReceiptAbsenceData { type Error = Error; - fn try_from(raw: RawPacketReceiptAbsenceData) -> Result { + fn try_from(_raw: RawPacketReceiptAbsenceData) -> Result { todo!() } } impl From for RawPacketReceiptAbsenceData { - fn from(value: PacketReceiptAbsenceData) -> Self { + fn from(_value: PacketReceiptAbsenceData) -> Self { todo!() } } From 6319252eb81639a58911d183cfaa8753d02588a2 Mon Sep 17 00:00:00 2001 From: Davirain Date: Mon, 15 May 2023 10:30:42 +0800 Subject: [PATCH 27/35] Add misbehaviour and update_client file --- ci/no-std-check/Cargo.lock | 331 +++++++++++++++++- .../clients/ics06_solomachine/client_state.rs | 52 +-- .../client_state/misbehaviour.rs | 39 +++ .../client_state/update_client.rs | 27 ++ 4 files changed, 413 insertions(+), 36 deletions(-) create mode 100644 crates/ibc/src/clients/ics06_solomachine/client_state/misbehaviour.rs create mode 100644 crates/ibc/src/clients/ics06_solomachine/client_state/update_client.rs diff --git a/ci/no-std-check/Cargo.lock b/ci/no-std-check/Cargo.lock index 68170766c..374dc1b2e 100644 --- a/ci/no-std-check/Cargo.lock +++ b/ci/no-std-check/Cargo.lock @@ -137,12 +137,30 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + [[package]] name = "base64" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bincode" version = "1.3.3" @@ -152,6 +170,24 @@ dependencies = [ "serde", ] +[[package]] +name = "bip32" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" +dependencies = [ + "bs58", + "hmac 0.12.1", + "k256", + "once_cell", + "pbkdf2 0.11.0", + "rand_core 0.6.4", + "ripemd", + "sha2 0.10.6", + "subtle", + "zeroize", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -291,6 +327,9 @@ name = "bs58" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +dependencies = [ + "sha2 0.9.9", +] [[package]] name = "bumpalo" @@ -359,6 +398,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "const-oid" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" + [[package]] name = "constant_time_eq" version = "0.2.5" @@ -371,6 +416,27 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "cosmrs" +version = "0.12.0" +source = "git+https://github.com/octopus-network/cosmos-rust.git?branch=new-proto-v0.12.0-rc#f9ca75d8cc1150033d14eaaa9e24187a568a0c48" +dependencies = [ + "bip32", + "displaydoc", + "ecdsa", + "eyre", + "getrandom 0.2.9", + "ibc-proto 0.29.0", + "k256", + "prost", + "rand_core 0.6.4", + "serde", + "serde_json", + "subtle-encoding", + "tendermint 0.30.0", + "tendermint-proto 0.30.0", +] + [[package]] name = "cpp_demangle" version = "0.3.5" @@ -413,6 +479,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -526,6 +604,16 @@ dependencies = [ "syn 2.0.15", ] +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -610,6 +698,18 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] + [[package]] name = "ed25519" version = "1.5.3" @@ -664,6 +764,25 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct", + "crypto-bigint", + "der", + "digest 0.10.6", + "ff", + "generic-array 0.14.7", + "group", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "environmental" version = "1.1.4" @@ -700,6 +819,16 @@ dependencies = [ "libc", ] +[[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + [[package]] name = "fake-simd" version = "0.1.2" @@ -712,6 +841,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "fixed-hash" version = "0.8.0" @@ -730,6 +869,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" dependencies = [ + "eyre", "paste", ] @@ -875,8 +1015,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] @@ -895,6 +1037,17 @@ version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "hash-db" version = "0.16.0" @@ -1015,15 +1168,17 @@ dependencies = [ [[package]] name = "ibc" -version = "0.37.0" +version = "0.40.0" dependencies = [ "bytes", "cfg-if", + "cosmrs", "derive_more", "displaydoc", "dyn-clone", "erased-serde", - "ibc-proto", + "eyre", + "ibc-proto 0.29.0", "ics23", "num-traits", "primitive-types", @@ -1034,9 +1189,9 @@ dependencies = [ "serde_json", "sha2 0.10.6", "subtle-encoding", - "tendermint", - "tendermint-light-client-verifier", - "tendermint-proto", + "tendermint 0.30.0", + "tendermint-light-client-verifier 0.30.0", + "tendermint-proto 0.30.0", "time", "tracing", "uint", @@ -1048,7 +1203,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9303a1308c886aea769ef0667c5caa422a78b01e9f8177fea8b91b08a4ff50c" dependencies = [ - "base64", + "base64 0.13.1", "borsh", "bytes", "flex-error", @@ -1057,7 +1212,24 @@ dependencies = [ "scale-info", "serde", "subtle-encoding", - "tendermint-proto", + "tendermint-proto 0.29.1", +] + +[[package]] +name = "ibc-proto" +version = "0.29.0" +source = "git+https://github.com/octopus-network/ibc-proto-rs.git?branch=new-proto-v0.29.0#daf23b1f0b6e1fbccd3fa8daec4f9375733cabc1" +dependencies = [ + "base64 0.21.0", + "borsh", + "bytes", + "flex-error", + "parity-scale-codec", + "prost", + "scale-info", + "serde", + "subtle-encoding", + "tendermint-proto 0.30.0", ] [[package]] @@ -1114,6 +1286,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + [[package]] name = "indexmap" version = "1.9.3" @@ -1169,6 +1347,19 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sha2 0.10.6", + "sha3", +] + [[package]] name = "keccak" version = "0.1.3" @@ -1203,7 +1394,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" dependencies = [ "arrayref", - "base64", + "base64 0.13.1", "digest 0.9.0", "hmac-drbg", "libsecp256k1-core", @@ -1367,15 +1558,15 @@ name = "no-std-check" version = "0.1.0" dependencies = [ "ibc", - "ibc-proto", + "ibc-proto 0.26.0", "sp-core", "sp-io", "sp-runtime", "sp-std", "syn 2.0.15", - "tendermint", - "tendermint-light-client-verifier", - "tendermint-proto", + "tendermint 0.29.1", + "tendermint-light-client-verifier 0.29.1", + "tendermint-proto 0.29.1", ] [[package]] @@ -1594,6 +1785,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der", + "spki", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1823,6 +2024,17 @@ version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint", + "hmac 0.12.1", + "zeroize", +] + [[package]] name = "ripemd" version = "0.1.3" @@ -2003,6 +2215,20 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct", + "der", + "generic-array 0.14.7", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "secp256k1" version = "0.24.3" @@ -2141,6 +2367,10 @@ name = "signature" version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.6", + "rand_core 0.6.4", +] [[package]] name = "slab" @@ -2486,6 +2716,16 @@ dependencies = [ "sp-std", ] +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "ss58-registry" version = "1.39.0" @@ -2605,7 +2845,38 @@ dependencies = [ "signature", "subtle", "subtle-encoding", - "tendermint-proto", + "tendermint-proto 0.29.1", + "time", + "zeroize", +] + +[[package]] +name = "tendermint" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90c3c1e32352551f0f1639ce765e4c66ce250c733d4b9ba1aff81130437465c" +dependencies = [ + "bytes", + "digest 0.10.6", + "ed25519", + "ed25519-consensus", + "flex-error", + "futures", + "k256", + "num-traits", + "once_cell", + "prost", + "prost-types", + "ripemd", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2 0.10.6", + "signature", + "subtle", + "subtle-encoding", + "tendermint-proto 0.30.0", "time", "zeroize", ] @@ -2619,7 +2890,20 @@ dependencies = [ "derive_more", "flex-error", "serde", - "tendermint", + "tendermint 0.29.1", + "time", +] + +[[package]] +name = "tendermint-light-client-verifier" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36e9193521a81e4c824faedc5eb31926f8918ebb21a1fa9cee9b3dbe5164a93" +dependencies = [ + "derive_more", + "flex-error", + "serde", + "tendermint 0.30.0", "time", ] @@ -2641,6 +2925,24 @@ dependencies = [ "time", ] +[[package]] +name = "tendermint-proto" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e553ed65874c3f35a71eb60d255edfea956274b5af37a0297d54bba039fe45e3" +dependencies = [ + "bytes", + "flex-error", + "num-derive", + "num-traits", + "prost", + "prost-types", + "serde", + "serde_bytes", + "subtle-encoding", + "time", +] + [[package]] name = "termcolor" version = "1.2.0" @@ -2686,6 +2988,7 @@ version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" dependencies = [ + "serde", "time-core", "time-macros", ] diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index e2aad32bc..26fc86427 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -1,5 +1,7 @@ -use crate::clients::ics06_solomachine::consensus_state::ConsensusState as SoloMachineConsensusState; +use crate::clients::ics06_solomachine::consensus_state::ConsensusState as SmConsensusState; use crate::clients::ics06_solomachine::error::Error; +use crate::clients::ics06_solomachine::header::Header as SmHeader; +use crate::clients::ics06_solomachine::misbehaviour::Misbehaviour as SmMisbehaviour; use crate::core::ics02_client::client_state::UpdateKind; use crate::core::ics02_client::client_state::{ClientState as Ics2ClientState, UpdatedState}; use crate::core::ics02_client::client_type::ClientType; @@ -22,6 +24,9 @@ use ibc_proto::ibc::lightclients::solomachine::v2::ClientState as RawSolClientSt use ibc_proto::protobuf::Protobuf; use prost::Message; +pub mod misbehaviour; +pub mod update_client; + pub const SOLOMACHINE_CLIENT_STATE_TYPE_URL: &str = "/ibc.lightclients.solomachine.v1.ClientState"; /// ClientState defines a solo machine client that tracks the current consensus @@ -33,7 +38,7 @@ pub struct ClientState { pub sequence: Height, /// frozen sequence of the solo machine pub is_frozen: bool, - pub consensus_state: SoloMachineConsensusState, + pub consensus_state: SmConsensusState, /// when set to true, will allow governance to update a solo machine client. /// The client will be unfrozen if it is frozen. pub allow_update_after_proposal: bool, @@ -44,7 +49,7 @@ impl ClientState { pub fn new( sequence: Height, is_frozen: bool, - consensus_state: SoloMachineConsensusState, + consensus_state: SmConsensusState, allow_update_after_proposal: bool, ) -> Self { Self { @@ -128,8 +133,7 @@ impl Ics2ClientState for ClientState { } fn initialise(&self, consensus_state: Any) -> Result, ClientError> { - SoloMachineConsensusState::try_from(consensus_state) - .map(SoloMachineConsensusState::into_box) + SmConsensusState::try_from(consensus_state).map(SmConsensusState::into_box) } /// verify_client_message must verify a client_message. A client_message @@ -138,46 +142,50 @@ impl Ics2ClientState for ClientState { /// update_state, and update_state_on_misbehaviour will assume that the /// content of the client_message has been verified and can be trusted. An /// error should be returned if the client_message fails to verify. + /// + /// VerifyClientMessage introspects the provided ClientMessage and checks its validity + /// A Solomachine Header is considered valid if the currently registered public key has signed over + /// the new public key with the correct sequence. + /// A Solomachine Misbehaviour is considered valid if duplicate signatures of the current public key + /// are found on two different messages at a given sequence. fn verify_client_message( &self, - _ctx: &dyn ValidationContext, - _client_id: &ClientId, - _client_message: Any, + ctx: &dyn ValidationContext, + client_id: &ClientId, + client_message: Any, update_kind: &UpdateKind, ) -> Result<(), ClientError> { match update_kind { UpdateKind::UpdateClient => { - // let header = TmHeader::try_from(client_message)?; - // self.verify_header(ctx, client_id, header) + let header = SmHeader::try_from(client_message)?; + self.verify_header(ctx, client_id, header) } UpdateKind::SubmitMisbehaviour => { - // let misbehaviour = TmMisbehaviour::try_from(client_message)?; - // self.verify_misbehaviour(ctx, client_id, misbehaviour) + let misbehaviour = SmMisbehaviour::try_from(client_message)?; + self.verify_misbehaviour(ctx, client_id, misbehaviour) } } - Ok(()) } /// Checks for evidence of a misbehaviour in Header or Misbehaviour type. It /// assumes the client_message has already been verified. fn check_for_misbehaviour( &self, - _ctx: &dyn ValidationContext, - _client_id: &ClientId, - _client_message: Any, + ctx: &dyn ValidationContext, + client_id: &ClientId, + client_message: Any, update_kind: &UpdateKind, ) -> Result { match update_kind { UpdateKind::UpdateClient => { - // let header = TmHeader::try_from(client_message)?; - // self.check_for_misbehaviour_update_client(ctx, client_id, header) + let header = SmHeader::try_from(client_message)?; + self.check_for_misbehaviour_update_client(ctx, client_id, header) } UpdateKind::SubmitMisbehaviour => { - // let misbehaviour = TmMisbehaviour::try_from(client_message)?; - // self.check_for_misbehaviour_misbehavior(&misbehaviour) + let misbehaviour = SmMisbehaviour::try_from(client_message)?; + self.check_for_misbehaviour_misbehavior(&misbehaviour) } } - Ok(true) } /// Updates and stores as necessary any associated information for an IBC @@ -279,7 +287,7 @@ impl TryFrom for ClientState { fn try_from(raw: RawSolClientState) -> Result { let sequence = Height::new(0, raw.sequence).map_err(Error::InvalidHeight)?; - let consensus_state: SoloMachineConsensusState = raw + let consensus_state: SmConsensusState = raw .consensus_state .ok_or(Error::ConsensusStateIsEmpty)? .try_into()?; diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state/misbehaviour.rs b/crates/ibc/src/clients/ics06_solomachine/client_state/misbehaviour.rs new file mode 100644 index 000000000..f46f2d2a5 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/client_state/misbehaviour.rs @@ -0,0 +1,39 @@ +use crate::prelude::*; + +use crate::clients::ics06_solomachine::consensus_state::ConsensusState as SmConsensusState; +use crate::clients::ics06_solomachine::header::Header as SmHeader; +use crate::clients::ics06_solomachine::misbehaviour::Misbehaviour as SmMisbehaviour; +use crate::core::ics02_client::error::ClientError; +use crate::core::timestamp::Timestamp; +use crate::core::{ics24_host::identifier::ClientId, ValidationContext}; + +use super::ClientState; + +impl ClientState { + // verify_misbehaviour determines whether or not two conflicting headers at + // the same height would have convinced the light client. + pub fn verify_misbehaviour( + &self, + _ctx: &dyn ValidationContext, + _client_id: &ClientId, + _misbehaviour: SmMisbehaviour, + ) -> Result<(), ClientError> { + todo!() + } + + pub fn verify_misbehaviour_header( + &self, + _header: &SmHeader, + _trusted_consensus_state: &SmConsensusState, + _current_timestamp: Timestamp, + ) -> Result<(), ClientError> { + todo!() + } + + pub fn check_for_misbehaviour_misbehavior( + &self, + _misbehaviour: &SmMisbehaviour, + ) -> Result { + todo!() + } +} diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state/update_client.rs b/crates/ibc/src/clients/ics06_solomachine/client_state/update_client.rs new file mode 100644 index 000000000..d723d2916 --- /dev/null +++ b/crates/ibc/src/clients/ics06_solomachine/client_state/update_client.rs @@ -0,0 +1,27 @@ +use crate::prelude::*; + +use crate::clients::ics06_solomachine::header::Header as SmHeader; +use crate::core::ics02_client::error::ClientError; +use crate::core::{ics24_host::identifier::ClientId, ValidationContext}; + +use super::ClientState; + +impl ClientState { + pub fn verify_header( + &self, + _ctx: &dyn ValidationContext, + _client_id: &ClientId, + _header: SmHeader, + ) -> Result<(), ClientError> { + todo!() + } + + pub fn check_for_misbehaviour_update_client( + &self, + _ctx: &dyn ValidationContext, + _client_id: &ClientId, + _header: SmHeader, + ) -> Result { + todo!() + } +} From c87f72e7b70170f1db58a119244041dcccb07c06 Mon Sep 17 00:00:00 2001 From: Davirain Date: Mon, 15 May 2023 10:34:23 +0800 Subject: [PATCH 28/35] refactor(ibc): replace `RawSolClientState` and `RawSolConsensusState` with `RawSmClientState` and `RawSmConsensusState`, replace `RawSolHeader` and `RawSolMisbehaviour` with `RawSmHeader` and `RawSmMisbehaviour` respectively. --- .../clients/ics06_solomachine/client_state.rs | 14 +++++++------- .../clients/ics06_solomachine/consensus_state.rs | 14 +++++++------- .../ibc/src/clients/ics06_solomachine/header.rs | 14 +++++++------- .../clients/ics06_solomachine/misbehaviour.rs | 16 ++++++++-------- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index 26fc86427..7176e6e32 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -20,7 +20,7 @@ use crate::Height; use core::time::Duration; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::commitment::v1::MerkleProof as RawMerkleProof; -use ibc_proto::ibc::lightclients::solomachine::v2::ClientState as RawSolClientState; +use ibc_proto::ibc::lightclients::solomachine::v2::ClientState as RawSmClientState; use ibc_proto::protobuf::Protobuf; use prost::Message; @@ -279,12 +279,12 @@ impl Ics2ClientState for ClientState { } } -impl Protobuf for ClientState {} +impl Protobuf for ClientState {} -impl TryFrom for ClientState { +impl TryFrom for ClientState { type Error = Error; - fn try_from(raw: RawSolClientState) -> Result { + fn try_from(raw: RawSmClientState) -> Result { let sequence = Height::new(0, raw.sequence).map_err(Error::InvalidHeight)?; let consensus_state: SmConsensusState = raw @@ -301,7 +301,7 @@ impl TryFrom for ClientState { } } -impl From for RawSolClientState { +impl From for RawSmClientState { fn from(value: ClientState) -> Self { let sequence = value.sequence.revision_height(); @@ -324,7 +324,7 @@ impl TryFrom for ClientState { use core::ops::Deref; fn decode_client_state(buf: B) -> Result { - RawSolClientState::decode(buf) + RawSmClientState::decode(buf) .map_err(Error::Decode)? .try_into() } @@ -344,7 +344,7 @@ impl From for Any { fn from(client_state: ClientState) -> Self { Any { type_url: SOLOMACHINE_CLIENT_STATE_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&client_state), + value: Protobuf::::encode_vec(&client_state), } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs index 16d0a82a3..4354c7f73 100644 --- a/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/consensus_state.rs @@ -5,7 +5,7 @@ use crate::core::timestamp::Timestamp; use crate::prelude::*; use cosmrs::crypto::PublicKey; use ibc_proto::google::protobuf::Any; -use ibc_proto::ibc::lightclients::solomachine::v2::ConsensusState as RawSolConsensusState; +use ibc_proto::ibc::lightclients::solomachine::v2::ConsensusState as RawSmConsensusState; use ibc_proto::protobuf::Protobuf; use prost::Message; @@ -69,12 +69,12 @@ impl crate::core::ics02_client::consensus_state::ConsensusState for ConsensusSta } } -impl Protobuf for ConsensusState {} +impl Protobuf for ConsensusState {} -impl TryFrom for ConsensusState { +impl TryFrom for ConsensusState { type Error = Error; - fn try_from(raw: RawSolConsensusState) -> Result { + fn try_from(raw: RawSmConsensusState) -> Result { let public_key = PublicKey::try_from(raw.public_key.ok_or(Error::PublicKeyIsEmpty)?) .map_err(Error::PublicKeyParseFailed)?; let timestamp = @@ -87,7 +87,7 @@ impl TryFrom for ConsensusState { } } -impl From for RawSolConsensusState { +impl From for RawSmConsensusState { fn from(value: ConsensusState) -> Self { let public_key = value .public_key @@ -112,7 +112,7 @@ impl TryFrom for ConsensusState { use core::ops::Deref; fn decode_consensus_state(buf: B) -> Result { - RawSolConsensusState::decode(buf) + RawSmConsensusState::decode(buf) .map_err(Error::Decode)? .try_into() } @@ -132,7 +132,7 @@ impl From for Any { fn from(consensus_state: ConsensusState) -> Self { Any { type_url: SOLOMACHINE_CONSENSUS_STATE_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&consensus_state), + value: Protobuf::::encode_vec(&consensus_state), } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/header.rs b/crates/ibc/src/clients/ics06_solomachine/header.rs index 3886b8d9c..d869eade3 100644 --- a/crates/ibc/src/clients/ics06_solomachine/header.rs +++ b/crates/ibc/src/clients/ics06_solomachine/header.rs @@ -6,7 +6,7 @@ use crate::Height; use bytes::Buf; use core::fmt::{Display, Error as FmtError, Formatter}; use ibc_proto::google::protobuf::Any; -use ibc_proto::ibc::lightclients::solomachine::v2::Header as RawSolHeader; +use ibc_proto::ibc::lightclients::solomachine::v2::Header as RawSmHeader; use ibc_proto::protobuf::Protobuf; use prost::Message; pub const SOLOMACHINE_HEADER_TYPE_URL: &str = "/ibc.lightclients.solomachine.v1.Header"; @@ -45,17 +45,17 @@ impl crate::core::ics02_client::header::Header for Header { } } -impl Protobuf for Header {} +impl Protobuf for Header {} -impl TryFrom for Header { +impl TryFrom for Header { type Error = Error; - fn try_from(_raw: RawSolHeader) -> Result { + fn try_from(_raw: RawSmHeader) -> Result { todo!() } } -impl From
for RawSolHeader { +impl From
for RawSmHeader { fn from(_value: Header) -> Self { todo!() } @@ -82,11 +82,11 @@ impl From
for Any { fn from(header: Header) -> Self { Any { type_url: SOLOMACHINE_HEADER_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&header), + value: Protobuf::::encode_vec(&header), } } } pub fn decode_header(buf: B) -> Result { - RawSolHeader::decode(buf).map_err(Error::Decode)?.try_into() + RawSmHeader::decode(buf).map_err(Error::Decode)?.try_into() } diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs index 23822b13b..16f14ca8b 100644 --- a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs @@ -4,7 +4,7 @@ use crate::core::ics24_host::identifier::ClientId; use crate::{prelude::*, Height}; use bytes::Buf; use ibc_proto::google::protobuf::Any; -use ibc_proto::ibc::lightclients::solomachine::v2::Misbehaviour as RawSolMisbehaviour; +use ibc_proto::ibc::lightclients::solomachine::v2::Misbehaviour as RawSmMisbehaviour; use ibc_proto::protobuf::Protobuf; use prost::Message; @@ -25,12 +25,12 @@ pub struct Misbehaviour { pub signature_two: Option, } -impl Protobuf for Misbehaviour {} +impl Protobuf for Misbehaviour {} -impl TryFrom for Misbehaviour { +impl TryFrom for Misbehaviour { type Error = Error; - fn try_from(raw: RawSolMisbehaviour) -> Result { + fn try_from(raw: RawSmMisbehaviour) -> Result { let client_id: ClientId = raw .client_id .parse() @@ -51,7 +51,7 @@ impl TryFrom for Misbehaviour { } } -impl From for RawSolMisbehaviour { +impl From for RawSmMisbehaviour { fn from(value: Misbehaviour) -> Self { let client_id = value.client_id.to_string(); let sequence = value.sequence.revision_height(); @@ -74,7 +74,7 @@ impl TryFrom for Misbehaviour { use core::ops::Deref; fn decode_misbehaviour(buf: B) -> Result { - RawSolMisbehaviour::decode(buf) + RawSmMisbehaviour::decode(buf) .map_err(Error::Decode)? .try_into() } @@ -94,13 +94,13 @@ impl From for Any { fn from(misbehaviour: Misbehaviour) -> Self { Any { type_url: SOLOMACHINE_MISBEHAVIOUR_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&misbehaviour), + value: Protobuf::::encode_vec(&misbehaviour), } } } pub fn decode_misbehaviour(buf: B) -> Result { - RawSolMisbehaviour::decode(buf) + RawSmMisbehaviour::decode(buf) .map_err(Error::Decode)? .try_into() } From 1238f2e363f63a3b522b6c291189fd0a15ed3e11 Mon Sep 17 00:00:00 2001 From: Davirain Date: Mon, 15 May 2023 11:05:33 +0800 Subject: [PATCH 29/35] feat(ics06): add signature and public key errors --- .../src/clients/ics06_solomachine/error.rs | 2 ++ .../src/clients/ics06_solomachine/header.rs | 33 ++++++++++++++++--- .../clients/ics06_solomachine/misbehaviour.rs | 20 ++++++----- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/error.rs b/crates/ibc/src/clients/ics06_solomachine/error.rs index f113393c7..931e5ce78 100644 --- a/crates/ibc/src/clients/ics06_solomachine/error.rs +++ b/crates/ibc/src/clients/ics06_solomachine/error.rs @@ -33,6 +33,8 @@ pub enum Error { PublicKeyIsEmpty, /// consensus state is empty ConsensusStateIsEmpty, + /// SignatureAndData empty + SignatureAndDataIsEmpty, } impl From for ClientError { diff --git a/crates/ibc/src/clients/ics06_solomachine/header.rs b/crates/ibc/src/clients/ics06_solomachine/header.rs index d869eade3..55c582b22 100644 --- a/crates/ibc/src/clients/ics06_solomachine/header.rs +++ b/crates/ibc/src/clients/ics06_solomachine/header.rs @@ -5,10 +5,12 @@ use crate::prelude::*; use crate::Height; use bytes::Buf; use core::fmt::{Display, Error as FmtError, Formatter}; +use cosmrs::crypto::PublicKey; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::lightclients::solomachine::v2::Header as RawSmHeader; use ibc_proto::protobuf::Protobuf; use prost::Message; + pub const SOLOMACHINE_HEADER_TYPE_URL: &str = "/ibc.lightclients.solomachine.v1.Header"; /// Header defines a solo machine consensus header @@ -19,7 +21,7 @@ pub struct Header { pub sequence: Height, pub timestamp: Timestamp, pub signature: Vec, - pub new_public_key: Option, + pub new_public_key: PublicKey, pub new_diversifier: String, } @@ -50,14 +52,35 @@ impl Protobuf for Header {} impl TryFrom for Header { type Error = Error; - fn try_from(_raw: RawSmHeader) -> Result { - todo!() + fn try_from(raw: RawSmHeader) -> Result { + let sequence = Height::new(0, raw.sequence).map_err(Error::InvalidHeight)?; + let timestamp = + Timestamp::from_nanoseconds(raw.timestamp).map_err(Error::ParseTimeError)?; + let signature = raw.signature; + + let new_public_key = + PublicKey::try_from(raw.new_public_key.ok_or(Error::PublicKeyIsEmpty)?) + .map_err(Error::PublicKeyParseFailed)?; + let new_diversifier = raw.new_diversifier; + Ok(Self { + sequence, + timestamp, + signature, + new_public_key, + new_diversifier, + }) } } impl From
for RawSmHeader { - fn from(_value: Header) -> Self { - todo!() + fn from(value: Header) -> Self { + Self { + sequence: value.sequence.revision_height(), + timestamp: value.timestamp.nanoseconds(), + signature: value.signature, + new_public_key: Some(value.new_public_key.to_any().expect("never failed")), + new_diversifier: value.new_diversifier, + } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs index 16f14ca8b..9b592cb86 100644 --- a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs @@ -21,8 +21,8 @@ pub const SOLOMACHINE_MISBEHAVIOUR_TYPE_URL: &str = "/ibc.lightclients.solomachi pub struct Misbehaviour { pub client_id: ClientId, pub sequence: Height, - pub signature_one: Option, - pub signature_two: Option, + pub signature_one: SignatureAndData, + pub signature_two: SignatureAndData, } impl Protobuf for Misbehaviour {} @@ -38,10 +38,14 @@ impl TryFrom for Misbehaviour { client_id: raw.client_id.clone(), })?; let sequence = Height::new(0, raw.sequence).map_err(Error::InvalidHeight)?; - let signature_one: Option = - raw.signature_one.map(TryInto::try_into).transpose()?; - let signature_two: Option = - raw.signature_two.map(TryInto::try_into).transpose()?; + let signature_one: SignatureAndData = raw + .signature_one + .ok_or(Error::SignatureAndDataIsEmpty)? + .try_into()?; + let signature_two: SignatureAndData = raw + .signature_two + .ok_or(Error::SignatureAndDataIsEmpty)? + .try_into()?; Ok(Self { client_id, sequence, @@ -59,8 +63,8 @@ impl From for RawSmMisbehaviour { Self { client_id, sequence, - signature_one: value.signature_one.map(Into::into), - signature_two: value.signature_two.map(Into::into), + signature_one: Some(value.signature_one.into()), + signature_two: Some(value.signature_two.into()), } } } From 71bbb0dfb1c7c9989bbdfa6e5930bd14e456b762 Mon Sep 17 00:00:00 2001 From: Davirain Date: Mon, 15 May 2023 11:19:54 +0800 Subject: [PATCH 30/35] Refactor debug and display implementations for ICS06 solomachine header; Add Display implementation for signature and data; Add Display implementation for DataType. --- .../src/clients/ics06_solomachine/header.rs | 16 ++++++++++++---- .../clients/ics06_solomachine/misbehaviour.rs | 9 +++++++-- .../misbehaviour/signature_and_data.rs | 9 +++++++++ .../src/clients/ics06_solomachine/types.rs | 19 +++++++++++++++++++ 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/header.rs b/crates/ibc/src/clients/ics06_solomachine/header.rs index 55c582b22..fc933ab89 100644 --- a/crates/ibc/src/clients/ics06_solomachine/header.rs +++ b/crates/ibc/src/clients/ics06_solomachine/header.rs @@ -26,14 +26,22 @@ pub struct Header { } impl core::fmt::Debug for Header { - fn fmt(&self, _f: &mut Formatter<'_>) -> Result<(), FmtError> { - todo!() + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { + write!(f, " Header {{...}}") } } impl Display for Header { - fn fmt(&self, _f: &mut Formatter<'_>) -> Result<(), FmtError> { - todo!() + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { + write!( + f, + "Header {{ sequence: {}, timestamp: {}, signature: {:?}, new_public_key: {:?}, new_diversifier: {} }}", + self.sequence, + self.timestamp, + self.signature, + self.new_public_key, + self.new_diversifier + ) } } diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs index 9b592cb86..f55ac87a0 100644 --- a/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour.rs @@ -46,6 +46,7 @@ impl TryFrom for Misbehaviour { .signature_two .ok_or(Error::SignatureAndDataIsEmpty)? .try_into()?; + Ok(Self { client_id, sequence, @@ -110,7 +111,11 @@ pub fn decode_misbehaviour(buf: B) -> Result { } impl core::fmt::Display for Misbehaviour { - fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - todo!() + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + write!( + f, + "ClientId({}), Sequence({}), SignatureOne({}), SignatureTwo({})", + self.client_id, self.sequence, self.signature_two, self.signature_two + ) } } diff --git a/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs b/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs index 24ceb9012..0428f922f 100644 --- a/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/misbehaviour/signature_and_data.rs @@ -15,6 +15,15 @@ pub struct SignatureAndData { pub data: Vec, pub timestamp: Timestamp, } +impl core::fmt::Display for SignatureAndData { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + write!( + f, + "signature: {:?}, data_type: {}, data: {:?}, timestamp: {}", + self.signature, self.data_type, self.data, self.timestamp + ) + } +} impl Protobuf for SignatureAndData {} diff --git a/crates/ibc/src/clients/ics06_solomachine/types.rs b/crates/ibc/src/clients/ics06_solomachine/types.rs index 54f84a544..b7fbcc45f 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types.rs @@ -1,3 +1,5 @@ +use core::fmt::write; + use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; use ibc_proto::ibc::lightclients::solomachine::v2::DataType as RawDataType; @@ -41,6 +43,23 @@ pub enum DataType { Header, } +impl core::fmt::Display for DataType { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + match self { + DataType::UninitializedUnspecified => write!(f, "uninitialized unspecified"), + DataType::ClientState => write!(f, "client state"), + DataType::ConsensusState => write!(f, "consensus state"), + DataType::ConnectionState => write!(f, "connection state"), + DataType::ChannelState => write!(f, "channel state"), + DataType::PacketCommitment => write!(f, "packet commitment"), + DataType::PacketAcknowledgement => write!(f, "packet acknowledgement"), + DataType::PacketReceiptAbsence => write!(f, "packet receipt absence"), + DataType::NextSequenceRecv => write!(f, "next sequence recv"), + DataType::Header => write!(f, "header"), + } + } +} + impl From for DataType { fn from(raw: RawDataType) -> Self { match raw { From 868ce3a9998941cd0eb3807b5db731baef62fedb Mon Sep 17 00:00:00 2001 From: Davirain Date: Mon, 15 May 2023 16:39:03 +0800 Subject: [PATCH 31/35] Add validation and verification methods for client state and signature in ICS06. --- .../clients/ics06_solomachine/client_state.rs | 129 ++++++++++++++++-- .../src/clients/ics06_solomachine/error.rs | 6 + .../src/clients/ics06_solomachine/proof.rs | 15 +- .../src/clients/ics06_solomachine/types.rs | 2 - .../ics06_solomachine/types/sign_bytes.rs | 4 +- 5 files changed, 141 insertions(+), 15 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index 7176e6e32..b645d4f72 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -1,7 +1,12 @@ +use super::misbehaviour::signature_and_data::SignatureAndData; use crate::clients::ics06_solomachine::consensus_state::ConsensusState as SmConsensusState; use crate::clients::ics06_solomachine::error::Error; use crate::clients::ics06_solomachine::header::Header as SmHeader; use crate::clients::ics06_solomachine::misbehaviour::Misbehaviour as SmMisbehaviour; +use crate::clients::ics06_solomachine::proof::verify_signature; +use crate::clients::ics06_solomachine::types::sign_bytes::SignBytes; +use crate::clients::ics06_solomachine::types::timestamped_signature_data::TimestampedSignatureData; +use crate::clients::ics06_solomachine::types::DataType; use crate::core::ics02_client::client_state::UpdateKind; use crate::core::ics02_client::client_state::{ClientState as Ics2ClientState, UpdatedState}; use crate::core::ics02_client::client_type::ClientType; @@ -18,6 +23,7 @@ use crate::core::{ExecutionContext, ValidationContext}; use crate::prelude::*; use crate::Height; use core::time::Duration; +use cosmrs::crypto::PublicKey; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::commitment::v1::MerkleProof as RawMerkleProof; use ibc_proto::ibc::lightclients::solomachine::v2::ClientState as RawSmClientState; @@ -77,13 +83,61 @@ impl ClientState { pub fn time_stamp(&self) -> Timestamp { self.consensus_state.timestamp } + + // Validate performs basic validation of the client state fields. + pub fn valida_basic(&self) -> Result<(), Error> { + if self.sequence.revision_height() == 0 { + return Err(Error::SequenceCannotZero); + } + self.consensus_state.valida_basic() + } + + // produceVerificationArgs perfoms the basic checks on the arguments that are + // shared between the verification functions and returns the public key of the + // consensus state, the unmarshalled proof representing the signature and timestamp. + pub fn produce_verification_args( + &self, + proof: &CommitmentProofBytes, + ) -> Result<(PublicKey, SignatureAndData, Timestamp, Height), Error> { + let proof = Vec::::from(proof.clone()); + if proof.is_empty() { + return Err(Error::ProofCannotEmpty); + } + let timestamped_sig_data = TimestampedSignatureData::decode_vec(&proof).map_err(|e| { + Error::Other(format!( + "failed to decode proof into type TimestampedSignatureData: {}", + e + )) + })?; + + let timestamp = timestamped_sig_data.timestamp; + + if timestamped_sig_data.signature_data.is_empty() { + return Err(Error::Other("signature data cannot be empty".into())); + } + + let signature_and_data = SignatureAndData::decode_vec(×tamped_sig_data.signature_data) + .map_err(|_| Error::Other("failed to decode SignatureData".into()))?; + + if self.consensus_state.timestamp > timestamp { + return Err(Error::Other(format!( + "the consensus state timestamp is greater than the signature timestamp ({} >= {})", + self.consensus_state.timestamp, timestamp + ))); + } + + let sequence = self.latest_height(); + let public_key = self.consensus_state.public_key(); + Ok((public_key, signature_and_data, timestamp, sequence)) + } } impl Ics2ClientState for ClientState { /// Return the chain identifier which this client is serving (i.e., the client is verifying /// consensus states from this chain). fn chain_id(&self) -> ChainId { - todo!() + // todo(davirian) + ChainId::default() } /// ClientType is Solo Machine. @@ -258,24 +312,83 @@ impl Ics2ClientState for ClientState { fn verify_membership( &self, _prefix: &CommitmentPrefix, - _proof: &CommitmentProofBytes, + proof: &CommitmentProofBytes, _root: &CommitmentRoot, - _path: Path, - _value: Vec, + path: Path, + value: Vec, ) -> Result<(), ClientError> { - todo!() + let (public_key, sig_data, timestamp, sequence) = self.produce_verification_args(proof)?; + let data_type = match path { + Path::ClientState(_) => DataType::ClientState, + Path::ClientConsensusState(_) => DataType::ConsensusState, + Path::ClientConnection(_) => DataType::ConnectionState, + Path::Connection(_) => DataType::ConnectionState, + Path::Ports(_) => DataType::Header, + Path::ChannelEnd(_) => DataType::ChannelState, + Path::SeqSend(_) => DataType::Header, + Path::SeqRecv(_) => DataType::NextSequenceRecv, + Path::SeqAck(_) => DataType::Header, + Path::Commitment(_) => DataType::PacketCommitment, + Path::Ack(_) => DataType::PacketAcknowledgement, + Path::Receipt(_) => DataType::Header, + Path::UpgradeClient(_) => DataType::Header, + }; + let sign_bytes = SignBytes { + sequence: sequence.revision_height(), + timestamp, + diversifier: self.consensus_state.diversifier.clone(), + data_type, + data: value, + }; + let sign_bz = sign_bytes.encode_vec(); + + verify_signature(public_key, sign_bz, sig_data).map_err(|e| ClientError::Other { + description: e.to_string(), + }) } // Verify_non_membership is a generic proof verification method which // verifies the absence of a given commitment. + // + // VerifyNonMembership is a generic proof verification method which verifies the absence + // of a given CommitmentPath at the latest sequence. + // The caller is expected to construct the full CommitmentPath from a CommitmentPrefix + // and a standardized path (as defined in ICS 24). fn verify_non_membership( &self, _prefix: &CommitmentPrefix, - _proof: &CommitmentProofBytes, + proof: &CommitmentProofBytes, _root: &CommitmentRoot, - _path: Path, + path: Path, ) -> Result<(), ClientError> { - todo!() + let (public_key, sig_data, timestamp, sequence) = self.produce_verification_args(proof)?; + let data_type = match path { + Path::ClientState(_) => DataType::ClientState, + Path::ClientConsensusState(_) => DataType::ConsensusState, + Path::ClientConnection(_) => DataType::ConnectionState, + Path::Connection(_) => DataType::ConnectionState, + Path::Ports(_) => DataType::Header, + Path::ChannelEnd(_) => DataType::ChannelState, + Path::SeqSend(_) => DataType::Header, + Path::SeqRecv(_) => DataType::NextSequenceRecv, + Path::SeqAck(_) => DataType::Header, + Path::Commitment(_) => DataType::PacketCommitment, + Path::Ack(_) => DataType::PacketAcknowledgement, + Path::Receipt(_) => DataType::Header, + Path::UpgradeClient(_) => DataType::Header, + }; + let sign_bytes = SignBytes { + sequence: sequence.revision_height(), + timestamp, + diversifier: self.consensus_state.diversifier.clone(), + data_type, + data: vec![], + }; + let sign_bz = sign_bytes.encode_vec(); + + verify_signature(public_key, sign_bz, sig_data).map_err(|e| ClientError::Other { + description: e.to_string(), + }) } } diff --git a/crates/ibc/src/clients/ics06_solomachine/error.rs b/crates/ibc/src/clients/ics06_solomachine/error.rs index 931e5ce78..31b29489c 100644 --- a/crates/ibc/src/clients/ics06_solomachine/error.rs +++ b/crates/ibc/src/clients/ics06_solomachine/error.rs @@ -35,6 +35,12 @@ pub enum Error { ConsensusStateIsEmpty, /// SignatureAndData empty SignatureAndDataIsEmpty, + /// Sequence cannot be zero + SequenceCannotZero, + /// Proof cannot be empty + ProofCannotEmpty, + /// Other : `{0}` + Other(String), } impl From for ClientError { diff --git a/crates/ibc/src/clients/ics06_solomachine/proof.rs b/crates/ibc/src/clients/ics06_solomachine/proof.rs index eb896e5fd..3967de6de 100644 --- a/crates/ibc/src/clients/ics06_solomachine/proof.rs +++ b/crates/ibc/src/clients/ics06_solomachine/proof.rs @@ -1,8 +1,17 @@ -use alloc::string::String; +use super::misbehaviour::signature_and_data::SignatureAndData; +use crate::clients::ics06_solomachine::error::Error; use alloc::vec::Vec; use cosmrs::crypto::PublicKey; -// use cosmrs::tx::SignatureBytes; -pub fn verify_signature(_publik_key: PublicKey, _sign_bytes: Vec) -> Result<(), String> { +// Verify_signature verifies if the the provided public key generated the signature +// over the given data. Single and Multi signature public keys are supported. +// The signature data type must correspond to the public key type. An error is +// returned if signature verification fails or an invalid SignatureData type is +// provided. +pub fn verify_signature( + _publik_key: PublicKey, + _sign_bytes: Vec, + _signature_and_data: SignatureAndData, +) -> Result<(), Error> { todo!() } diff --git a/crates/ibc/src/clients/ics06_solomachine/types.rs b/crates/ibc/src/clients/ics06_solomachine/types.rs index b7fbcc45f..b75962575 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types.rs @@ -1,5 +1,3 @@ -use core::fmt::write; - use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; use ibc_proto::ibc::lightclients::solomachine::v2::DataType as RawDataType; diff --git a/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs b/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs index a12ca48df..54657d9a3 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/sign_bytes.rs @@ -4,7 +4,7 @@ use crate::prelude::*; use ibc_proto::ibc::lightclients::solomachine::v2::SignBytes as RawSignBytes; use super::DataType; -// use ibc_proto::protobuf::Protobuf; +use ibc_proto::protobuf::Protobuf; /// SignBytes defines the signed bytes used for signature verification. #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -19,7 +19,7 @@ pub struct SignBytes { pub data: Vec, } -// impl Protobuf for SignBytes {} +impl Protobuf for SignBytes {} impl TryFrom for SignBytes { type Error = Error; From 85a1110b65511ee168ff9effd1b04584e484ea5c Mon Sep 17 00:00:00 2001 From: Davirain Date: Mon, 15 May 2023 17:10:17 +0800 Subject: [PATCH 32/35] Refactor solomachine client state update, verify header signature and assert timestamp. --- .../client_state/update_client.rs | 48 +++++++++++++++++-- .../ics06_solomachine/types/header_data.rs | 4 +- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state/update_client.rs b/crates/ibc/src/clients/ics06_solomachine/client_state/update_client.rs index d723d2916..e06aea698 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state/update_client.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state/update_client.rs @@ -1,19 +1,57 @@ +use ibc_proto::protobuf::Protobuf; + +use crate::clients::ics06_solomachine::types::header_data::HeaderData; +use crate::clients::ics06_solomachine::types::sign_bytes::SignBytes; use crate::prelude::*; +use super::ClientState; use crate::clients::ics06_solomachine::header::Header as SmHeader; +use crate::clients::ics06_solomachine::misbehaviour::signature_and_data::SignatureAndData; +use crate::clients::ics06_solomachine::proof::verify_signature; use crate::core::ics02_client::error::ClientError; use crate::core::{ics24_host::identifier::ClientId, ValidationContext}; - -use super::ClientState; - impl ClientState { pub fn verify_header( &self, _ctx: &dyn ValidationContext, _client_id: &ClientId, - _header: SmHeader, + header: SmHeader, ) -> Result<(), ClientError> { - todo!() + // assert update timestamp is not less than current consensus state timestamp + if header.timestamp < self.consensus_state.timestamp { + return Err(ClientError::Other { + description: format!( + "header timestamp is less than to the consensus state timestamp ({} < {})", + header.timestamp, self.consensus_state.timestamp, + ), + }); + } + + // assert currently registered public key signed over the new public key with correct sequence + let header_data = HeaderData { + new_pub_key: header.new_public_key, + new_diversifier: header.new_diversifier, + }; + let data_bz = header_data.encode_vec(); + + let sign_bytes = SignBytes { + sequence: self.sequence.revision_height(), + timestamp: header.timestamp, + diversifier: self.consensus_state.diversifier.clone(), + data_type: crate::clients::ics06_solomachine::types::DataType::Header, + data: data_bz, + }; + let data = sign_bytes.encode_vec(); + let sig_data = + SignatureAndData::decode_vec(&header.signature).map_err(|_| ClientError::Other { + description: "failed to decode SignatureData".into(), + })?; + + let public_key = self.consensus_state.public_key(); + + verify_signature(public_key, data, sig_data).map_err(|e| ClientError::Other { + description: e.to_string(), + }) } pub fn check_for_misbehaviour_update_client( diff --git a/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs index 6cf46a363..8ceb8925c 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs @@ -1,6 +1,6 @@ use crate::clients::ics06_solomachine::error::Error; use crate::prelude::*; -use ibc_proto::google::protobuf::Any; +use cosmrs::crypto::PublicKey; use ibc_proto::ibc::lightclients::solomachine::v2::HeaderData as RawHeaderData; use ibc_proto::protobuf::Protobuf; @@ -9,7 +9,7 @@ use ibc_proto::protobuf::Protobuf; #[derive(Clone, PartialEq)] pub struct HeaderData { /// header public key - pub new_pub_key: Option, + pub new_pub_key: PublicKey, /// header diversifier pub new_diversifier: String, } From 81cc8e30e0653bb4d08735453be63c2dfa3d8b04 Mon Sep 17 00:00:00 2001 From: Davirain Date: Mon, 15 May 2023 19:12:58 +0800 Subject: [PATCH 33/35] feat: update error.rs and related types --- .../src/clients/ics06_solomachine/error.rs | 11 ++++++++++ .../types/channel_state_data.rs | 8 ++++---- .../types/client_stata_data.rs | 20 ++++++++++++++----- .../types/connection_state_data.rs | 20 ++++++++++++++----- .../types/consensus_state_data.rs | 20 ++++++++++++++----- .../ics06_solomachine/types/header_data.rs | 16 +++++++++++---- .../types/packet_receipt_absence_data.rs | 8 ++++---- 7 files changed, 76 insertions(+), 27 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/error.rs b/crates/ibc/src/clients/ics06_solomachine/error.rs index 31b29489c..900595449 100644 --- a/crates/ibc/src/clients/ics06_solomachine/error.rs +++ b/crates/ibc/src/clients/ics06_solomachine/error.rs @@ -1,3 +1,4 @@ +use crate::core::ics03_connection::error::ConnectionError; use crate::core::ics04_channel::error::ChannelError; use crate::prelude::*; @@ -23,6 +24,10 @@ pub enum Error { ParseTimeError(ParseTimestampError), /// Channel error: `{0}` ChannelError(ChannelError), + /// Client error: `{0}` + ClientError(ClientError), + /// Connection error: `{0}` + ConnectionError(ConnectionError), /// timestamp cannot be 0 TimeStampIsEmpty, /// diversifier cannot contain only spaces @@ -39,6 +44,12 @@ pub enum Error { SequenceCannotZero, /// Proof cannot be empty ProofCannotEmpty, + /// ChannelEnd is empty + ChannelEndIsEmpty, + /// ClientState is empty + ClientStateIsEmpty, + /// ConnectionEnd is empty + ConnectionEndIsEmpty, /// Other : `{0}` Other(String), } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs index 7b27ef73c..f8a08e619 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/channel_state_data.rs @@ -9,7 +9,7 @@ use ibc_proto::protobuf::Protobuf; #[derive(Clone, PartialEq)] pub struct ChannelStateData { pub path: Vec, - pub channel: Option, + pub channel: ChannelEnd, } impl Protobuf for ChannelStateData {} @@ -21,8 +21,8 @@ impl TryFrom for ChannelStateData { path: raw.path, channel: raw .channel - .map(TryInto::try_into) - .transpose() + .ok_or(Error::ChannelEndIsEmpty)? + .try_into() .map_err(Error::ChannelError)?, }) } @@ -32,7 +32,7 @@ impl From for RawChannelStateData { fn from(value: ChannelStateData) -> Self { Self { path: value.path, - channel: value.channel.map(Into::into), + channel: Some(value.channel.into()), } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs index 4a5fe8181..6785f4c33 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/client_stata_data.rs @@ -9,7 +9,7 @@ use ibc_proto::protobuf::Protobuf; pub struct ClientStateData { pub path: Vec, // Ics06 solomachine client state - pub client_state: Option, + pub client_state: ClientState, } impl Protobuf for ClientStateData {} @@ -17,13 +17,23 @@ impl Protobuf for ClientStateData {} impl TryFrom for ClientStateData { type Error = Error; - fn try_from(_raw: RawClientStateData) -> Result { - todo!() + fn try_from(raw: RawClientStateData) -> Result { + Ok(Self { + path: raw.path, + client_state: raw + .client_state + .ok_or(Error::ClientStateIsEmpty)? + .try_into() + .map_err(Error::ClientError)?, + }) } } impl From for RawClientStateData { - fn from(_value: ClientStateData) -> Self { - todo!() + fn from(value: ClientStateData) -> Self { + Self { + path: value.path, + client_state: Some(value.client_state.into()), + } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs index c918fbcab..36aca1724 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/connection_state_data.rs @@ -10,7 +10,7 @@ use ibc_proto::protobuf::Protobuf; #[derive(Clone, PartialEq)] pub struct ConnectionStateData { pub path: Vec, - pub connection: Option, + pub connection: ConnectionEnd, } impl Protobuf for ConnectionStateData {} @@ -18,13 +18,23 @@ impl Protobuf for ConnectionStateData {} impl TryFrom for ConnectionStateData { type Error = Error; - fn try_from(_raw: RawConnectionStateData) -> Result { - todo!() + fn try_from(raw: RawConnectionStateData) -> Result { + Ok(Self { + path: raw.path, + connection: raw + .connection + .ok_or(Error::ConnectionEndIsEmpty)? + .try_into() + .map_err(Error::ConnectionError)?, + }) } } impl From for RawConnectionStateData { - fn from(_value: ConnectionStateData) -> Self { - todo!() + fn from(value: ConnectionStateData) -> Self { + Self { + path: value.path, + connection: Some(value.connection.into()), + } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs index 3ac146d24..2c0589a77 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/consensus_state_data.rs @@ -11,7 +11,7 @@ use ibc_proto::protobuf::Protobuf; pub struct ConsensusStateData { pub path: Vec, // ics06 solomachine client consensus state - pub consensus_state: Option, + pub consensus_state: ConsensusState, } impl Protobuf for ConsensusStateData {} @@ -19,13 +19,23 @@ impl Protobuf for ConsensusStateData {} impl TryFrom for ConsensusStateData { type Error = Error; - fn try_from(_raw: RawConsensusStateData) -> Result { - todo!() + fn try_from(raw: RawConsensusStateData) -> Result { + Ok(Self { + path: raw.path, + consensus_state: raw + .consensus_state + .ok_or(Error::ConsensusStateIsEmpty)? + .try_into() + .map_err(Error::ClientError)?, + }) } } impl From for RawConsensusStateData { - fn from(_value: ConsensusStateData) -> Self { - todo!() + fn from(value: ConsensusStateData) -> Self { + Self { + path: value.path, + consensus_state: Some(value.consensus_state.into()), + } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs index 8ceb8925c..84b6b705d 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/header_data.rs @@ -19,13 +19,21 @@ impl Protobuf for HeaderData {} impl TryFrom for HeaderData { type Error = Error; - fn try_from(_raw: RawHeaderData) -> Result { - todo!() + fn try_from(raw: RawHeaderData) -> Result { + let new_pub_key = PublicKey::try_from(raw.new_pub_key.ok_or(Error::PublicKeyIsEmpty)?) + .map_err(Error::PublicKeyParseFailed)?; + Ok(Self { + new_pub_key, + new_diversifier: raw.new_diversifier, + }) } } impl From for RawHeaderData { - fn from(_value: HeaderData) -> Self { - todo!() + fn from(value: HeaderData) -> Self { + Self { + new_pub_key: Some(value.new_pub_key.to_any().expect("never failed")), + new_diversifier: value.new_diversifier, + } } } diff --git a/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs b/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs index e5c1a829d..f28f895a2 100644 --- a/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs +++ b/crates/ibc/src/clients/ics06_solomachine/types/packet_receipt_absence_data.rs @@ -15,13 +15,13 @@ impl Protobuf for PacketReceiptAbsenceData {} impl TryFrom for PacketReceiptAbsenceData { type Error = Error; - fn try_from(_raw: RawPacketReceiptAbsenceData) -> Result { - todo!() + fn try_from(raw: RawPacketReceiptAbsenceData) -> Result { + Ok(Self { path: raw.path }) } } impl From for RawPacketReceiptAbsenceData { - fn from(_value: PacketReceiptAbsenceData) -> Self { - todo!() + fn from(value: PacketReceiptAbsenceData) -> Self { + Self { path: value.path } } } From 63764b3c6775c396b286ae642a920f0e07e1dec3 Mon Sep 17 00:00:00 2001 From: Davirain Date: Mon, 15 May 2023 19:51:20 +0800 Subject: [PATCH 34/35] Add implementation for updating Solo Machine client state from header and store it. --- .../clients/ics06_solomachine/client_state.rs | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state.rs b/crates/ibc/src/clients/ics06_solomachine/client_state.rs index b645d4f72..b23bc052d 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state.rs @@ -249,13 +249,29 @@ impl Ics2ClientState for ClientState { /// /// Post-condition: on success, the return value MUST contain at least one /// height. + // ref: https://github.com/cosmos/ibc-go/blob/388283012124fd3cd66c9541000541d9c6767117/modules/light-clients/06-solomachine/update.go#L80 fn update_state( &self, - _ctx: &mut dyn ExecutionContext, - _client_id: &ClientId, - _header: Any, + ctx: &mut dyn ExecutionContext, + client_id: &ClientId, + header: Any, ) -> Result, ClientError> { - todo!() + let sm_header = SmHeader::try_from(header).map_err(|e| ClientError::Other { + description: format!("decode SmHeader Error({})", e), + })?; + + let consensus_state = SmConsensusState { + public_key: sm_header.new_public_key, + diversifier: sm_header.new_diversifier, + timestamp: sm_header.timestamp, + }; + let mut new_client_state = self.clone(); + new_client_state.sequence.increment(); + new_client_state.consensus_state = consensus_state; + + ctx.store_client_state(ClientStatePath::new(client_id), new_client_state.into_box())?; + + Ok(vec![sm_header.sequence]) } /// update_state_on_misbehaviour should perform appropriate state changes on From eba936ff5274067395031c27030699dc0c281fb1 Mon Sep 17 00:00:00 2001 From: Davirain Date: Mon, 15 May 2023 20:11:10 +0800 Subject: [PATCH 35/35] Add verification of solomachine signatures and data in updating the client state. --- .../client_state/misbehaviour.rs | 49 ++++++++++++++++++- .../client_state/update_client.rs | 1 + 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state/misbehaviour.rs b/crates/ibc/src/clients/ics06_solomachine/client_state/misbehaviour.rs index f46f2d2a5..317336765 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state/misbehaviour.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state/misbehaviour.rs @@ -1,8 +1,13 @@ +use ibc_proto::protobuf::Protobuf; + +use crate::clients::ics06_solomachine::types::sign_bytes::SignBytes; use crate::prelude::*; +use crate::clients::ics06_solomachine::client_state::SignatureAndData; use crate::clients::ics06_solomachine::consensus_state::ConsensusState as SmConsensusState; use crate::clients::ics06_solomachine::header::Header as SmHeader; use crate::clients::ics06_solomachine::misbehaviour::Misbehaviour as SmMisbehaviour; +use crate::clients::ics06_solomachine::proof::verify_signature; use crate::core::ics02_client::error::ClientError; use crate::core::timestamp::Timestamp; use crate::core::{ics24_host::identifier::ClientId, ValidationContext}; @@ -18,7 +23,49 @@ impl ClientState { _client_id: &ClientId, _misbehaviour: SmMisbehaviour, ) -> Result<(), ClientError> { - todo!() + // NOTE: a check that the misbehaviour message data are not equal is done by + // misbehaviour.ValidateBasic which is called by the 02-client keeper. + // verify first signature + self.verify_signature_and_data(_misbehaviour.clone(), _misbehaviour.signature_one.clone()) + .map_err(|_| ClientError::Other { + description: "failed to verify signature one".into(), + })?; + + // verify second signature + self.verify_signature_and_data(_misbehaviour.clone(), _misbehaviour.signature_two) + .map_err(|_| ClientError::Other { + description: "failed to verify signature one".into(), + }) + } + + // verifySignatureAndData verifies that the currently registered public key has signed + // over the provided data and that the data is valid. The data is valid if it can be + // unmarshaled into the specified data type. + // ref: https://github.com/cosmos/ibc-go/blob/388283012124fd3cd66c9541000541d9c6767117/modules/light-clients/06-solomachine/misbehaviour_handle.go#L41 + pub fn verify_signature_and_data( + &self, + misbehaviour: SmMisbehaviour, + signature_and_data: SignatureAndData, + ) -> Result<(), ClientError> { + let sign_bytes = SignBytes { + sequence: misbehaviour.sequence.revision_height(), + timestamp: signature_and_data.timestamp, + diversifier: self.consensus_state.diversifier.clone(), + data_type: crate::clients::ics06_solomachine::types::DataType::Header, + data: signature_and_data.data, + }; + let data = sign_bytes.encode_vec(); + + let signature_and_data = SignatureAndData::decode_vec(&signature_and_data.signature) + .map_err(|_| ClientError::Other { + description: "failed to decode SignatureData".into(), + })?; + + let public_key = self.consensus_state.public_key(); + + verify_signature(public_key, data, signature_and_data).map_err(|e| ClientError::Other { + description: e.to_string(), + }) } pub fn verify_misbehaviour_header( diff --git a/crates/ibc/src/clients/ics06_solomachine/client_state/update_client.rs b/crates/ibc/src/clients/ics06_solomachine/client_state/update_client.rs index e06aea698..d5e72b183 100644 --- a/crates/ibc/src/clients/ics06_solomachine/client_state/update_client.rs +++ b/crates/ibc/src/clients/ics06_solomachine/client_state/update_client.rs @@ -38,6 +38,7 @@ impl ClientState { sequence: self.sequence.revision_height(), timestamp: header.timestamp, diversifier: self.consensus_state.diversifier.clone(), + // todo(davirain): https://github.com/cosmos/ibc-go/blob/388283012124fd3cd66c9541000541d9c6767117/modules/light-clients/06-solomachine/update.go#LL52C36-L52C36 data_type: crate::clients::ics06_solomachine::types::DataType::Header, data: data_bz, };