From c4b6e3035c3b717f9f8ca09ec97c15beaf3d7cd9 Mon Sep 17 00:00:00 2001 From: Anca Zamfir Date: Thu, 19 Aug 2021 15:26:36 +0200 Subject: [PATCH] Compatibility with Cosmos SDK v0.43+ (#948) * Adapted proto compiler. Regenerated Rust files * Adapt to newer namespace for apps. * Manual fix for Staking erroneous compilation * Workaround: disabled chain upgrade * Added specific GRPC-web port to prevent conflict on 9091. * Upgrade protos * Add support for new message action strings * Improved output for one-chain script * CLI for chain upgrade proposal adapted to gaia v5. * Re-generated proto files with updated proto-compiler (fmt enabled). * Manual fix for staking::Validators erroneous compilation; added the .applications.transfer generated file * Quick feature for parametrizing upgraded chain * Clippy fix. Meta for params for better display. * Adapted query_upgraded_client_state * Adapted query_upgraded_consensus_state to ibc-go-v1 * Moved from gRPC to ABCI * Adapted send_tx_simulate to new def of SimulateRequest * Added parametrizable upgrade plan name * Fix unwraps. Retain unbonding period if none specified. * Missing post-merge bracket * Removed register and send match arms for rpc events * Support for new message.actions strings of ICS27 Based on discussion from https://github.com/cosmos/cosmos-sdk/pull/9139#discussion_r628159208 This is not yet tested! * Update protos sdk(v0.43.0-rc2) & ibc-go(v1.0.0-rc3) * Revert "Added specific GRPC-web port to prevent conflict on 9091." This reverts commit abf6dba19f8eb5fcc370fcb33edc9bf5a1c4c21a. * Add missing fields in upgrade Plan * Fix clippy warnings * Added another action field to match intertx MsgSend * Update protos sdk(v0.43.0) & ibc-go(v1.0.0) * Update cosmos SDK module version requirement in compatibility.rs * Add legacy upgrade support (#1289) * Add legacy upgrade support * Fix check for legacy * Update .changelog * Add TODO * Apply suggestion Co-authored-by: Adi Seredinschi Co-authored-by: Adi Seredinschi * Apply suggestions * Update .changelog * Fix .changelog entry Co-authored-by: Adi Seredinschi Co-authored-by: Shoaib Ahmed --- .../features/1287-upgrade-legacy.md | 3 + .../948-upgrade-to-cosmos-sdk-v0.43.md | 3 + modules/src/application/mod.rs | 5 + .../src/ics02_client/msgs/create_client.rs | 2 +- .../src/ics02_client/msgs/update_client.rs | 2 +- proto-compiler/README.md | 2 +- proto-compiler/src/cmd/compile.rs | 18 +- proto/src/prost/COSMOS_IBC_COMMIT | 1 + proto/src/prost/COSMOS_SDK_COMMIT | 2 +- proto/src/prost/cosmos.auth.v1beta1.rs | 44 +- proto/src/prost/cosmos.base.query.v1beta1.rs | 3 + .../prost/cosmos.base.reflection.v2alpha1.rs | 376 ++++++++++++++++++ proto/src/prost/cosmos.base.store.v1beta1.rs | 16 + .../prost/cosmos.base.tendermint.v1beta1.rs | 2 + proto/src/prost/cosmos.gov.v1beta1.rs | 92 +++-- proto/src/prost/cosmos.staking.v1beta1.rs | 125 ++++-- proto/src/prost/cosmos.tx.v1beta1.rs | 9 +- proto/src/prost/cosmos.upgrade.v1beta1.rs | 64 ++- .../src/prost/ibc.applications.transfer.v1.rs | 20 +- proto/src/prost/ibc.core.channel.v1.rs | 88 ++-- proto/src/prost/ibc.core.client.v1.rs | 234 ++++++++--- proto/src/prost/ibc.core.connection.v1.rs | 51 ++- .../prost/ibc.lightclients.solomachine.v1.rs | 14 +- .../prost/ibc.lightclients.solomachine.v2.rs | 205 ++++++++++ .../prost/ibc.lightclients.tendermint.v1.rs | 13 +- relayer-cli/src/commands/tx.rs | 4 +- relayer-cli/src/commands/tx/upgrade.rs | 52 ++- relayer/src/chain/cosmos.rs | 121 ++---- relayer/src/chain/cosmos/compatibility.rs | 2 +- relayer/src/error.rs | 16 +- relayer/src/event/rpc.rs | 97 +++-- relayer/src/upgrade_chain.rs | 115 ++++-- 32 files changed, 1416 insertions(+), 385 deletions(-) create mode 100644 .changelog/unreleased/features/1287-upgrade-legacy.md create mode 100644 .changelog/unreleased/features/948-upgrade-to-cosmos-sdk-v0.43.md create mode 100644 proto/src/prost/COSMOS_IBC_COMMIT create mode 100644 proto/src/prost/cosmos.base.reflection.v2alpha1.rs create mode 100644 proto/src/prost/ibc.lightclients.solomachine.v2.rs diff --git a/.changelog/unreleased/features/1287-upgrade-legacy.md b/.changelog/unreleased/features/1287-upgrade-legacy.md new file mode 100644 index 0000000000..2ff89373cf --- /dev/null +++ b/.changelog/unreleased/features/1287-upgrade-legacy.md @@ -0,0 +1,3 @@ +- Add `--legacy | -l` flag to support upgrades for chains built with Cosmos SDK < v0.43.0 ([#1287]) + +[#1287]: https://github.com/informalsystems/ibc-rs/issues/1287 diff --git a/.changelog/unreleased/features/948-upgrade-to-cosmos-sdk-v0.43.md b/.changelog/unreleased/features/948-upgrade-to-cosmos-sdk-v0.43.md new file mode 100644 index 0000000000..8b558e883e --- /dev/null +++ b/.changelog/unreleased/features/948-upgrade-to-cosmos-sdk-v0.43.md @@ -0,0 +1,3 @@ +- Upgrade to Cosmos SDK proto (v0.43.0) & ibc-go proto (v1.0.0) ([#948]) + +- [#948]: https://github.com/informalsystems/ibc-rs/pull/948 diff --git a/modules/src/application/mod.rs b/modules/src/application/mod.rs index bff5c4c1d5..c3eb98a343 100644 --- a/modules/src/application/mod.rs +++ b/modules/src/application/mod.rs @@ -1 +1,6 @@ pub mod ics20_fungible_token_transfer; + +// TODO: These consts should move into the ICS27 namespace +pub const ICS27_BANK_SEND_TYPE_URL: &str = "/cosmos.bank.v1beta1.MsgSend"; +pub const ICS27_SEND_TYPE_URL: &str = "/intertx.MsgSend"; +pub const ICS27_REGISTER_TYPE_URL: &str = "/intertx.MsgRegister"; diff --git a/modules/src/ics02_client/msgs/create_client.rs b/modules/src/ics02_client/msgs/create_client.rs index a01266d685..6c3e62bfc9 100644 --- a/modules/src/ics02_client/msgs/create_client.rs +++ b/modules/src/ics02_client/msgs/create_client.rs @@ -12,7 +12,7 @@ use crate::ics02_client::error::Error; use crate::signer::Signer; use crate::tx_msg::Msg; -pub(crate) const TYPE_URL: &str = "/ibc.core.client.v1.MsgCreateClient"; +pub const TYPE_URL: &str = "/ibc.core.client.v1.MsgCreateClient"; /// A type of message that triggers the creation of a new on-chain (IBC) client. #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/modules/src/ics02_client/msgs/update_client.rs b/modules/src/ics02_client/msgs/update_client.rs index 9062f203a1..f38406850c 100644 --- a/modules/src/ics02_client/msgs/update_client.rs +++ b/modules/src/ics02_client/msgs/update_client.rs @@ -13,7 +13,7 @@ use crate::ics24_host::identifier::ClientId; use crate::signer::Signer; use crate::tx_msg::Msg; -pub(crate) const TYPE_URL: &str = "/ibc.core.client.v1.MsgUpdateClient"; +pub const TYPE_URL: &str = "/ibc.core.client.v1.MsgUpdateClient"; /// A type of message that triggers the update of an on-chain (IBC) client with new headers. #[derive(Clone, Debug, PartialEq)] // TODO: Add Eq bound when possible diff --git a/proto-compiler/README.md b/proto-compiler/README.md index d27186b9ab..f767d6402a 100644 --- a/proto-compiler/README.md +++ b/proto-compiler/README.md @@ -15,7 +15,7 @@ cargo build --locked Run the following command to clone the Cosmos SDK and the IBC-Go repositories, and check out a specific commit: ```bash -$ cargo run -- clone --out /tmp/cosmos --sdk-commit 7648bfca45b9d0897103ec739210607dce77c4fb --ibc-go-commit 333c1f338b2a14a1928a6f8ab64c37123c0e97b6 +$ cargo run -- clone --out /tmp/cosmos --sdk-commit 8cfa2c26738276d895caf9eb98b3f70616218e17 --ibc-go-commit d70f49c8f612d60f1b7e2f1d1f160f28988962e1 ``` Note: diff --git a/proto-compiler/src/cmd/compile.rs b/proto-compiler/src/cmd/compile.rs index a2f7d2588d..506f13fc81 100644 --- a/proto-compiler/src/cmd/compile.rs +++ b/proto-compiler/src/cmd/compile.rs @@ -27,10 +27,9 @@ pub struct CompileCmd { impl CompileCmd { pub fn run(&self) { - let with_ibc = self.ibc.is_none(); let tmp_sdk = TempDir::new("ibc-proto-sdk").unwrap(); Self::output_version(&self.sdk, tmp_sdk.as_ref(), "COSMOS_SDK_COMMIT"); - Self::compile_sdk_protos(&self.sdk, tmp_sdk.as_ref(), with_ibc); + Self::compile_sdk_protos(&self.sdk, tmp_sdk.as_ref(), self.ibc.clone()); match &self.ibc { None => { @@ -121,7 +120,7 @@ impl CompileCmd { } } - fn compile_sdk_protos(sdk_dir: &Path, out_dir: &Path, with_ibc: bool) { + fn compile_sdk_protos(sdk_dir: &Path, out_dir: &Path, ibc_dep: Option) { println!( "[info ] Compiling Cosmos-SDK .proto files to Rust into '{}'...", out_dir.display() @@ -130,7 +129,7 @@ impl CompileCmd { let root = env!("CARGO_MANIFEST_DIR"); // Paths - let mut proto_paths = vec![ + let proto_paths = vec![ format!("{}/../proto/definitions/mock", root), format!("{}/proto/cosmos/auth", sdk_dir.display()), format!("{}/proto/cosmos/gov", sdk_dir.display()), @@ -140,17 +139,18 @@ impl CompileCmd { format!("{}/proto/cosmos/upgrade", sdk_dir.display()), ]; - if with_ibc { - // Use the IBC proto files from the SDK - proto_paths.push(format!("{}/proto/ibc", sdk_dir.display())); - } - let proto_includes_paths = [ + let mut proto_includes_paths = vec![ format!("{}/../proto", root), format!("{}/proto", sdk_dir.display()), format!("{}/third_party/proto", sdk_dir.display()), ]; + if let Some(ibc_dir) = ibc_dep { + // Use the IBC proto files from the SDK + proto_includes_paths.push(format!("{}/proto", ibc_dir.display()),); + } + // List available proto files let mut protos: Vec = vec![]; for proto_path in &proto_paths { diff --git a/proto/src/prost/COSMOS_IBC_COMMIT b/proto/src/prost/COSMOS_IBC_COMMIT new file mode 100644 index 0000000000..35de0afb6d --- /dev/null +++ b/proto/src/prost/COSMOS_IBC_COMMIT @@ -0,0 +1 @@ +e9f1dc2a4f8631749c72e48957848cab3eb10762 \ No newline at end of file diff --git a/proto/src/prost/COSMOS_SDK_COMMIT b/proto/src/prost/COSMOS_SDK_COMMIT index a3ad18444f..e38880d6a2 100644 --- a/proto/src/prost/COSMOS_SDK_COMMIT +++ b/proto/src/prost/COSMOS_SDK_COMMIT @@ -1 +1 @@ -7648bfca45b9d0897103ec739210607dce77c4fb \ No newline at end of file +v0.43.0 \ No newline at end of file diff --git a/proto/src/prost/cosmos.auth.v1beta1.rs b/proto/src/prost/cosmos.auth.v1beta1.rs index 235e269ec8..4931e8e827 100644 --- a/proto/src/prost/cosmos.auth.v1beta1.rs +++ b/proto/src/prost/cosmos.auth.v1beta1.rs @@ -36,15 +36,22 @@ pub struct Params { #[prost(uint64, tag = "5")] pub sig_verify_cost_secp256k1: u64, } -/// GenesisState defines the auth module's genesis state. +/// QueryAccountsRequest is the request type for the Query/Accounts RPC method. #[derive(Clone, PartialEq, ::prost::Message)] -pub struct GenesisState { - /// params defines all the paramaters of the module. +pub struct QueryAccountsRequest { + /// pagination defines an optional pagination for the request. #[prost(message, optional, tag = "1")] - pub params: ::core::option::Option, - /// accounts are the accounts present at genesis. - #[prost(message, repeated, tag = "2")] + pub pagination: ::core::option::Option, +} +/// QueryAccountsResponse is the response type for the Query/Accounts RPC method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryAccountsResponse { + /// accounts are the existing accounts + #[prost(message, repeated, tag = "1")] pub accounts: ::prost::alloc::vec::Vec<::prost_types::Any>, + /// pagination defines the pagination in the response. + #[prost(message, optional, tag = "2")] + pub pagination: ::core::option::Option, } /// QueryAccountRequest is the request type for the Query/Account RPC method. #[derive(Clone, PartialEq, ::prost::Message)] @@ -104,6 +111,21 @@ pub mod query_client { let inner = tonic::client::Grpc::with_interceptor(inner, interceptor); Self { inner } } + #[doc = " Accounts returns all the existing accounts"] + pub async fn accounts( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/cosmos.auth.v1beta1.Query/Accounts"); + self.inner.unary(request.into_request(), path, codec).await + } #[doc = " Account returns account details based on address."] pub async fn account( &mut self, @@ -148,3 +170,13 @@ pub mod query_client { } } } +/// GenesisState defines the auth module's genesis state. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenesisState { + /// params defines all the paramaters of the module. + #[prost(message, optional, tag = "1")] + pub params: ::core::option::Option, + /// accounts are the accounts present at genesis. + #[prost(message, repeated, tag = "2")] + pub accounts: ::prost::alloc::vec::Vec<::prost_types::Any>, +} diff --git a/proto/src/prost/cosmos.base.query.v1beta1.rs b/proto/src/prost/cosmos.base.query.v1beta1.rs index dd279dc4f0..ddd77b72a7 100644 --- a/proto/src/prost/cosmos.base.query.v1beta1.rs +++ b/proto/src/prost/cosmos.base.query.v1beta1.rs @@ -27,6 +27,9 @@ pub struct PageRequest { /// is set. #[prost(bool, tag = "4")] pub count_total: bool, + /// reverse is set to true if results are to be returned in the descending order. + #[prost(bool, tag = "5")] + pub reverse: bool, } /// PageResponse is to be embedded in gRPC response messages where the /// corresponding request message has used PageRequest. diff --git a/proto/src/prost/cosmos.base.reflection.v2alpha1.rs b/proto/src/prost/cosmos.base.reflection.v2alpha1.rs new file mode 100644 index 0000000000..d56baed0d0 --- /dev/null +++ b/proto/src/prost/cosmos.base.reflection.v2alpha1.rs @@ -0,0 +1,376 @@ +/// AppDescriptor describes a cosmos-sdk based application +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AppDescriptor { + /// AuthnDescriptor provides information on how to authenticate transactions on the application + /// NOTE: experimental and subject to change in future releases. + #[prost(message, optional, tag = "1")] + pub authn: ::core::option::Option, + /// chain provides the chain descriptor + #[prost(message, optional, tag = "2")] + pub chain: ::core::option::Option, + /// codec provides metadata information regarding codec related types + #[prost(message, optional, tag = "3")] + pub codec: ::core::option::Option, + /// configuration provides metadata information regarding the sdk.Config type + #[prost(message, optional, tag = "4")] + pub configuration: ::core::option::Option, + /// query_services provides metadata information regarding the available queriable endpoints + #[prost(message, optional, tag = "5")] + pub query_services: ::core::option::Option, + /// tx provides metadata information regarding how to send transactions to the given application + #[prost(message, optional, tag = "6")] + pub tx: ::core::option::Option, +} +/// TxDescriptor describes the accepted transaction type +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TxDescriptor { + /// fullname is the protobuf fullname of the raw transaction type (for instance the tx.Tx type) + /// it is not meant to support polymorphism of transaction types, it is supposed to be used by + /// reflection clients to understand if they can handle a specific transaction type in an application. + #[prost(string, tag = "1")] + pub fullname: ::prost::alloc::string::String, + /// msgs lists the accepted application messages (sdk.Msg) + #[prost(message, repeated, tag = "2")] + pub msgs: ::prost::alloc::vec::Vec, +} +/// AuthnDescriptor provides information on how to sign transactions without relying +/// on the online RPCs GetTxMetadata and CombineUnsignedTxAndSignatures +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AuthnDescriptor { + /// sign_modes defines the supported signature algorithm + #[prost(message, repeated, tag = "1")] + pub sign_modes: ::prost::alloc::vec::Vec, +} +/// SigningModeDescriptor provides information on a signing flow of the application +/// NOTE(fdymylja): here we could go as far as providing an entire flow on how +/// to sign a message given a SigningModeDescriptor, but it's better to think about +/// this another time +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SigningModeDescriptor { + /// name defines the unique name of the signing mode + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + /// number is the unique int32 identifier for the sign_mode enum + #[prost(int32, tag = "2")] + pub number: i32, + /// authn_info_provider_method_fullname defines the fullname of the method to call to get + /// the metadata required to authenticate using the provided sign_modes + #[prost(string, tag = "3")] + pub authn_info_provider_method_fullname: ::prost::alloc::string::String, +} +/// ChainDescriptor describes chain information of the application +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ChainDescriptor { + /// id is the chain id + #[prost(string, tag = "1")] + pub id: ::prost::alloc::string::String, +} +/// CodecDescriptor describes the registered interfaces and provides metadata information on the types +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CodecDescriptor { + /// interfaces is a list of the registerted interfaces descriptors + #[prost(message, repeated, tag = "1")] + pub interfaces: ::prost::alloc::vec::Vec, +} +/// InterfaceDescriptor describes the implementation of an interface +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct InterfaceDescriptor { + /// fullname is the name of the interface + #[prost(string, tag = "1")] + pub fullname: ::prost::alloc::string::String, + /// interface_accepting_messages contains information regarding the proto messages which contain the interface as + /// google.protobuf.Any field + #[prost(message, repeated, tag = "2")] + pub interface_accepting_messages: ::prost::alloc::vec::Vec, + /// interface_implementers is a list of the descriptors of the interface implementers + #[prost(message, repeated, tag = "3")] + pub interface_implementers: ::prost::alloc::vec::Vec, +} +/// InterfaceImplementerDescriptor describes an interface implementer +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct InterfaceImplementerDescriptor { + /// fullname is the protobuf queryable name of the interface implementer + #[prost(string, tag = "1")] + pub fullname: ::prost::alloc::string::String, + /// type_url defines the type URL used when marshalling the type as any + /// this is required so we can provide type safe google.protobuf.Any marshalling and + /// unmarshalling, making sure that we don't accept just 'any' type + /// in our interface fields + #[prost(string, tag = "2")] + pub type_url: ::prost::alloc::string::String, +} +/// InterfaceAcceptingMessageDescriptor describes a protobuf message which contains +/// an interface represented as a google.protobuf.Any +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct InterfaceAcceptingMessageDescriptor { + /// fullname is the protobuf fullname of the type containing the interface + #[prost(string, tag = "1")] + pub fullname: ::prost::alloc::string::String, + /// field_descriptor_names is a list of the protobuf name (not fullname) of the field + /// which contains the interface as google.protobuf.Any (the interface is the same, but + /// it can be in multiple fields of the same proto message) + #[prost(string, repeated, tag = "2")] + pub field_descriptor_names: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +/// ConfigurationDescriptor contains metadata information on the sdk.Config +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ConfigurationDescriptor { + /// bech32_account_address_prefix is the account address prefix + #[prost(string, tag = "1")] + pub bech32_account_address_prefix: ::prost::alloc::string::String, +} +/// MsgDescriptor describes a cosmos-sdk message that can be delivered with a transaction +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MsgDescriptor { + /// msg_type_url contains the TypeURL of a sdk.Msg. + #[prost(string, tag = "1")] + pub msg_type_url: ::prost::alloc::string::String, +} +/// GetAuthnDescriptorRequest is the request used for the GetAuthnDescriptor RPC +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetAuthnDescriptorRequest {} +/// GetAuthnDescriptorResponse is the response returned by the GetAuthnDescriptor RPC +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetAuthnDescriptorResponse { + /// authn describes how to authenticate to the application when sending transactions + #[prost(message, optional, tag = "1")] + pub authn: ::core::option::Option, +} +/// GetChainDescriptorRequest is the request used for the GetChainDescriptor RPC +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetChainDescriptorRequest {} +/// GetChainDescriptorResponse is the response returned by the GetChainDescriptor RPC +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetChainDescriptorResponse { + /// chain describes application chain information + #[prost(message, optional, tag = "1")] + pub chain: ::core::option::Option, +} +/// GetCodecDescriptorRequest is the request used for the GetCodecDescriptor RPC +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetCodecDescriptorRequest {} +/// GetCodecDescriptorResponse is the response returned by the GetCodecDescriptor RPC +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetCodecDescriptorResponse { + /// codec describes the application codec such as registered interfaces and implementations + #[prost(message, optional, tag = "1")] + pub codec: ::core::option::Option, +} +/// GetConfigurationDescriptorRequest is the request used for the GetConfigurationDescriptor RPC +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetConfigurationDescriptorRequest {} +/// GetConfigurationDescriptorResponse is the response returned by the GetConfigurationDescriptor RPC +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetConfigurationDescriptorResponse { + /// config describes the application's sdk.Config + #[prost(message, optional, tag = "1")] + pub config: ::core::option::Option, +} +/// GetQueryServicesDescriptorRequest is the request used for the GetQueryServicesDescriptor RPC +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetQueryServicesDescriptorRequest {} +/// GetQueryServicesDescriptorResponse is the response returned by the GetQueryServicesDescriptor RPC +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetQueryServicesDescriptorResponse { + /// queries provides information on the available queryable services + #[prost(message, optional, tag = "1")] + pub queries: ::core::option::Option, +} +/// GetTxDescriptorRequest is the request used for the GetTxDescriptor RPC +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetTxDescriptorRequest {} +/// GetTxDescriptorResponse is the response returned by the GetTxDescriptor RPC +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetTxDescriptorResponse { + /// tx provides information on msgs that can be forwarded to the application + /// alongside the accepted transaction protobuf type + #[prost(message, optional, tag = "1")] + pub tx: ::core::option::Option, +} +/// QueryServicesDescriptor contains the list of cosmos-sdk queriable services +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryServicesDescriptor { + /// query_services is a list of cosmos-sdk QueryServiceDescriptor + #[prost(message, repeated, tag = "1")] + pub query_services: ::prost::alloc::vec::Vec, +} +/// QueryServiceDescriptor describes a cosmos-sdk queryable service +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryServiceDescriptor { + /// fullname is the protobuf fullname of the service descriptor + #[prost(string, tag = "1")] + pub fullname: ::prost::alloc::string::String, + /// is_module describes if this service is actually exposed by an application's module + #[prost(bool, tag = "2")] + pub is_module: bool, + /// methods provides a list of query service methods + #[prost(message, repeated, tag = "3")] + pub methods: ::prost::alloc::vec::Vec, +} +/// QueryMethodDescriptor describes a queryable method of a query service +/// no other info is provided beside method name and tendermint queryable path +/// because it would be redundant with the grpc reflection service +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryMethodDescriptor { + /// name is the protobuf name (not fullname) of the method + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + /// full_query_path is the path that can be used to query + /// this method via tendermint abci.Query + #[prost(string, tag = "2")] + pub full_query_path: ::prost::alloc::string::String, +} +#[doc = r" Generated client implementations."] +pub mod reflection_service_client { + #![allow(unused_variables, dead_code, missing_docs)] + use tonic::codegen::*; + #[doc = " ReflectionService defines a service for application reflection."] + pub struct ReflectionServiceClient { + inner: tonic::client::Grpc, + } + impl ReflectionServiceClient { + #[doc = r" Attempt to create a new client by connecting to a given endpoint."] + pub async fn connect(dst: D) -> Result + where + D: std::convert::TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl ReflectionServiceClient + where + T: tonic::client::GrpcService, + T::ResponseBody: Body + HttpBody + Send + 'static, + T::Error: Into, + ::Error: Into + Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_interceptor(inner: T, interceptor: impl Into) -> Self { + let inner = tonic::client::Grpc::with_interceptor(inner, interceptor); + Self { inner } + } + #[doc = " GetAuthnDescriptor returns information on how to authenticate transactions in the application"] + #[doc = " NOTE: this RPC is still experimental and might be subject to breaking changes or removal in"] + #[doc = " future releases of the cosmos-sdk."] + pub async fn get_authn_descriptor( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.base.reflection.v2alpha1.ReflectionService/GetAuthnDescriptor", + ); + self.inner.unary(request.into_request(), path, codec).await + } + #[doc = " GetChainDescriptor returns the description of the chain"] + pub async fn get_chain_descriptor( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.base.reflection.v2alpha1.ReflectionService/GetChainDescriptor", + ); + self.inner.unary(request.into_request(), path, codec).await + } + #[doc = " GetCodecDescriptor returns the descriptor of the codec of the application"] + pub async fn get_codec_descriptor( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.base.reflection.v2alpha1.ReflectionService/GetCodecDescriptor", + ); + self.inner.unary(request.into_request(), path, codec).await + } + #[doc = " GetConfigurationDescriptor returns the descriptor for the sdk.Config of the application"] + pub async fn get_configuration_descriptor( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> + { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.base.reflection.v2alpha1.ReflectionService/GetConfigurationDescriptor", + ); + self.inner.unary(request.into_request(), path, codec).await + } + #[doc = " GetQueryServicesDescriptor returns the available gRPC queryable services of the application"] + pub async fn get_query_services_descriptor( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> + { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.base.reflection.v2alpha1.ReflectionService/GetQueryServicesDescriptor", + ); + self.inner.unary(request.into_request(), path, codec).await + } + #[doc = " GetTxDescriptor returns information on the used transaction object and available msgs that can be used"] + pub async fn get_tx_descriptor( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.base.reflection.v2alpha1.ReflectionService/GetTxDescriptor", + ); + self.inner.unary(request.into_request(), path, codec).await + } + } + impl Clone for ReflectionServiceClient { + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + } + } + } + impl std::fmt::Debug for ReflectionServiceClient { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "ReflectionServiceClient {{ ... }}") + } + } +} diff --git a/proto/src/prost/cosmos.base.store.v1beta1.rs b/proto/src/prost/cosmos.base.store.v1beta1.rs index 58f7c5c1d3..8407d7ede4 100644 --- a/proto/src/prost/cosmos.base.store.v1beta1.rs +++ b/proto/src/prost/cosmos.base.store.v1beta1.rs @@ -61,3 +61,19 @@ pub struct CommitId { #[prost(bytes = "vec", tag = "2")] pub hash: ::prost::alloc::vec::Vec, } +/// StoreKVPair is a KVStore KVPair used for listening to state changes (Sets and Deletes) +/// It optionally includes the StoreKey for the originating KVStore and a Boolean flag to distinguish between Sets and +/// Deletes +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StoreKvPair { + /// the store key for the KVStore this pair originates from + #[prost(string, tag = "1")] + pub store_key: ::prost::alloc::string::String, + /// true indicates a delete operation, false indicates a set operation + #[prost(bool, tag = "2")] + pub delete: bool, + #[prost(bytes = "vec", tag = "3")] + pub key: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "4")] + pub value: ::prost::alloc::vec::Vec, +} diff --git a/proto/src/prost/cosmos.base.tendermint.v1beta1.rs b/proto/src/prost/cosmos.base.tendermint.v1beta1.rs index 2a14494dda..2d0cf3aab7 100644 --- a/proto/src/prost/cosmos.base.tendermint.v1beta1.rs +++ b/proto/src/prost/cosmos.base.tendermint.v1beta1.rs @@ -110,6 +110,8 @@ pub struct VersionInfo { pub go_version: ::prost::alloc::string::String, #[prost(message, repeated, tag = "7")] pub build_deps: ::prost::alloc::vec::Vec, + #[prost(string, tag = "8")] + pub cosmos_sdk_version: ::prost::alloc::string::String, } /// Module is the type for VersionInfo #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/proto/src/prost/cosmos.gov.v1beta1.rs b/proto/src/prost/cosmos.gov.v1beta1.rs index fc092bcfe0..0d72036027 100644 --- a/proto/src/prost/cosmos.gov.v1beta1.rs +++ b/proto/src/prost/cosmos.gov.v1beta1.rs @@ -1,3 +1,11 @@ +/// WeightedVoteOption defines a unit of vote for vote split. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct WeightedVoteOption { + #[prost(enumeration = "VoteOption", tag = "1")] + pub option: i32, + #[prost(string, tag = "2")] + pub weight: ::prost::alloc::string::String, +} /// TextProposal defines a standard text proposal whose changes need to be /// manually updated in case of approval. #[derive(Clone, PartialEq, ::prost::Message)] @@ -60,8 +68,14 @@ pub struct Vote { pub proposal_id: u64, #[prost(string, tag = "2")] pub voter: ::prost::alloc::string::String, + /// Deprecated: Prefer to use `options` instead. This field is set in queries + /// if and only if `len(options) == 1` and that option has weight 1. In all + /// other cases, this field will default to VOTE_OPTION_UNSPECIFIED. + #[deprecated] #[prost(enumeration = "VoteOption", tag = "3")] pub option: i32, + #[prost(message, repeated, tag = "4")] + pub options: ::prost::alloc::vec::Vec, } /// DepositParams defines the params for deposits on governance proposals. #[derive(Clone, PartialEq, ::prost::Message)] @@ -133,31 +147,6 @@ pub enum ProposalStatus { /// failed. Failed = 5, } -/// GenesisState defines the gov module's genesis state. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct GenesisState { - /// starting_proposal_id is the ID of the starting proposal. - #[prost(uint64, tag = "1")] - pub starting_proposal_id: u64, - /// deposits defines all the deposits present at genesis. - #[prost(message, repeated, tag = "2")] - pub deposits: ::prost::alloc::vec::Vec, - /// votes defines all the votes present at genesis. - #[prost(message, repeated, tag = "3")] - pub votes: ::prost::alloc::vec::Vec, - /// proposals defines all the proposals present at genesis. - #[prost(message, repeated, tag = "4")] - pub proposals: ::prost::alloc::vec::Vec, - /// params defines all the paramaters of related to deposit. - #[prost(message, optional, tag = "5")] - pub deposit_params: ::core::option::Option, - /// params defines all the paramaters of related to voting. - #[prost(message, optional, tag = "6")] - pub voting_params: ::core::option::Option, - /// params defines all the paramaters of related to tally. - #[prost(message, optional, tag = "7")] - pub tally_params: ::core::option::Option, -} /// QueryProposalRequest is the request type for the Query/Proposal RPC method. #[derive(Clone, PartialEq, ::prost::Message)] pub struct QueryProposalRequest { @@ -504,6 +493,19 @@ pub struct MsgVote { /// MsgVoteResponse defines the Msg/Vote response type. #[derive(Clone, PartialEq, ::prost::Message)] pub struct MsgVoteResponse {} +/// MsgVoteWeighted defines a message to cast a vote. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MsgVoteWeighted { + #[prost(uint64, tag = "1")] + pub proposal_id: u64, + #[prost(string, tag = "2")] + pub voter: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "3")] + pub options: ::prost::alloc::vec::Vec, +} +/// MsgVoteWeightedResponse defines the Msg/VoteWeighted response type. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MsgVoteWeightedResponse {} /// MsgDeposit defines a message to submit a deposit to an existing proposal. #[derive(Clone, PartialEq, ::prost::Message)] pub struct MsgDeposit { @@ -582,6 +584,21 @@ pub mod msg_client { let path = http::uri::PathAndQuery::from_static("/cosmos.gov.v1beta1.Msg/Vote"); self.inner.unary(request.into_request(), path, codec).await } + #[doc = " VoteWeighted defines a method to add a weighted vote on a specific proposal."] + pub async fn vote_weighted( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/cosmos.gov.v1beta1.Msg/VoteWeighted"); + self.inner.unary(request.into_request(), path, codec).await + } #[doc = " Deposit defines a method to add deposit on a specific proposal."] pub async fn deposit( &mut self, @@ -611,3 +628,28 @@ pub mod msg_client { } } } +/// GenesisState defines the gov module's genesis state. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenesisState { + /// starting_proposal_id is the ID of the starting proposal. + #[prost(uint64, tag = "1")] + pub starting_proposal_id: u64, + /// deposits defines all the deposits present at genesis. + #[prost(message, repeated, tag = "2")] + pub deposits: ::prost::alloc::vec::Vec, + /// votes defines all the votes present at genesis. + #[prost(message, repeated, tag = "3")] + pub votes: ::prost::alloc::vec::Vec, + /// proposals defines all the proposals present at genesis. + #[prost(message, repeated, tag = "4")] + pub proposals: ::prost::alloc::vec::Vec, + /// params defines all the paramaters of related to deposit. + #[prost(message, optional, tag = "5")] + pub deposit_params: ::core::option::Option, + /// params defines all the paramaters of related to voting. + #[prost(message, optional, tag = "6")] + pub voting_params: ::core::option::Option, + /// params defines all the paramaters of related to tally. + #[prost(message, optional, tag = "7")] + pub tally_params: ::core::option::Option, +} diff --git a/proto/src/prost/cosmos.staking.v1beta1.rs b/proto/src/prost/cosmos.staking.v1beta1.rs index 3483140f49..e69bf80c29 100644 --- a/proto/src/prost/cosmos.staking.v1beta1.rs +++ b/proto/src/prost/cosmos.staking.v1beta1.rs @@ -289,45 +289,6 @@ pub enum BondStatus { /// BONDED defines a validator that is bonded. Bonded = 3, } -/// GenesisState defines the staking module's genesis state. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct GenesisState { - /// params defines all the paramaters of related to deposit. - #[prost(message, optional, tag = "1")] - pub params: ::core::option::Option, - /// last_total_power tracks the total amounts of bonded tokens recorded during - /// the previous end block. - #[prost(bytes = "vec", tag = "2")] - pub last_total_power: ::prost::alloc::vec::Vec, - /// last_validator_powers is a special index that provides a historical list - /// of the last-block's bonded validators. - #[prost(message, repeated, tag = "3")] - pub last_validator_powers: ::prost::alloc::vec::Vec, - /// delegations defines the validator set at genesis. - #[prost(message, repeated, tag = "4")] - pub validators: ::prost::alloc::vec::Vec, - /// delegations defines the delegations active at genesis. - #[prost(message, repeated, tag = "5")] - pub delegations: ::prost::alloc::vec::Vec, - /// unbonding_delegations defines the unbonding delegations active at genesis. - #[prost(message, repeated, tag = "6")] - pub unbonding_delegations: ::prost::alloc::vec::Vec, - /// redelegations defines the redelegations active at genesis. - #[prost(message, repeated, tag = "7")] - pub redelegations: ::prost::alloc::vec::Vec, - #[prost(bool, tag = "8")] - pub exported: bool, -} -/// LastValidatorPower required for validator set update logic. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct LastValidatorPower { - /// address is the address of the validator. - #[prost(string, tag = "1")] - pub address: ::prost::alloc::string::String, - /// power defines the power of the validator. - #[prost(int64, tag = "2")] - pub power: i64, -} /// QueryValidatorsRequest is request type for Query/Validators RPC method. #[derive(Clone, PartialEq, ::prost::Message)] pub struct QueryValidatorsRequest { @@ -876,6 +837,53 @@ pub mod query_client { } } } +/// StakeAuthorization defines authorization for delegate/undelegate/redelegate. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StakeAuthorization { + /// max_tokens specifies the maximum amount of tokens can be delegate to a validator. If it is + /// empty, there is no spend limit and any amount of coins can be delegated. + #[prost(message, optional, tag = "1")] + pub max_tokens: ::core::option::Option, + /// authorization_type defines one of AuthorizationType. + #[prost(enumeration = "AuthorizationType", tag = "4")] + pub authorization_type: i32, + /// validators is the oneof that represents either allow_list or deny_list + #[prost(oneof = "stake_authorization::Validators", tags = "2, 3")] + pub validators: ::core::option::Option, +} +/// Nested message and enum types in `StakeAuthorization`. +pub mod stake_authorization { + /// Validators defines list of validator addresses. + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct ValidatorsVec { + #[prost(string, repeated, tag = "1")] + pub address: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + } + /// validators is the oneof that represents either allow_list or deny_list + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Validators { + /// allow_list specifies list of validator addresses to whom grantee can delegate tokens on behalf of granter's + /// account. + #[prost(message, tag = "2")] + AllowList(ValidatorsVec), + /// deny_list specifies list of validator addresses to whom grantee can not delegate tokens. + #[prost(message, tag = "3")] + DenyList(ValidatorsVec), + } +} +/// AuthorizationType defines the type of staking module authorization type +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum AuthorizationType { + /// AUTHORIZATION_TYPE_UNSPECIFIED specifies an unknown authorization type + Unspecified = 0, + /// AUTHORIZATION_TYPE_DELEGATE defines an authorization type for Msg/Delegate + Delegate = 1, + /// AUTHORIZATION_TYPE_UNDELEGATE defines an authorization type for Msg/Undelegate + Undelegate = 2, + /// AUTHORIZATION_TYPE_REDELEGATE defines an authorization type for Msg/BeginRedelegate + Redelegate = 3, +} /// MsgCreateValidator defines a SDK message for creating a new validator. #[derive(Clone, PartialEq, ::prost::Message)] pub struct MsgCreateValidator { @@ -1096,3 +1104,42 @@ pub mod msg_client { } } } +/// GenesisState defines the staking module's genesis state. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenesisState { + /// params defines all the paramaters of related to deposit. + #[prost(message, optional, tag = "1")] + pub params: ::core::option::Option, + /// last_total_power tracks the total amounts of bonded tokens recorded during + /// the previous end block. + #[prost(bytes = "vec", tag = "2")] + pub last_total_power: ::prost::alloc::vec::Vec, + /// last_validator_powers is a special index that provides a historical list + /// of the last-block's bonded validators. + #[prost(message, repeated, tag = "3")] + pub last_validator_powers: ::prost::alloc::vec::Vec, + /// delegations defines the validator set at genesis. + #[prost(message, repeated, tag = "4")] + pub validators: ::prost::alloc::vec::Vec, + /// delegations defines the delegations active at genesis. + #[prost(message, repeated, tag = "5")] + pub delegations: ::prost::alloc::vec::Vec, + /// unbonding_delegations defines the unbonding delegations active at genesis. + #[prost(message, repeated, tag = "6")] + pub unbonding_delegations: ::prost::alloc::vec::Vec, + /// redelegations defines the redelegations active at genesis. + #[prost(message, repeated, tag = "7")] + pub redelegations: ::prost::alloc::vec::Vec, + #[prost(bool, tag = "8")] + pub exported: bool, +} +/// LastValidatorPower required for validator set update logic. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct LastValidatorPower { + /// address is the address of the validator. + #[prost(string, tag = "1")] + pub address: ::prost::alloc::string::String, + /// power defines the power of the validator. + #[prost(int64, tag = "2")] + pub power: i64, +} diff --git a/proto/src/prost/cosmos.tx.v1beta1.rs b/proto/src/prost/cosmos.tx.v1beta1.rs index db69dc04b9..2b89c3f08e 100644 --- a/proto/src/prost/cosmos.tx.v1beta1.rs +++ b/proto/src/prost/cosmos.tx.v1beta1.rs @@ -67,7 +67,9 @@ pub struct TxBody { /// transaction. #[prost(message, repeated, tag = "1")] pub messages: ::prost::alloc::vec::Vec<::prost_types::Any>, - /// memo is any arbitrary memo to be added to the transaction + /// memo is any arbitrary note/comment to be added to the transaction. + /// WARNING: in clients, any publicly exposed text should not be called memo, + /// but should be called `note` instead (see https://github.com/cosmos/cosmos-sdk/issues/9122). #[prost(string, tag = "2")] pub memo: ::prost::alloc::string::String, /// timeout is the block height after which this transaction will not @@ -237,8 +239,13 @@ pub struct BroadcastTxResponse { #[derive(Clone, PartialEq, ::prost::Message)] pub struct SimulateRequest { /// tx is the transaction to simulate. + /// Deprecated. Send raw tx bytes instead. + #[deprecated] #[prost(message, optional, tag = "1")] pub tx: ::core::option::Option, + /// tx_bytes is the raw transaction. + #[prost(bytes = "vec", tag = "2")] + pub tx_bytes: ::prost::alloc::vec::Vec, } /// SimulateResponse is the response type for the /// Service.SimulateRPC method. diff --git a/proto/src/prost/cosmos.upgrade.v1beta1.rs b/proto/src/prost/cosmos.upgrade.v1beta1.rs index 57b44062ff..b10e2b6f82 100644 --- a/proto/src/prost/cosmos.upgrade.v1beta1.rs +++ b/proto/src/prost/cosmos.upgrade.v1beta1.rs @@ -10,8 +10,10 @@ pub struct Plan { /// reached and the software will exit. #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, - /// The time after which the upgrade must be performed. - /// Leave set to its zero value to use a pre-defined Height instead. + /// Deprecated: Time based upgrades have been deprecated. Time based upgrade logic + /// has been removed from the SDK. + /// If this field is not empty, an error will be thrown. + #[deprecated] #[prost(message, optional, tag = "2")] pub time: ::core::option::Option<::prost_types::Timestamp>, /// The height at which the upgrade must be performed. @@ -22,11 +24,10 @@ pub struct Plan { /// such as a git commit that validators could automatically upgrade to #[prost(string, tag = "4")] pub info: ::prost::alloc::string::String, - /// IBC-enabled chains can opt-in to including the upgraded client state in its upgrade plan - /// This will make the chain commit to the correct upgraded (self) client state before the upgrade occurs, - /// so that connecting chains can verify that the new upgraded client is valid by verifying a proof on the - /// previous version of the chain. - /// This will allow IBC connections to persist smoothly across planned chain upgrades + /// Deprecated: UpgradedClientState field has been deprecated. IBC upgrade logic has been + /// moved to the IBC module in the sub module 02-client. + /// If this field is not empty, an error will be thrown. + #[deprecated] #[prost(message, optional, tag = "5")] pub upgraded_client_state: ::core::option::Option<::prost_types::Any>, } @@ -50,6 +51,16 @@ pub struct CancelSoftwareUpgradeProposal { #[prost(string, tag = "2")] pub description: ::prost::alloc::string::String, } +/// ModuleVersion specifies a module and its consensus version. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ModuleVersion { + /// name of the app module + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + /// consensus version of the app module + #[prost(uint64, tag = "2")] + pub version: u64, +} /// QueryCurrentPlanRequest is the request type for the Query/CurrentPlan RPC /// method. #[derive(Clone, PartialEq, ::prost::Message)] @@ -91,8 +102,26 @@ pub struct QueryUpgradedConsensusStateRequest { /// RPC method. #[derive(Clone, PartialEq, ::prost::Message)] pub struct QueryUpgradedConsensusStateResponse { - #[prost(message, optional, tag = "1")] - pub upgraded_consensus_state: ::core::option::Option<::prost_types::Any>, + #[prost(bytes = "vec", tag = "2")] + pub upgraded_consensus_state: ::prost::alloc::vec::Vec, +} +/// QueryModuleVersionsRequest is the request type for the Query/ModuleVersions +/// RPC method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryModuleVersionsRequest { + /// module_name is a field to query a specific module + /// consensus version from state. Leaving this empty will + /// fetch the full list of module versions from state + #[prost(string, tag = "1")] + pub module_name: ::prost::alloc::string::String, +} +/// QueryModuleVersionsResponse is the response type for the Query/ModuleVersions +/// RPC method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryModuleVersionsResponse { + /// module_versions is a list of module names with their consensus versions. + #[prost(message, repeated, tag = "1")] + pub module_versions: ::prost::alloc::vec::Vec, } #[doc = r" Generated client implementations."] pub mod query_client { @@ -181,6 +210,23 @@ pub mod query_client { ); self.inner.unary(request.into_request(), path, codec).await } + #[doc = " ModuleVersions queries the list of module versions from state."] + pub async fn module_versions( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.upgrade.v1beta1.Query/ModuleVersions", + ); + self.inner.unary(request.into_request(), path, codec).await + } } impl Clone for QueryClient { fn clone(&self) -> Self { diff --git a/proto/src/prost/ibc.applications.transfer.v1.rs b/proto/src/prost/ibc.applications.transfer.v1.rs index 5dec6feebf..af506906de 100644 --- a/proto/src/prost/ibc.applications.transfer.v1.rs +++ b/proto/src/prost/ibc.applications.transfer.v1.rs @@ -43,16 +43,6 @@ pub struct Params { #[prost(bool, tag = "2")] pub receive_enabled: bool, } -/// GenesisState defines the ibc-transfer genesis state -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct GenesisState { - #[prost(string, tag = "1")] - pub port_id: ::prost::alloc::string::String, - #[prost(message, repeated, tag = "2")] - pub denom_traces: ::prost::alloc::vec::Vec, - #[prost(message, optional, tag = "3")] - pub params: ::core::option::Option, -} /// QueryDenomTraceRequest is the request type for the Query/DenomTrace RPC /// method #[derive(Clone, PartialEq, ::prost::Message)] @@ -296,3 +286,13 @@ pub mod msg_client { } } } +/// GenesisState defines the ibc-transfer genesis state +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenesisState { + #[prost(string, tag = "1")] + pub port_id: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "2")] + pub denom_traces: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "3")] + pub params: ::core::option::Option, +} diff --git a/proto/src/prost/ibc.core.channel.v1.rs b/proto/src/prost/ibc.core.channel.v1.rs index 75c4747064..6da3fcc088 100644 --- a/proto/src/prost/ibc.core.channel.v1.rs +++ b/proto/src/prost/ibc.core.channel.v1.rs @@ -160,38 +160,6 @@ pub enum Order { /// packets are delivered exactly in the order which they were sent Ordered = 2, } -/// GenesisState defines the ibc channel submodule's genesis state. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct GenesisState { - #[prost(message, repeated, tag = "1")] - pub channels: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag = "2")] - pub acknowledgements: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag = "3")] - pub commitments: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag = "4")] - pub receipts: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag = "5")] - pub send_sequences: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag = "6")] - pub recv_sequences: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag = "7")] - pub ack_sequences: ::prost::alloc::vec::Vec, - /// the sequence for the next generated channel identifier - #[prost(uint64, tag = "8")] - pub next_channel_sequence: u64, -} -/// PacketSequence defines the genesis type necessary to retrieve and store -/// next send and receive sequences. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct PacketSequence { - #[prost(string, tag = "1")] - pub port_id: ::prost::alloc::string::String, - #[prost(string, tag = "2")] - pub channel_id: ::prost::alloc::string::String, - #[prost(uint64, tag = "3")] - pub sequence: u64, -} /// QueryChannelRequest is the request type for the Query/Channel RPC method #[derive(Clone, PartialEq, ::prost::Message)] pub struct QueryChannelRequest { @@ -404,8 +372,8 @@ pub struct QueryPacketReceiptRequest { #[prost(uint64, tag = "3")] pub sequence: u64, } -/// QueryPacketReceiptResponse defines the client query response for a packet receipt -/// which also includes a proof, and the height from which the proof was +/// QueryPacketReceiptResponse defines the client query response for a packet +/// receipt which also includes a proof, and the height from which the proof was /// retrieved #[derive(Clone, PartialEq, ::prost::Message)] pub struct QueryPacketReceiptResponse { @@ -709,7 +677,8 @@ pub mod query_client { ); self.inner.unary(request.into_request(), path, codec).await } - #[doc = " PacketReceipt queries if a given packet sequence has been received on the queried chain"] + #[doc = " PacketReceipt queries if a given packet sequence has been received on the"] + #[doc = " queried chain"] pub async fn packet_receipt( &mut self, request: impl tonic::IntoRequest, @@ -780,8 +749,8 @@ pub mod query_client { ); self.inner.unary(request.into_request(), path, codec).await } - #[doc = " UnreceivedAcks returns all the unreceived IBC acknowledgements associated with a"] - #[doc = " channel and sequences."] + #[doc = " UnreceivedAcks returns all the unreceived IBC acknowledgements associated"] + #[doc = " with a channel and sequences."] pub async fn unreceived_acks( &mut self, request: impl tonic::IntoRequest, @@ -849,8 +818,8 @@ pub struct MsgChannelOpenInitResponse {} pub struct MsgChannelOpenTry { #[prost(string, tag = "1")] pub port_id: ::prost::alloc::string::String, - /// in the case of crossing hello's, when both chains call OpenInit, we need the channel identifier - /// of the previous channel in state INIT + /// in the case of crossing hello's, when both chains call OpenInit, we need + /// the channel identifier of the previous channel in state INIT #[prost(string, tag = "2")] pub previous_channel_id: ::prost::alloc::string::String, #[prost(message, optional, tag = "3")] @@ -904,7 +873,8 @@ pub struct MsgChannelOpenConfirm { #[prost(string, tag = "5")] pub signer: ::prost::alloc::string::String, } -/// MsgChannelOpenConfirmResponse defines the Msg/ChannelOpenConfirm response type. +/// MsgChannelOpenConfirmResponse defines the Msg/ChannelOpenConfirm response +/// type. #[derive(Clone, PartialEq, ::prost::Message)] pub struct MsgChannelOpenConfirmResponse {} /// MsgChannelCloseInit defines a msg sent by a Relayer to Chain A @@ -936,7 +906,8 @@ pub struct MsgChannelCloseConfirm { #[prost(string, tag = "5")] pub signer: ::prost::alloc::string::String, } -/// MsgChannelCloseConfirmResponse defines the Msg/ChannelCloseConfirm response type. +/// MsgChannelCloseConfirmResponse defines the Msg/ChannelCloseConfirm response +/// type. #[derive(Clone, PartialEq, ::prost::Message)] pub struct MsgChannelCloseConfirmResponse {} /// MsgRecvPacket receives incoming IBC packet @@ -1121,7 +1092,8 @@ pub mod msg_client { http::uri::PathAndQuery::from_static("/ibc.core.channel.v1.Msg/ChannelCloseInit"); self.inner.unary(request.into_request(), path, codec).await } - #[doc = " ChannelCloseConfirm defines a rpc handler method for MsgChannelCloseConfirm."] + #[doc = " ChannelCloseConfirm defines a rpc handler method for"] + #[doc = " MsgChannelCloseConfirm."] pub async fn channel_close_confirm( &mut self, request: impl tonic::IntoRequest, @@ -1214,3 +1186,35 @@ pub mod msg_client { } } } +/// GenesisState defines the ibc channel submodule's genesis state. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenesisState { + #[prost(message, repeated, tag = "1")] + pub channels: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "2")] + pub acknowledgements: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "3")] + pub commitments: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "4")] + pub receipts: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "5")] + pub send_sequences: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "6")] + pub recv_sequences: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "7")] + pub ack_sequences: ::prost::alloc::vec::Vec, + /// the sequence for the next generated channel identifier + #[prost(uint64, tag = "8")] + pub next_channel_sequence: u64, +} +/// PacketSequence defines the genesis type necessary to retrieve and store +/// next send and receive sequences. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PacketSequence { + #[prost(string, tag = "1")] + pub port_id: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub channel_id: ::prost::alloc::string::String, + #[prost(uint64, tag = "3")] + pub sequence: u64, +} diff --git a/proto/src/prost/ibc.core.client.v1.rs b/proto/src/prost/ibc.core.client.v1.rs index d150ad20b8..f963aa6793 100644 --- a/proto/src/prost/ibc.core.client.v1.rs +++ b/proto/src/prost/ibc.core.client.v1.rs @@ -9,7 +9,8 @@ pub struct IdentifiedClientState { #[prost(message, optional, tag = "2")] pub client_state: ::core::option::Option<::prost_types::Any>, } -/// ConsensusStateWithHeight defines a consensus state with an additional height field. +/// ConsensusStateWithHeight defines a consensus state with an additional height +/// field. #[derive(Clone, PartialEq, ::prost::Message)] pub struct ConsensusStateWithHeight { /// consensus state height @@ -30,9 +31,10 @@ pub struct ClientConsensusStates { #[prost(message, repeated, tag = "2")] pub consensus_states: ::prost::alloc::vec::Vec, } -/// ClientUpdateProposal is a governance proposal. If it passes, the client is -/// updated with the provided header. The update may fail if the header is not -/// valid given certain conditions specified by the client implementation. +/// ClientUpdateProposal is a governance proposal. If it passes, the substitute +/// client's latest consensus state is copied over to the subject client. The proposal +/// handler may fail if the subject and the substitute do not match in client and +/// chain parameters (with exception to latest height, frozen height, and chain-id). #[derive(Clone, PartialEq, ::prost::Message)] pub struct ClientUpdateProposal { /// the title of the update proposal @@ -43,20 +45,41 @@ pub struct ClientUpdateProposal { pub description: ::prost::alloc::string::String, /// the client identifier for the client to be updated if the proposal passes #[prost(string, tag = "3")] - pub client_id: ::prost::alloc::string::String, - /// the header used to update the client if the proposal passes + pub subject_client_id: ::prost::alloc::string::String, + /// the substitute client identifier for the client standing in for the subject + /// client + #[prost(string, tag = "4")] + pub substitute_client_id: ::prost::alloc::string::String, +} +/// UpgradeProposal is a gov Content type for initiating an IBC breaking +/// upgrade. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UpgradeProposal { + #[prost(string, tag = "1")] + pub title: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub description: ::prost::alloc::string::String, + #[prost(message, optional, tag = "3")] + pub plan: ::core::option::Option, + /// An UpgradedClientState must be provided to perform an IBC breaking upgrade. + /// This will make the chain commit to the correct upgraded (self) client state + /// before the upgrade occurs, so that connecting chains can verify that the + /// new upgraded client is valid by verifying a proof on the previous version + /// of the chain. This will allow IBC connections to persist smoothly across + /// planned chain upgrades #[prost(message, optional, tag = "4")] - pub header: ::core::option::Option<::prost_types::Any>, + pub upgraded_client_state: ::core::option::Option<::prost_types::Any>, } /// Height is a monotonically increasing data type /// that can be compared against another Height for the purposes of updating and /// freezing clients /// -/// Normally the RevisionHeight is incremented at each height while keeping RevisionNumber -/// the same. However some consensus algorithms may choose to reset the -/// height in certain conditions e.g. hard forks, state-machine breaking changes -/// In these cases, the RevisionNumber is incremented so that height continues to -/// be monitonically increasing even as the RevisionHeight gets reset +/// Normally the RevisionHeight is incremented at each height while keeping +/// RevisionNumber the same. However some consensus algorithms may choose to +/// reset the height in certain conditions e.g. hard forks, state-machine +/// breaking changes In these cases, the RevisionNumber is incremented so that +/// height continues to be monitonically increasing even as the RevisionHeight +/// gets reset #[derive(Clone, PartialEq, ::prost::Message)] pub struct Height { /// the revision that the client is currently on @@ -73,46 +96,6 @@ pub struct Params { #[prost(string, repeated, tag = "1")] pub allowed_clients: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } -/// GenesisState defines the ibc client submodule's genesis state. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct GenesisState { - /// client states with their corresponding identifiers - #[prost(message, repeated, tag = "1")] - pub clients: ::prost::alloc::vec::Vec, - /// consensus states from each client - #[prost(message, repeated, tag = "2")] - pub clients_consensus: ::prost::alloc::vec::Vec, - /// metadata from each client - #[prost(message, repeated, tag = "3")] - pub clients_metadata: ::prost::alloc::vec::Vec, - #[prost(message, optional, tag = "4")] - pub params: ::core::option::Option, - /// create localhost on initialization - #[prost(bool, tag = "5")] - pub create_localhost: bool, - /// the sequence for the next generated client identifier - #[prost(uint64, tag = "6")] - pub next_client_sequence: u64, -} -/// GenesisMetadata defines the genesis type for metadata that clients may return -/// with ExportMetadata -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct GenesisMetadata { - /// store key of metadata without clientID-prefix - #[prost(bytes = "vec", tag = "1")] - pub key: ::prost::alloc::vec::Vec, - /// metadata value - #[prost(bytes = "vec", tag = "2")] - pub value: ::prost::alloc::vec::Vec, -} -/// IdentifiedGenesisMetadata has the client metadata with the corresponding client id. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct IdentifiedGenesisMetadata { - #[prost(string, tag = "1")] - pub client_id: ::prost::alloc::string::String, - #[prost(message, repeated, tag = "2")] - pub client_metadata: ::prost::alloc::vec::Vec, -} /// QueryClientStateRequest is the request type for the Query/ClientState RPC /// method #[derive(Clone, PartialEq, ::prost::Message)] @@ -218,16 +201,57 @@ pub struct QueryConsensusStatesResponse { super::super::super::super::cosmos::base::query::v1beta1::PageResponse, >, } -/// QueryClientParamsRequest is the request type for the Query/ClientParams RPC method. +/// QueryClientStatusRequest is the request type for the Query/ClientStatus RPC +/// method +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryClientStatusRequest { + /// client unique identifier + #[prost(string, tag = "1")] + pub client_id: ::prost::alloc::string::String, +} +/// QueryClientStatusResponse is the response type for the Query/ClientStatus RPC +/// method. It returns the current status of the IBC client. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryClientStatusResponse { + #[prost(string, tag = "1")] + pub status: ::prost::alloc::string::String, +} +/// QueryClientParamsRequest is the request type for the Query/ClientParams RPC +/// method. #[derive(Clone, PartialEq, ::prost::Message)] pub struct QueryClientParamsRequest {} -/// QueryClientParamsResponse is the response type for the Query/ClientParams RPC method. +/// QueryClientParamsResponse is the response type for the Query/ClientParams RPC +/// method. #[derive(Clone, PartialEq, ::prost::Message)] pub struct QueryClientParamsResponse { /// params defines the parameters of the module. #[prost(message, optional, tag = "1")] pub params: ::core::option::Option, } +/// QueryUpgradedClientStateRequest is the request type for the +/// Query/UpgradedClientState RPC method +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryUpgradedClientStateRequest {} +/// QueryUpgradedClientStateResponse is the response type for the +/// Query/UpgradedClientState RPC method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryUpgradedClientStateResponse { + /// client state associated with the request identifier + #[prost(message, optional, tag = "1")] + pub upgraded_client_state: ::core::option::Option<::prost_types::Any>, +} +/// QueryUpgradedConsensusStateRequest is the request type for the +/// Query/UpgradedConsensusState RPC method +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryUpgradedConsensusStateRequest {} +/// QueryUpgradedConsensusStateResponse is the response type for the +/// Query/UpgradedConsensusState RPC method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryUpgradedConsensusStateResponse { + /// Consensus state associated with the request identifier + #[prost(message, optional, tag = "1")] + pub upgraded_consensus_state: ::core::option::Option<::prost_types::Any>, +} #[doc = r" Generated client implementations."] pub mod query_client { #![allow(unused_variables, dead_code, missing_docs)] @@ -328,6 +352,22 @@ pub mod query_client { http::uri::PathAndQuery::from_static("/ibc.core.client.v1.Query/ConsensusStates"); self.inner.unary(request.into_request(), path, codec).await } + #[doc = " Status queries the status of an IBC client."] + pub async fn client_status( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = + http::uri::PathAndQuery::from_static("/ibc.core.client.v1.Query/ClientStatus"); + self.inner.unary(request.into_request(), path, codec).await + } #[doc = " ClientParams queries all parameters of the ibc client."] pub async fn client_params( &mut self, @@ -344,6 +384,42 @@ pub mod query_client { http::uri::PathAndQuery::from_static("/ibc.core.client.v1.Query/ClientParams"); self.inner.unary(request.into_request(), path, codec).await } + #[doc = " UpgradedClientState queries an Upgraded IBC light client."] + pub async fn upgraded_client_state( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> + { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/ibc.core.client.v1.Query/UpgradedClientState", + ); + self.inner.unary(request.into_request(), path, codec).await + } + #[doc = " UpgradedConsensusState queries an Upgraded IBC consensus state."] + pub async fn upgraded_consensus_state( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> + { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/ibc.core.client.v1.Query/UpgradedConsensusState", + ); + self.inner.unary(request.into_request(), path, codec).await + } } impl Clone for QueryClient { fn clone(&self) -> Self { @@ -392,7 +468,8 @@ pub struct MsgUpdateClient { /// MsgUpdateClientResponse defines the Msg/UpdateClient response type. #[derive(Clone, PartialEq, ::prost::Message)] pub struct MsgUpdateClientResponse {} -/// MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client state +/// MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client +/// state #[derive(Clone, PartialEq, ::prost::Message)] pub struct MsgUpgradeClient { /// client unique identifier @@ -401,7 +478,8 @@ pub struct MsgUpgradeClient { /// upgraded client state #[prost(message, optional, tag = "2")] pub client_state: ::core::option::Option<::prost_types::Any>, - /// upgraded consensus state, only contains enough information to serve as a basis of trust in update logic + /// upgraded consensus state, only contains enough information to serve as a + /// basis of trust in update logic #[prost(message, optional, tag = "3")] pub consensus_state: ::core::option::Option<::prost_types::Any>, /// proof that old chain committed to new client @@ -431,7 +509,8 @@ pub struct MsgSubmitMisbehaviour { #[prost(string, tag = "3")] pub signer: ::prost::alloc::string::String, } -/// MsgSubmitMisbehaviourResponse defines the Msg/SubmitMisbehaviour response type. +/// MsgSubmitMisbehaviourResponse defines the Msg/SubmitMisbehaviour response +/// type. #[derive(Clone, PartialEq, ::prost::Message)] pub struct MsgSubmitMisbehaviourResponse {} #[doc = r" Generated client implementations."] @@ -544,3 +623,44 @@ pub mod msg_client { } } } +/// GenesisState defines the ibc client submodule's genesis state. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenesisState { + /// client states with their corresponding identifiers + #[prost(message, repeated, tag = "1")] + pub clients: ::prost::alloc::vec::Vec, + /// consensus states from each client + #[prost(message, repeated, tag = "2")] + pub clients_consensus: ::prost::alloc::vec::Vec, + /// metadata from each client + #[prost(message, repeated, tag = "3")] + pub clients_metadata: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "4")] + pub params: ::core::option::Option, + /// create localhost on initialization + #[prost(bool, tag = "5")] + pub create_localhost: bool, + /// the sequence for the next generated client identifier + #[prost(uint64, tag = "6")] + pub next_client_sequence: u64, +} +/// GenesisMetadata defines the genesis type for metadata that clients may return +/// with ExportMetadata +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenesisMetadata { + /// store key of metadata without clientID-prefix + #[prost(bytes = "vec", tag = "1")] + pub key: ::prost::alloc::vec::Vec, + /// metadata value + #[prost(bytes = "vec", tag = "2")] + pub value: ::prost::alloc::vec::Vec, +} +/// IdentifiedGenesisMetadata has the client metadata with the corresponding +/// client id. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IdentifiedGenesisMetadata { + #[prost(string, tag = "1")] + pub client_id: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "2")] + pub client_metadata: ::prost::alloc::vec::Vec, +} diff --git a/proto/src/prost/ibc.core.connection.v1.rs b/proto/src/prost/ibc.core.connection.v1.rs index b2009fc392..154282ada2 100644 --- a/proto/src/prost/ibc.core.connection.v1.rs +++ b/proto/src/prost/ibc.core.connection.v1.rs @@ -20,8 +20,9 @@ pub struct ConnectionEnd { /// counterparty chain associated with this connection. #[prost(message, optional, tag = "4")] pub counterparty: ::core::option::Option, - /// delay period that must pass before a consensus state can be used for packet-verification - /// NOTE: delay period logic is only implemented by some clients. + /// delay period that must pass before a consensus state can be used for + /// packet-verification NOTE: delay period logic is only implemented by some + /// clients. #[prost(uint64, tag = "5")] pub delay_period: u64, } @@ -92,6 +93,15 @@ pub struct Version { #[prost(string, repeated, tag = "2")] pub features: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } +/// Params defines the set of Connection parameters. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Params { + /// maximum expected time per block (in nanoseconds), used to enforce block delay. This parameter should reflect the + /// largest amount of time that the chain might reasonably take to produce the next block under normal operating + /// conditions. A safe choice is 3-5x the expected time per block. + #[prost(uint64, tag = "1")] + pub max_expected_time_per_block: u64, +} /// State defines if a connection is in one of the following states: /// INIT, TRYOPEN, OPEN or UNINITIALIZED. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] @@ -107,17 +117,6 @@ pub enum State { /// A connection end has completed the handshake. Open = 3, } -/// GenesisState defines the ibc connection submodule's genesis state. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct GenesisState { - #[prost(message, repeated, tag = "1")] - pub connections: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag = "2")] - pub client_connection_paths: ::prost::alloc::vec::Vec, - /// the sequence for the next generated connection identifier - #[prost(uint64, tag = "3")] - pub next_connection_sequence: u64, -} /// QueryConnectionRequest is the request type for the Query/Connection RPC /// method #[derive(Clone, PartialEq, ::prost::Message)] @@ -391,7 +390,8 @@ pub struct MsgConnectionOpenInit { #[prost(string, tag = "5")] pub signer: ::prost::alloc::string::String, } -/// MsgConnectionOpenInitResponse defines the Msg/ConnectionOpenInit response type. +/// MsgConnectionOpenInitResponse defines the Msg/ConnectionOpenInit response +/// type. #[derive(Clone, PartialEq, ::prost::Message)] pub struct MsgConnectionOpenInitResponse {} /// MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a @@ -400,8 +400,8 @@ pub struct MsgConnectionOpenInitResponse {} pub struct MsgConnectionOpenTry { #[prost(string, tag = "1")] pub client_id: ::prost::alloc::string::String, - /// in the case of crossing hello's, when both chains call OpenInit, we need the connection identifier - /// of the previous connection in state INIT + /// in the case of crossing hello's, when both chains call OpenInit, we need + /// the connection identifier of the previous connection in state INIT #[prost(string, tag = "2")] pub previous_connection_id: ::prost::alloc::string::String, #[prost(message, optional, tag = "3")] @@ -478,7 +478,8 @@ pub struct MsgConnectionOpenConfirm { #[prost(string, tag = "4")] pub signer: ::prost::alloc::string::String, } -/// MsgConnectionOpenConfirmResponse defines the Msg/ConnectionOpenConfirm response type. +/// MsgConnectionOpenConfirmResponse defines the Msg/ConnectionOpenConfirm +/// response type. #[derive(Clone, PartialEq, ::prost::Message)] pub struct MsgConnectionOpenConfirmResponse {} #[doc = r" Generated client implementations."] @@ -566,7 +567,8 @@ pub mod msg_client { ); self.inner.unary(request.into_request(), path, codec).await } - #[doc = " ConnectionOpenConfirm defines a rpc handler method for MsgConnectionOpenConfirm."] + #[doc = " ConnectionOpenConfirm defines a rpc handler method for"] + #[doc = " MsgConnectionOpenConfirm."] pub async fn connection_open_confirm( &mut self, request: impl tonic::IntoRequest, @@ -598,3 +600,16 @@ pub mod msg_client { } } } +/// GenesisState defines the ibc connection submodule's genesis state. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenesisState { + #[prost(message, repeated, tag = "1")] + pub connections: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "2")] + pub client_connection_paths: ::prost::alloc::vec::Vec, + /// the sequence for the next generated connection identifier + #[prost(uint64, tag = "3")] + pub next_connection_sequence: u64, + #[prost(message, optional, tag = "4")] + pub params: ::core::option::Option, +} diff --git a/proto/src/prost/ibc.lightclients.solomachine.v1.rs b/proto/src/prost/ibc.lightclients.solomachine.v1.rs index 87a6618619..a88d929272 100644 --- a/proto/src/prost/ibc.lightclients.solomachine.v1.rs +++ b/proto/src/prost/ibc.lightclients.solomachine.v1.rs @@ -15,15 +15,17 @@ pub struct ClientState { #[prost(bool, tag = "4")] pub allow_update_after_proposal: bool, } -/// 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. +/// 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, ::prost::Message)] pub struct ConsensusState { /// public key of the solo machine #[prost(message, optional, tag = "1")] pub public_key: ::core::option::Option<::prost_types::Any>, - /// diversifier allows the same public key to be re-used across different solo machine clients - /// (potentially on different chains) without being considered misbehaviour. + /// diversifier allows the same public key to be re-used across different solo + /// machine clients (potentially on different chains) without being considered + /// misbehaviour. #[prost(string, tag = "2")] pub diversifier: ::prost::alloc::string::String, #[prost(uint64, tag = "3")] @@ -175,8 +177,8 @@ pub struct NextSequenceRecvData { #[prost(uint64, tag = "2")] pub next_seq_recv: u64, } -/// DataType defines the type of solo machine proof being created. This is done to preserve uniqueness of different -/// data sign byte encodings. +/// 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, ::prost::Enumeration)] #[repr(i32)] pub enum DataType { diff --git a/proto/src/prost/ibc.lightclients.solomachine.v2.rs b/proto/src/prost/ibc.lightclients.solomachine.v2.rs new file mode 100644 index 0000000000..41bccb3b6f --- /dev/null +++ b/proto/src/prost/ibc.lightclients.solomachine.v2.rs @@ -0,0 +1,205 @@ +/// ClientState defines a solo machine client that tracks the current consensus +/// state and if the client is frozen. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ClientState { + /// latest sequence of the client state + #[prost(uint64, tag = "1")] + pub sequence: u64, + /// frozen sequence of the solo machine + #[prost(bool, tag = "2")] + pub is_frozen: bool, + #[prost(message, optional, tag = "3")] + 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. + #[prost(bool, tag = "4")] + pub allow_update_after_proposal: bool, +} +/// 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, ::prost::Message)] +pub struct ConsensusState { + /// public key of the solo machine + #[prost(message, optional, tag = "1")] + pub public_key: ::core::option::Option<::prost_types::Any>, + /// diversifier allows the same public key to be re-used across different solo + /// machine clients (potentially on different chains) without being considered + /// misbehaviour. + #[prost(string, tag = "2")] + pub diversifier: ::prost::alloc::string::String, + #[prost(uint64, tag = "3")] + pub timestamp: u64, +} +/// Header defines a solo machine consensus header +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Header { + /// sequence to update solo machine public key at + #[prost(uint64, tag = "1")] + pub sequence: u64, + #[prost(uint64, tag = "2")] + pub timestamp: u64, + #[prost(bytes = "vec", tag = "3")] + pub signature: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "4")] + pub new_public_key: ::core::option::Option<::prost_types::Any>, + #[prost(string, tag = "5")] + pub new_diversifier: ::prost::alloc::string::String, +} +/// Misbehaviour defines misbehaviour for a solo machine which consists +/// of a sequence and two signatures over different messages at that sequence. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Misbehaviour { + #[prost(string, tag = "1")] + pub client_id: ::prost::alloc::string::String, + #[prost(uint64, tag = "2")] + pub sequence: u64, + #[prost(message, optional, tag = "3")] + pub signature_one: ::core::option::Option, + #[prost(message, optional, tag = "4")] + pub signature_two: ::core::option::Option, +} +/// SignatureAndData contains a signature and the data signed over to create that +/// signature. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SignatureAndData { + #[prost(bytes = "vec", tag = "1")] + pub signature: ::prost::alloc::vec::Vec, + #[prost(enumeration = "DataType", tag = "2")] + pub data_type: i32, + #[prost(bytes = "vec", tag = "3")] + pub data: ::prost::alloc::vec::Vec, + #[prost(uint64, tag = "4")] + pub timestamp: u64, +} +/// TimestampedSignatureData contains the signature data and the timestamp of the +/// signature. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TimestampedSignatureData { + #[prost(bytes = "vec", tag = "1")] + pub signature_data: ::prost::alloc::vec::Vec, + #[prost(uint64, tag = "2")] + pub timestamp: u64, +} +/// SignBytes defines the signed bytes used for signature verification. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SignBytes { + #[prost(uint64, tag = "1")] + pub sequence: u64, + #[prost(uint64, tag = "2")] + pub timestamp: u64, + #[prost(string, tag = "3")] + pub diversifier: ::prost::alloc::string::String, + /// type of the data used + #[prost(enumeration = "DataType", tag = "4")] + pub data_type: i32, + /// marshaled data + #[prost(bytes = "vec", tag = "5")] + pub data: ::prost::alloc::vec::Vec, +} +/// HeaderData returns the SignBytes data for update verification. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct HeaderData { + /// header public key + #[prost(message, optional, tag = "1")] + pub new_pub_key: ::core::option::Option<::prost_types::Any>, + /// header diversifier + #[prost(string, tag = "2")] + pub new_diversifier: ::prost::alloc::string::String, +} +/// ClientStateData returns the SignBytes data for client state verification. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ClientStateData { + #[prost(bytes = "vec", tag = "1")] + pub path: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "2")] + pub client_state: ::core::option::Option<::prost_types::Any>, +} +/// ConsensusStateData returns the SignBytes data for consensus state +/// verification. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ConsensusStateData { + #[prost(bytes = "vec", tag = "1")] + pub path: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "2")] + pub consensus_state: ::core::option::Option<::prost_types::Any>, +} +/// ConnectionStateData returns the SignBytes data for connection state +/// verification. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ConnectionStateData { + #[prost(bytes = "vec", tag = "1")] + pub path: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "2")] + pub connection: + ::core::option::Option, +} +/// ChannelStateData returns the SignBytes data for channel state +/// verification. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ChannelStateData { + #[prost(bytes = "vec", tag = "1")] + pub path: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "2")] + pub channel: ::core::option::Option, +} +/// PacketCommitmentData returns the SignBytes data for packet commitment +/// verification. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PacketCommitmentData { + #[prost(bytes = "vec", tag = "1")] + pub path: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub commitment: ::prost::alloc::vec::Vec, +} +/// PacketAcknowledgementData returns the SignBytes data for acknowledgement +/// verification. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PacketAcknowledgementData { + #[prost(bytes = "vec", tag = "1")] + pub path: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub acknowledgement: ::prost::alloc::vec::Vec, +} +/// PacketReceiptAbsenceData returns the SignBytes data for +/// packet receipt absence verification. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PacketReceiptAbsenceData { + #[prost(bytes = "vec", tag = "1")] + pub path: ::prost::alloc::vec::Vec, +} +/// NextSequenceRecvData returns the SignBytes data for verification of the next +/// sequence to be received. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct NextSequenceRecvData { + #[prost(bytes = "vec", tag = "1")] + pub path: ::prost::alloc::vec::Vec, + #[prost(uint64, tag = "2")] + pub next_seq_recv: u64, +} +/// 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, ::prost::Enumeration)] +#[repr(i32)] +pub enum DataType { + /// Default State + UninitializedUnspecified = 0, + /// Data type for client state verification + ClientState = 1, + /// Data type for consensus state verification + ConsensusState = 2, + /// Data type for connection state verification + ConnectionState = 3, + /// Data type for channel state verification + ChannelState = 4, + /// Data type for packet commitment verification + PacketCommitment = 5, + /// Data type for packet acknowledgement verification + PacketAcknowledgement = 6, + /// Data type for packet receipt absence verification + PacketReceiptAbsence = 7, + /// Data type for next sequence recv verification + NextSequenceRecv = 8, + /// Data type for header verification + Header = 9, +} diff --git a/proto/src/prost/ibc.lightclients.tendermint.v1.rs b/proto/src/prost/ibc.lightclients.tendermint.v1.rs index 3fdb9aaaa0..c12457f143 100644 --- a/proto/src/prost/ibc.lightclients.tendermint.v1.rs +++ b/proto/src/prost/ibc.lightclients.tendermint.v1.rs @@ -26,10 +26,12 @@ pub struct ClientState { #[prost(message, repeated, tag = "8")] pub proof_specs: ::prost::alloc::vec::Vec, /// Path at which next upgraded client will be committed. - /// Each element corresponds to the key for a single CommitmentProof in the chained proof. - /// NOTE: ClientState must stored under `{upgradePath}/{upgradeHeight}/clientState` - /// ConsensusState must be stored under `{upgradepath}/{upgradeHeight}/consensusState` - /// For SDK chains using the default upgrade module, upgrade_path should be []string{"upgrade", "upgradedIBCState"}` + /// Each element corresponds to the key for a single CommitmentProof in the + /// chained proof. NOTE: ClientState must stored under + /// `{upgradePath}/{upgradeHeight}/clientState` ConsensusState must be stored + /// under `{upgradepath}/{upgradeHeight}/consensusState` For SDK chains using + /// the default upgrade module, upgrade_path should be []string{"upgrade", + /// "upgradedIBCState"}` #[prost(string, repeated, tag = "9")] pub upgrade_path: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, /// This flag, when set to true, will allow governance to recover a client @@ -88,7 +90,8 @@ pub struct Header { #[prost(message, optional, tag = "4")] pub trusted_validators: ::core::option::Option<::tendermint_proto::types::ValidatorSet>, } -/// Fraction defines the protobuf message type for tmmath.Fraction that only supports positive values. +/// Fraction defines the protobuf message type for tmmath.Fraction that only +/// supports positive values. #[derive(Clone, PartialEq, ::prost::Message)] pub struct Fraction { #[prost(uint64, tag = "1")] diff --git a/relayer-cli/src/commands/tx.rs b/relayer-cli/src/commands/tx.rs index ff6ec99806..d03cfd0bc7 100644 --- a/relayer-cli/src/commands/tx.rs +++ b/relayer-cli/src/commands/tx.rs @@ -101,8 +101,8 @@ pub enum TxRawCommands { PacketAck(packet::TxRawPacketAckCmd), /// The `tx raw upgrade-chain` subcommand - #[options(help = "Send an upgrade plan")] - UpgradeChain(upgrade::TxUpgradeChainCmd), + #[options(help = "Send an IBC upgrade plan")] + UpgradeChain(upgrade::TxIbcUpgradeChainCmd), } impl Override for TxCmd { diff --git a/relayer-cli/src/commands/tx/upgrade.rs b/relayer-cli/src/commands/tx/upgrade.rs index a711207aae..71331dfcd2 100644 --- a/relayer-cli/src/commands/tx/upgrade.rs +++ b/relayer-cli/src/commands/tx/upgrade.rs @@ -1,11 +1,12 @@ use std::sync::Arc; +use std::time::Duration; use abscissa_core::{Command, Options, Runnable}; use tokio::runtime::Runtime as TokioRuntime; use ibc::events::IbcEvent; use ibc::ics24_host::identifier::{ChainId, ClientId}; -use ibc_relayer::upgrade_chain::{build_and_send_upgrade_chain_message, UpdatePlanOptions}; +use ibc_relayer::upgrade_chain::{build_and_send_ibc_upgrade_proposal, UpgradePlanOptions}; use ibc_relayer::{ chain::{ChainEndpoint, CosmosSdkChain}, config::Config, @@ -16,7 +17,7 @@ use crate::error::Error; use crate::prelude::*; #[derive(Clone, Command, Debug, Options)] -pub struct TxUpgradeChainCmd { +pub struct TxIbcUpgradeChainCmd { #[options(free, required, help = "identifier of the chain to upgrade")] dst_chain_id: ChainId, @@ -39,10 +40,37 @@ pub struct TxUpgradeChainCmd { help = "upgrade height offset in number of blocks since current" )] height_offset: u64, + + #[options( + short = "c", + meta = "CHAIN-ID", + help = "new chain identifier to assign to the upgrading chain (optional)" + )] + new_chain_id: Option, + + #[options( + short = "u", + meta = "PERIOD", + help = "new unbonding period to assign to the upgrading chain, in seconds (optional)" + )] + new_unbonding: Option, + + #[options( + short = "n", + meta = "NAME", + help = "a string to name the upgrade proposal plan (default: 'plan')" + )] + upgrade_name: Option, + + #[options( + help = "use legacy upgrade proposal constructs (for chains built with Cosmos SDK < v0.43.0)", + short = "l" + )] + legacy: bool, } -impl TxUpgradeChainCmd { - fn validate_options(&self, config: &Config) -> Result { +impl TxIbcUpgradeChainCmd { + fn validate_options(&self, config: &Config) -> Result { let src_chain_config = config .find_chain(&self.src_chain_id) .ok_or_else(|| "missing src chain configuration".to_string())?; @@ -51,19 +79,29 @@ impl TxUpgradeChainCmd { .find_chain(&self.dst_chain_id) .ok_or_else(|| "missing destination chain configuration".to_string())?; - let opts = UpdatePlanOptions { + let opts = UpgradePlanOptions { dst_chain_config: dst_chain_config.clone(), src_chain_config: src_chain_config.clone(), src_client_id: self.src_client_id.clone(), amount: self.amount, height_offset: self.height_offset, + upgraded_chain_id: self + .new_chain_id + .clone() + .unwrap_or_else(|| self.dst_chain_id.clone()), + upgraded_unbonding_period: self.new_unbonding.map(Duration::from_secs), + upgrade_plan_name: self + .upgrade_name + .clone() + .unwrap_or_else(|| "plan".to_string()), + legacy: self.legacy, }; Ok(opts) } } -impl Runnable for TxUpgradeChainCmd { +impl Runnable for TxIbcUpgradeChainCmd { fn run(&self) { let config = app_config(); @@ -90,7 +128,7 @@ impl Runnable for TxUpgradeChainCmd { }; let res: Result, Error> = - build_and_send_upgrade_chain_message(dst_chain, src_chain, &opts) + build_and_send_ibc_upgrade_proposal(dst_chain, src_chain, &opts) .map_err(Error::upgrade_chain); match res { diff --git a/relayer/src/chain/cosmos.rs b/relayer/src/chain/cosmos.rs index 91883dc4cb..dabcef014a 100644 --- a/relayer/src/chain/cosmos.rs +++ b/relayer/src/chain/cosmos.rs @@ -32,6 +32,7 @@ use ibc::ics02_client::client_consensus::{ AnyConsensusState, AnyConsensusStateWithHeight, QueryClientEventRequest, }; use ibc::ics02_client::client_state::{AnyClientState, IdentifiedAnyClientState}; +use ibc::ics02_client::client_type::ClientType; use ibc::ics02_client::events as ClientEvents; use ibc::ics03_connection::connection::{ConnectionEnd, IdentifiedConnectionEnd}; use ibc::ics04_channel::channel::{ChannelEnd, IdentifiedChannelEnd, QueryPacketEventDataRequest}; @@ -58,9 +59,6 @@ use ibc_proto::cosmos::tx::v1beta1::{ AuthInfo, Fee, ModeInfo, SignDoc, SignerInfo, SimulateRequest, SimulateResponse, Tx, TxBody, TxRaw, }; -use ibc_proto::cosmos::upgrade::v1beta1::{ - QueryCurrentPlanRequest, QueryUpgradedConsensusStateRequest, -}; use ibc_proto::ibc::core::channel::v1::{ PacketState, QueryChannelClientStateRequest, QueryChannelsRequest, QueryConnectionChannelsRequest, QueryNextSequenceReceiveRequest, @@ -335,12 +333,10 @@ impl CosmosSdkChain { // if the batch is split in two TX-es, the second one will fail the simulation in `deliverTx` check // In this case we just leave the gas un-adjusted, i.e. use `self.max_gas()` let estimated_gas = self - .send_tx_simulate(SimulateRequest { - tx: Some(Tx { - body: Some(body), - auth_info: Some(auth_info), - signatures: vec![signed_doc], - }), + .send_tx_simulate(Tx { + body: Some(body), + auth_info: Some(auth_info), + signatures: vec![signed_doc], }) .map_or(self.max_gas(), |sr| { sr.gas_info.map_or(self.max_gas(), |g| g.gas_used) @@ -452,12 +448,17 @@ impl CosmosSdkChain { Ok(response) } - // Perform an ABCI query against the client upgrade sub-store to fetch a proof. - fn query_client_upgrade_proof( + /// Perform an ABCI query against the client upgrade sub-store. + /// Fetches both the target data, as well as the proof. + /// + /// The data is returned in its raw format `Vec`, and is either + /// the client state (if the target path is [`UpgradedClientState`]), + /// or the client consensus state ([`UpgradedClientConsensusState`]). + fn query_client_upgrade_state( &self, data: ClientUpgradePath, height: Height, - ) -> Result<(MerkleProof, ICSHeight), Error> { + ) -> Result<(Vec, MerkleProof), Error> { let prev_height = Height::try_from(height.value() - 1).map_err(Error::invalid_height)?; let path = TendermintABCIPath::from_str(SDK_UPGRADE_QUERY_PATH).unwrap(); @@ -471,17 +472,19 @@ impl CosmosSdkChain { let proof = response.proof.ok_or_else(Error::empty_response_proof)?; - let height = ICSHeight::new( - self.config.id.version(), - response.height.increment().value(), - ); - - Ok((proof, height)) + Ok((response.value, proof)) } - fn send_tx_simulate(&self, request: SimulateRequest) -> Result { + fn send_tx_simulate(&self, tx: Tx) -> Result { crate::time!("tx simulate"); + // The `tx` field of `SimulateRequest` was deprecated + // in favor of `tx_bytes` + let mut tx_bytes = vec![]; + prost::Message::encode(&tx, &mut tx_bytes).unwrap(); + #[allow(deprecated)] + let req = SimulateRequest { tx: None, tx_bytes }; + let mut client = self .block_on( ibc_proto::cosmos::tx::v1beta1::service_client::ServiceClient::connect( @@ -490,7 +493,7 @@ impl CosmosSdkChain { ) .map_err(Error::grpc_transport)?; - let request = tonic::Request::new(request); + let request = tonic::Request::new(req); let response = self .block_on(client.simulate(request)) .map_err(Error::grpc_status)? @@ -954,39 +957,20 @@ impl ChainEndpoint for CosmosSdkChain { ) -> Result<(Self::ClientState, MerkleProof), Error> { crate::time!("query_upgraded_client_state"); - let mut client = self - .block_on( - ibc_proto::cosmos::upgrade::v1beta1::query_client::QueryClient::connect( - self.grpc_addr.clone(), - ), - ) - .map_err(Error::grpc_transport)?; - - let req = tonic::Request::new(QueryCurrentPlanRequest {}); - let response = self - .block_on(client.current_plan(req)) - .map_err(Error::grpc_status)?; - - let upgraded_client_state_raw = response - .into_inner() - .plan - .ok_or_else(Error::empty_response_value)? - .upgraded_client_state - .ok_or_else(Error::empty_upgraded_client_state)?; - let client_state = AnyClientState::try_from(upgraded_client_state_raw) - .map_err(Error::invalid_upgraded_client_state)?; - - // TODO: Better error kinds here. - let tm_client_state = downcast!(client_state.clone() => AnyClientState::Tendermint) - .ok_or_else(|| Error::client_state_type(format!("{:?}", client_state)))?; - - // Query for the proof. + // Query for the value and the proof. let tm_height = Height::try_from(height.revision_height).map_err(Error::invalid_height)?; - let (proof, _proof_height) = self.query_client_upgrade_proof( + let (upgraded_client_state_raw, proof) = self.query_client_upgrade_state( ClientUpgradePath::UpgradedClientState(height.revision_height), tm_height, )?; + let client_state = AnyClientState::decode_vec(&upgraded_client_state_raw) + .map_err(Error::conversion_from_any)?; + + let client_type = client_state.client_type(); + let tm_client_state = downcast!(client_state => AnyClientState::Tendermint) + .ok_or_else(|| Error::client_type_mismatch(ClientType::Tendermint, client_type))?; + Ok((tm_client_state, proof)) } @@ -998,40 +982,21 @@ impl ChainEndpoint for CosmosSdkChain { let tm_height = Height::try_from(height.revision_height).map_err(Error::invalid_height)?; - let mut client = self - .block_on( - ibc_proto::cosmos::upgrade::v1beta1::query_client::QueryClient::connect( - self.grpc_addr.clone(), - ), - ) - .map_err(Error::grpc_transport)?; - - let req = tonic::Request::new(QueryUpgradedConsensusStateRequest { - last_height: tm_height.into(), - }); - let response = self - .block_on(client.upgraded_consensus_state(req)) - .map_err(Error::grpc_status)?; - - let upgraded_consensus_state_raw = response - .into_inner() - .upgraded_consensus_state - .ok_or_else(Error::empty_response_value)?; - - // TODO: More explicit error kinds (should not reuse Grpc all over the place) - let consensus_state = - AnyConsensusState::try_from(upgraded_consensus_state_raw).map_err(Error::ics02)?; - - let tm_consensus_state = - downcast!(consensus_state.clone() => AnyConsensusState::Tendermint) - .ok_or_else(|| Error::client_state_type(format!("{:?}", consensus_state)))?; - - // Fetch the proof. - let (proof, _proof_height) = self.query_client_upgrade_proof( + // Fetch the consensus state and its proof. + let (upgraded_consensus_state_raw, proof) = self.query_client_upgrade_state( ClientUpgradePath::UpgradedClientConsensusState(height.revision_height), tm_height, )?; + let consensus_state = AnyConsensusState::decode_vec(&upgraded_consensus_state_raw) + .map_err(Error::conversion_from_any)?; + + let cs_client_type = consensus_state.client_type(); + let tm_consensus_state = downcast!(consensus_state => AnyConsensusState::Tendermint) + .ok_or_else(|| { + Error::consensus_state_type_mismatch(ClientType::Tendermint, cs_client_type) + })?; + Ok((tm_consensus_state, proof)) } diff --git a/relayer/src/chain/cosmos/compatibility.rs b/relayer/src/chain/cosmos/compatibility.rs index c475b3d4e5..e79c430fdb 100644 --- a/relayer/src/chain/cosmos/compatibility.rs +++ b/relayer/src/chain/cosmos/compatibility.rs @@ -23,7 +23,7 @@ const SDK_MODULE_NAME: &str = "cosmos/cosmos-sdk"; /// # Note: Should be consistent with [features] guide page. /// /// [features]: https://hermes.informal.systems/features.html -const SDK_MODULE_VERSION_REQ: &str = ">=0.41.3, <=0.42.9"; +const SDK_MODULE_VERSION_REQ: &str = ">=0.41.3, <=0.43.0"; /// Helper struct to capture all the reported information of an /// IBC application, e.g., `gaiad`. diff --git a/relayer/src/error.rs b/relayer/src/error.rs index 76bcf56c8f..4af2417ba5 100644 --- a/relayer/src/error.rs +++ b/relayer/src/error.rs @@ -129,12 +129,19 @@ define_error! { Event |_| { "Bad Notification" }, + ConversionFromAny + [ TraceError ] + |_| { "Conversion from a protobuf `Any` into a domain type failed" }, + EmptyUpgradedClientState - |_| { "The upgrade plan specifies no upgraded client state" }, + |_| { "Found no upgraded client state" }, - InvalidUpgradedClientState - [ client_error::Error ] - |e| { format!("the upgrade plan specifies an invalid upgraded client state: {}", e.source) }, + ConsensusStateTypeMismatch + { + expected: ClientType, + got: ClientType, + } + |e| { format!("consensus state type mismatch; hint: expected client type '{0}', got '{1}'", e.expected, e.got) }, EmptyResponseValue |_| { "Empty response value" }, @@ -415,7 +422,6 @@ define_error! { format!("Hermes health check failed while verifying the application compatibility for chain {0}:{1}; caused by: {2}", e.chain_id, e.address, e.cause) }, - } } diff --git a/relayer/src/event/rpc.rs b/relayer/src/event/rpc.rs index 34073a3927..bcfe85c693 100644 --- a/relayer/src/event/rpc.rs +++ b/relayer/src/event/rpc.rs @@ -59,52 +59,68 @@ pub fn get_all_events( pub fn build_event(mut object: RawObject) -> Result { match object.action.as_str() { // Client events - "create_client" => Ok(IbcEvent::from(ClientEvents::CreateClient::try_from( - object, - )?)), - "update_client" => Ok(IbcEvent::from(ClientEvents::UpdateClient::try_from( - object, - )?)), - "submit_misbehaviour" => Ok(IbcEvent::from(ClientEvents::ClientMisbehaviour::try_from( - object, - )?)), + "create_client" | ibc::ics02_client::msgs::create_client::TYPE_URL => Ok(IbcEvent::from( + ClientEvents::CreateClient::try_from(object)?, + )), + "update_client" | ibc::ics02_client::msgs::update_client::TYPE_URL => Ok(IbcEvent::from( + ClientEvents::UpdateClient::try_from(object)?, + )), + "submit_misbehaviour" | ibc::ics02_client::msgs::misbehavior::TYPE_URL => Ok( + IbcEvent::from(ClientEvents::ClientMisbehaviour::try_from(object)?), + ), // Connection events - "connection_open_init" => Ok(IbcEvent::from(ConnectionEvents::OpenInit::try_from( - object, - )?)), - "connection_open_try" => Ok(IbcEvent::from(ConnectionEvents::OpenTry::try_from(object)?)), - "connection_open_ack" => Ok(IbcEvent::from(ConnectionEvents::OpenAck::try_from(object)?)), - "connection_open_confirm" => Ok(IbcEvent::from(ConnectionEvents::OpenConfirm::try_from( - object, - )?)), + "connection_open_init" | ibc::ics03_connection::msgs::conn_open_init::TYPE_URL => Ok( + IbcEvent::from(ConnectionEvents::OpenInit::try_from(object)?), + ), + "connection_open_try" | ibc::ics03_connection::msgs::conn_open_try::TYPE_URL => { + Ok(IbcEvent::from(ConnectionEvents::OpenTry::try_from(object)?)) + } + "connection_open_ack" | ibc::ics03_connection::msgs::conn_open_ack::TYPE_URL => { + Ok(IbcEvent::from(ConnectionEvents::OpenAck::try_from(object)?)) + } + "connection_open_confirm" | ibc::ics03_connection::msgs::conn_open_confirm::TYPE_URL => Ok( + IbcEvent::from(ConnectionEvents::OpenConfirm::try_from(object)?), + ), // Channel events - "channel_open_init" => Ok(IbcEvent::from(ChannelEvents::OpenInit::try_from(object)?)), - "channel_open_try" => Ok(IbcEvent::from(ChannelEvents::OpenTry::try_from(object)?)), - "channel_open_ack" => Ok(IbcEvent::from(ChannelEvents::OpenAck::try_from(object)?)), - "channel_open_confirm" => Ok(IbcEvent::from(ChannelEvents::OpenConfirm::try_from( - object, - )?)), - "channel_close_init" => Ok(IbcEvent::from(ChannelEvents::CloseInit::try_from(object)?)), - "channel_close_confirm" => Ok(IbcEvent::from(ChannelEvents::CloseConfirm::try_from( - object, - )?)), + "channel_open_init" | ibc::ics04_channel::msgs::chan_open_init::TYPE_URL => { + Ok(IbcEvent::from(ChannelEvents::OpenInit::try_from(object)?)) + } + "channel_open_try" | ibc::ics04_channel::msgs::chan_open_try::TYPE_URL => { + Ok(IbcEvent::from(ChannelEvents::OpenTry::try_from(object)?)) + } + "channel_open_ack" | ibc::ics04_channel::msgs::chan_open_ack::TYPE_URL => { + Ok(IbcEvent::from(ChannelEvents::OpenAck::try_from(object)?)) + } + "channel_open_confirm" | ibc::ics04_channel::msgs::chan_open_confirm::TYPE_URL => Ok( + IbcEvent::from(ChannelEvents::OpenConfirm::try_from(object)?), + ), + "channel_close_init" | ibc::ics04_channel::msgs::chan_close_init::TYPE_URL => { + Ok(IbcEvent::from(ChannelEvents::CloseInit::try_from(object)?)) + } + "channel_close_confirm" | ibc::ics04_channel::msgs::chan_close_confirm::TYPE_URL => Ok( + IbcEvent::from(ChannelEvents::CloseConfirm::try_from(object)?), + ), // Packet events // Note: There is no message.action "send_packet", the only one we can hook into is the // module's action: // - "transfer" for ICS20 - // - "register" and "send" for ICS27 + // - "MsgSend" and "MsgRegister" for ICS27 // However the attributes are all prefixed with "send_packet" therefore the overwrite here // TODO: This need to be sorted out - "transfer" | "register" | "send" => { + "transfer" + | ibc::application::ics20_fungible_token_transfer::msgs::transfer::TYPE_URL + | ibc::application::ICS27_BANK_SEND_TYPE_URL + | ibc::application::ICS27_SEND_TYPE_URL + | ibc::application::ICS27_REGISTER_TYPE_URL => { object.action = "send_packet".to_string(); Ok(IbcEvent::from(ChannelEvents::SendPacket::try_from(object)?)) } // Same here // TODO: sort this out - "recv_packet" => { + "recv_packet" | ibc::ics04_channel::msgs::recv_packet::TYPE_URL => { object.action = "write_acknowledgement".to_string(); Ok(IbcEvent::from( ChannelEvents::WriteAcknowledgement::try_from(object)?, @@ -113,14 +129,19 @@ pub fn build_event(mut object: RawObject) -> Result { "write_acknowledgement" => Ok(IbcEvent::from( ChannelEvents::WriteAcknowledgement::try_from(object)?, )), - "acknowledge_packet" => Ok(IbcEvent::from(ChannelEvents::AcknowledgePacket::try_from( - object, - )?)), - "timeout_packet" => Ok(IbcEvent::from(ChannelEvents::TimeoutPacket::try_from( - object, - )?)), - - "timeout_on_close_packet" => { + "acknowledge_packet" | ibc::ics04_channel::msgs::acknowledgement::TYPE_URL => { + object.action = "acknowledge_packet".to_string(); + Ok(IbcEvent::from(ChannelEvents::AcknowledgePacket::try_from( + object, + )?)) + } + "timeout_packet" | ibc::ics04_channel::msgs::timeout::TYPE_URL => { + object.action = "timeout_packet".to_string(); + Ok(IbcEvent::from(ChannelEvents::TimeoutPacket::try_from( + object, + )?)) + } + "timeout_on_close_packet" | ibc::ics04_channel::msgs::timeout_on_close::TYPE_URL => { object.action = "timeout_packet".to_string(); Ok(IbcEvent::from( ChannelEvents::TimeoutOnClosePacket::try_from(object)?, diff --git a/relayer/src/upgrade_chain.rs b/relayer/src/upgrade_chain.rs index ed9712c4db..57f97b9325 100644 --- a/relayer/src/upgrade_chain.rs +++ b/relayer/src/upgrade_chain.rs @@ -1,13 +1,19 @@ +//! Chain upgrade plans for triggering IBC-breaking upgrades. +#![allow(deprecated)] // TODO(hu55a1n1): remove this when we don't need legacy upgrade support + use std::time::Duration; +use bytes::BufMut; use flex_error::define_error; +use prost_types::Any; + use ibc::ics02_client::client_state::AnyClientState; use ibc::ics02_client::height::Height; use ibc::ics24_host::identifier::{ChainId, ClientId}; use ibc::{events::IbcEvent, ics07_tendermint::client_state::ClientState}; use ibc_proto::cosmos::gov::v1beta1::MsgSubmitProposal; use ibc_proto::cosmos::upgrade::v1beta1::{Plan, SoftwareUpgradeProposal}; -use prost_types::Any; +use ibc_proto::ibc::core::client::v1::UpgradeProposal; use crate::chain::{ChainEndpoint, CosmosSdkChain}; use crate::config::ChainConfig; @@ -15,6 +21,10 @@ use crate::error::Error; define_error! { UpgradeChainError { + Query + [ Error ] + |_| { "error during a query" }, + Key [ Error ] |_| { "key error" }, @@ -38,54 +48,65 @@ define_error! { } #[derive(Clone, Debug)] -pub struct UpdatePlanOptions { +pub struct UpgradePlanOptions { pub src_chain_config: ChainConfig, pub dst_chain_config: ChainConfig, pub src_client_id: ClientId, pub amount: u64, pub height_offset: u64, + pub upgraded_chain_id: ChainId, + pub upgraded_unbonding_period: Option, + pub upgrade_plan_name: String, + pub legacy: bool, } -pub fn build_and_send_upgrade_chain_message( - mut dst_chain: CosmosSdkChain, // the chain undergoing upgrade - src_chain: CosmosSdkChain, // the chain supplying a client state - opts: &UpdatePlanOptions, +pub fn build_and_send_ibc_upgrade_proposal( + mut dst_chain: CosmosSdkChain, // the chain which will undergo an upgrade + src_chain: CosmosSdkChain, // the source chain; supplies a client state for building the upgrade plan + opts: &UpgradePlanOptions, ) -> Result, UpgradeChainError> { - // build a proposal Plan let upgrade_height = dst_chain .query_latest_height() - .unwrap() + .map_err(UpgradeChainError::query)? .add(opts.height_offset); let client_state = src_chain .query_client_state(&opts.src_client_id, Height::zero()) - .unwrap(); + .map_err(UpgradeChainError::query)?; + + // Retain the old unbonding period in case the user did not specify a new one + let upgraded_unbonding_period = opts + .upgraded_unbonding_period + .unwrap_or(client_state.unbonding_period); let mut upgraded_client_state = ClientState::zero_custom_fields(client_state); upgraded_client_state.latest_height = upgrade_height.increment(); - upgraded_client_state.unbonding_period = Duration::from_secs(400 * 3600); + upgraded_client_state.unbonding_period = upgraded_unbonding_period; + upgraded_client_state.chain_id = opts.upgraded_chain_id.clone(); let raw_client_state = AnyClientState::Tendermint(upgraded_client_state); - let plan = Plan { - name: "test".to_string(), - time: None, - height: upgrade_height.revision_height as i64, - info: "upgrade the chain software and unbonding period".to_string(), + let proposal = UpgradeProposal { + title: "proposal 0".to_string(), + description: "upgrade the chain software and unbonding period".to_string(), upgraded_client_state: Some(Any::from(raw_client_state)), + plan: Some(Plan { + name: opts.upgrade_plan_name.clone(), + height: upgrade_height.revision_height as i64, + info: "".to_string(), + ..Default::default() // deprecated fields - time & upgraded_client_state + }), }; - // build the proposal - let proposal = SoftwareUpgradeProposal { - title: "upgrade_ibc_clients".to_string(), - description: "upgrade the chain software and unbonding period".to_string(), - plan: Some(plan), + let proposal = if opts.legacy { + Proposal::Legacy(proposal.into()) + } else { + Proposal::Default(proposal) }; let mut buf_proposal = Vec::new(); - prost::Message::encode(&proposal, &mut buf_proposal).unwrap(); - + proposal.encode(&mut buf_proposal); let any_proposal = Any { - type_url: "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal".to_string(), + type_url: proposal.type_url(), value: buf_proposal, }; @@ -125,3 +146,51 @@ pub fn build_and_send_upgrade_chain_message( Some(reason) => Err(UpgradeChainError::tx_response(reason)), } } + +enum Proposal { + Default(UpgradeProposal), + Legacy(LegacyProposal), +} + +impl Proposal { + fn encode(&self, buf: &mut impl BufMut) { + match self { + Proposal::Default(p) => prost::Message::encode(p, buf), + Proposal::Legacy(p) => prost::Message::encode(&p.0, buf), + } + .unwrap() + } + + fn type_url(&self) -> String { + match self { + Proposal::Default(_) => "/ibc.core.client.v1.UpgradeProposal", + Proposal::Legacy(_) => "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", + } + .to_owned() + } +} + +struct LegacyProposal(SoftwareUpgradeProposal); + +impl From for LegacyProposal { + fn from(v: UpgradeProposal) -> Self { + let plan = { + if let Some(plan) = v.plan { + Some(Plan { + name: plan.name, + height: plan.height, + info: plan.info, + time: None, + upgraded_client_state: v.upgraded_client_state, + }) + } else { + None + } + }; + Self(SoftwareUpgradeProposal { + title: v.title, + description: v.description, + plan, + }) + } +}