From 96b0ba7d606fca9c574cdf12f67d89ba830d69bc Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 27 Apr 2023 22:25:26 +0300 Subject: [PATCH 01/54] Skeleton for IBC enclave light client validation --- .vscode/settings.json | 7 +- .../enclaves/shared/cosmos-proto/build.rs | 16 + .../shared/cosmos-proto/src/ibc/channel.rs | 2360 ++++++++ .../shared/cosmos-proto/src/ibc/client.rs | 1673 ++++++ .../shared/cosmos-proto/src/ibc/tx.rs | 5090 +++++++++++++++++ .../enclaves/shared/cosmos-proto/src/lib.rs | 6 + .../enclaves/shared/cosmos-types/src/types.rs | 68 + 7 files changed, 9218 insertions(+), 2 deletions(-) create mode 100644 cosmwasm/enclaves/shared/cosmos-proto/src/ibc/channel.rs create mode 100644 cosmwasm/enclaves/shared/cosmos-proto/src/ibc/client.rs create mode 100644 cosmwasm/enclaves/shared/cosmos-proto/src/ibc/tx.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 179ffa0aa..2a35bf3e7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,7 +14,8 @@ "integration-tests/contract-v0.10/Cargo.toml", "go-cosmwasm/Cargo.toml", "integration-tests/contract-v0.10/Cargo.toml", - "check-hw/Cargo.toml" + "check-hw/Cargo.toml", + "./cosmwasm/enclaves/shared/cosmos-proto/Cargo.toml" ], "rust-analyzer.diagnostics.experimental.enable": true, "rust-analyzer.rustfmt.rangeFormatting.enable": true, @@ -22,6 +23,7 @@ "unresolved-macro-call", "unresolved-proc-macro" ], + "rust-analyzer.cargo.features": ["light-client-validation", "build-protobuf"], "[rust]": { "editor.formatOnSave": true, "editor.defaultFormatter": "rust-lang.rust-analyzer" @@ -40,5 +42,6 @@ "[go]": { "editor.formatOnSave": true, "editor.defaultFormatter": "golang.go" - } + }, + "rust-analyzer.showUnlinkedFileNotification": false } diff --git a/cosmwasm/enclaves/shared/cosmos-proto/build.rs b/cosmwasm/enclaves/shared/cosmos-proto/build.rs index 7cbfa2287..ccb854a7b 100644 --- a/cosmwasm/enclaves/shared/cosmos-proto/build.rs +++ b/cosmwasm/enclaves/shared/cosmos-proto/build.rs @@ -47,6 +47,14 @@ mod protobuf { .expect(&format!("could not canonicalize {:?}", path)) } + fn from_ibc(path: &str) -> PathBuf { + let mut full_path = PathBuf::from("../../../../third_party/proto/ibc"); + full_path.push(path); + full_path + .canonicalize() + .expect(&format!("could not canonicalize {:?}", path)) + } + pub fn build_protobuf_parsers() { let protoc_err_msg = "protoc failed to generate protobuf parsers"; let mut library_dir = dirs::home_dir().unwrap(); @@ -84,6 +92,14 @@ mod protobuf { "src/cosmwasm", &[from_base("proto/secret/compute/v1beta1/msg.proto")], ), + ( + "src/ibc", + &[ + from_ibc("core/channel/v1/tx.proto"), + from_ibc("core/channel/v1/channel.proto"), + from_ibc("core/client/v1/client.proto"), + ], + ), ]; for (out_dir, inputs) in directories { diff --git a/cosmwasm/enclaves/shared/cosmos-proto/src/ibc/channel.rs b/cosmwasm/enclaves/shared/cosmos-proto/src/ibc/channel.rs new file mode 100644 index 000000000..a2d7eecfd --- /dev/null +++ b/cosmwasm/enclaves/shared/cosmos-proto/src/ibc/channel.rs @@ -0,0 +1,2360 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `ibc/core/channel/v1/channel.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct Channel { + // message fields + pub state: State, + pub ordering: Order, + pub counterparty: ::protobuf::SingularPtrField, + pub connection_hops: ::protobuf::RepeatedField<::std::string::String>, + pub version: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Channel { + fn default() -> &'a Channel { + ::default_instance() + } +} + +impl Channel { + pub fn new() -> Channel { + ::std::default::Default::default() + } + + // .ibc.core.channel.v1.State state = 1; + + + pub fn get_state(&self) -> State { + self.state + } + pub fn clear_state(&mut self) { + self.state = State::STATE_UNINITIALIZED_UNSPECIFIED; + } + + // Param is passed by value, moved + pub fn set_state(&mut self, v: State) { + self.state = v; + } + + // .ibc.core.channel.v1.Order ordering = 2; + + + pub fn get_ordering(&self) -> Order { + self.ordering + } + pub fn clear_ordering(&mut self) { + self.ordering = Order::ORDER_NONE_UNSPECIFIED; + } + + // Param is passed by value, moved + pub fn set_ordering(&mut self, v: Order) { + self.ordering = v; + } + + // .ibc.core.channel.v1.Counterparty counterparty = 3; + + + pub fn get_counterparty(&self) -> &Counterparty { + self.counterparty.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_counterparty(&mut self) { + self.counterparty.clear(); + } + + pub fn has_counterparty(&self) -> bool { + self.counterparty.is_some() + } + + // Param is passed by value, moved + pub fn set_counterparty(&mut self, v: Counterparty) { + self.counterparty = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_counterparty(&mut self) -> &mut Counterparty { + if self.counterparty.is_none() { + self.counterparty.set_default(); + } + self.counterparty.as_mut().unwrap() + } + + // Take field + pub fn take_counterparty(&mut self) -> Counterparty { + self.counterparty.take().unwrap_or_else(|| Counterparty::new()) + } + + // repeated string connection_hops = 4; + + + pub fn get_connection_hops(&self) -> &[::std::string::String] { + &self.connection_hops + } + pub fn clear_connection_hops(&mut self) { + self.connection_hops.clear(); + } + + // Param is passed by value, moved + pub fn set_connection_hops(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) { + self.connection_hops = v; + } + + // Mutable pointer to the field. + pub fn mut_connection_hops(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> { + &mut self.connection_hops + } + + // Take field + pub fn take_connection_hops(&mut self) -> ::protobuf::RepeatedField<::std::string::String> { + ::std::mem::replace(&mut self.connection_hops, ::protobuf::RepeatedField::new()) + } + + // string version = 5; + + + pub fn get_version(&self) -> &str { + &self.version + } + pub fn clear_version(&mut self) { + self.version.clear(); + } + + // Param is passed by value, moved + pub fn set_version(&mut self, v: ::std::string::String) { + self.version = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_version(&mut self) -> &mut ::std::string::String { + &mut self.version + } + + // Take field + pub fn take_version(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.version, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for Channel { + fn is_initialized(&self) -> bool { + for v in &self.counterparty { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.state, 1, &mut self.unknown_fields)? + }, + 2 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.ordering, 2, &mut self.unknown_fields)? + }, + 3 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.counterparty)?; + }, + 4 => { + ::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.connection_hops)?; + }, + 5 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.version)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.state != State::STATE_UNINITIALIZED_UNSPECIFIED { + my_size += ::protobuf::rt::enum_size(1, self.state); + } + if self.ordering != Order::ORDER_NONE_UNSPECIFIED { + my_size += ::protobuf::rt::enum_size(2, self.ordering); + } + if let Some(ref v) = self.counterparty.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + for value in &self.connection_hops { + my_size += ::protobuf::rt::string_size(4, &value); + }; + if !self.version.is_empty() { + my_size += ::protobuf::rt::string_size(5, &self.version); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.state != State::STATE_UNINITIALIZED_UNSPECIFIED { + os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.state))?; + } + if self.ordering != Order::ORDER_NONE_UNSPECIFIED { + os.write_enum(2, ::protobuf::ProtobufEnum::value(&self.ordering))?; + } + if let Some(ref v) = self.counterparty.as_ref() { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + for v in &self.connection_hops { + os.write_string(4, &v)?; + }; + if !self.version.is_empty() { + os.write_string(5, &self.version)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Channel { + Channel::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "state", + |m: &Channel| { &m.state }, + |m: &mut Channel| { &mut m.state }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "ordering", + |m: &Channel| { &m.ordering }, + |m: &mut Channel| { &mut m.ordering }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "counterparty", + |m: &Channel| { &m.counterparty }, + |m: &mut Channel| { &mut m.counterparty }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "connection_hops", + |m: &Channel| { &m.connection_hops }, + |m: &mut Channel| { &mut m.connection_hops }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "version", + |m: &Channel| { &m.version }, + |m: &mut Channel| { &mut m.version }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Channel", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Channel { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Channel::new) + } +} + +impl ::protobuf::Clear for Channel { + fn clear(&mut self) { + self.state = State::STATE_UNINITIALIZED_UNSPECIFIED; + self.ordering = Order::ORDER_NONE_UNSPECIFIED; + self.counterparty.clear(); + self.connection_hops.clear(); + self.version.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Channel { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Channel { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct IdentifiedChannel { + // message fields + pub state: State, + pub ordering: Order, + pub counterparty: ::protobuf::SingularPtrField, + pub connection_hops: ::protobuf::RepeatedField<::std::string::String>, + pub version: ::std::string::String, + pub port_id: ::std::string::String, + pub channel_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a IdentifiedChannel { + fn default() -> &'a IdentifiedChannel { + ::default_instance() + } +} + +impl IdentifiedChannel { + pub fn new() -> IdentifiedChannel { + ::std::default::Default::default() + } + + // .ibc.core.channel.v1.State state = 1; + + + pub fn get_state(&self) -> State { + self.state + } + pub fn clear_state(&mut self) { + self.state = State::STATE_UNINITIALIZED_UNSPECIFIED; + } + + // Param is passed by value, moved + pub fn set_state(&mut self, v: State) { + self.state = v; + } + + // .ibc.core.channel.v1.Order ordering = 2; + + + pub fn get_ordering(&self) -> Order { + self.ordering + } + pub fn clear_ordering(&mut self) { + self.ordering = Order::ORDER_NONE_UNSPECIFIED; + } + + // Param is passed by value, moved + pub fn set_ordering(&mut self, v: Order) { + self.ordering = v; + } + + // .ibc.core.channel.v1.Counterparty counterparty = 3; + + + pub fn get_counterparty(&self) -> &Counterparty { + self.counterparty.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_counterparty(&mut self) { + self.counterparty.clear(); + } + + pub fn has_counterparty(&self) -> bool { + self.counterparty.is_some() + } + + // Param is passed by value, moved + pub fn set_counterparty(&mut self, v: Counterparty) { + self.counterparty = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_counterparty(&mut self) -> &mut Counterparty { + if self.counterparty.is_none() { + self.counterparty.set_default(); + } + self.counterparty.as_mut().unwrap() + } + + // Take field + pub fn take_counterparty(&mut self) -> Counterparty { + self.counterparty.take().unwrap_or_else(|| Counterparty::new()) + } + + // repeated string connection_hops = 4; + + + pub fn get_connection_hops(&self) -> &[::std::string::String] { + &self.connection_hops + } + pub fn clear_connection_hops(&mut self) { + self.connection_hops.clear(); + } + + // Param is passed by value, moved + pub fn set_connection_hops(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) { + self.connection_hops = v; + } + + // Mutable pointer to the field. + pub fn mut_connection_hops(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> { + &mut self.connection_hops + } + + // Take field + pub fn take_connection_hops(&mut self) -> ::protobuf::RepeatedField<::std::string::String> { + ::std::mem::replace(&mut self.connection_hops, ::protobuf::RepeatedField::new()) + } + + // string version = 5; + + + pub fn get_version(&self) -> &str { + &self.version + } + pub fn clear_version(&mut self) { + self.version.clear(); + } + + // Param is passed by value, moved + pub fn set_version(&mut self, v: ::std::string::String) { + self.version = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_version(&mut self) -> &mut ::std::string::String { + &mut self.version + } + + // Take field + pub fn take_version(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.version, ::std::string::String::new()) + } + + // string port_id = 6; + + + pub fn get_port_id(&self) -> &str { + &self.port_id + } + pub fn clear_port_id(&mut self) { + self.port_id.clear(); + } + + // Param is passed by value, moved + pub fn set_port_id(&mut self, v: ::std::string::String) { + self.port_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_port_id(&mut self) -> &mut ::std::string::String { + &mut self.port_id + } + + // Take field + pub fn take_port_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.port_id, ::std::string::String::new()) + } + + // string channel_id = 7; + + + pub fn get_channel_id(&self) -> &str { + &self.channel_id + } + pub fn clear_channel_id(&mut self) { + self.channel_id.clear(); + } + + // Param is passed by value, moved + pub fn set_channel_id(&mut self, v: ::std::string::String) { + self.channel_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_channel_id(&mut self) -> &mut ::std::string::String { + &mut self.channel_id + } + + // Take field + pub fn take_channel_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.channel_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for IdentifiedChannel { + fn is_initialized(&self) -> bool { + for v in &self.counterparty { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.state, 1, &mut self.unknown_fields)? + }, + 2 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.ordering, 2, &mut self.unknown_fields)? + }, + 3 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.counterparty)?; + }, + 4 => { + ::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.connection_hops)?; + }, + 5 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.version)?; + }, + 6 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.port_id)?; + }, + 7 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.channel_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.state != State::STATE_UNINITIALIZED_UNSPECIFIED { + my_size += ::protobuf::rt::enum_size(1, self.state); + } + if self.ordering != Order::ORDER_NONE_UNSPECIFIED { + my_size += ::protobuf::rt::enum_size(2, self.ordering); + } + if let Some(ref v) = self.counterparty.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + for value in &self.connection_hops { + my_size += ::protobuf::rt::string_size(4, &value); + }; + if !self.version.is_empty() { + my_size += ::protobuf::rt::string_size(5, &self.version); + } + if !self.port_id.is_empty() { + my_size += ::protobuf::rt::string_size(6, &self.port_id); + } + if !self.channel_id.is_empty() { + my_size += ::protobuf::rt::string_size(7, &self.channel_id); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.state != State::STATE_UNINITIALIZED_UNSPECIFIED { + os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.state))?; + } + if self.ordering != Order::ORDER_NONE_UNSPECIFIED { + os.write_enum(2, ::protobuf::ProtobufEnum::value(&self.ordering))?; + } + if let Some(ref v) = self.counterparty.as_ref() { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + for v in &self.connection_hops { + os.write_string(4, &v)?; + }; + if !self.version.is_empty() { + os.write_string(5, &self.version)?; + } + if !self.port_id.is_empty() { + os.write_string(6, &self.port_id)?; + } + if !self.channel_id.is_empty() { + os.write_string(7, &self.channel_id)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> IdentifiedChannel { + IdentifiedChannel::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "state", + |m: &IdentifiedChannel| { &m.state }, + |m: &mut IdentifiedChannel| { &mut m.state }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "ordering", + |m: &IdentifiedChannel| { &m.ordering }, + |m: &mut IdentifiedChannel| { &mut m.ordering }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "counterparty", + |m: &IdentifiedChannel| { &m.counterparty }, + |m: &mut IdentifiedChannel| { &mut m.counterparty }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "connection_hops", + |m: &IdentifiedChannel| { &m.connection_hops }, + |m: &mut IdentifiedChannel| { &mut m.connection_hops }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "version", + |m: &IdentifiedChannel| { &m.version }, + |m: &mut IdentifiedChannel| { &mut m.version }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "port_id", + |m: &IdentifiedChannel| { &m.port_id }, + |m: &mut IdentifiedChannel| { &mut m.port_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "channel_id", + |m: &IdentifiedChannel| { &m.channel_id }, + |m: &mut IdentifiedChannel| { &mut m.channel_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "IdentifiedChannel", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static IdentifiedChannel { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(IdentifiedChannel::new) + } +} + +impl ::protobuf::Clear for IdentifiedChannel { + fn clear(&mut self) { + self.state = State::STATE_UNINITIALIZED_UNSPECIFIED; + self.ordering = Order::ORDER_NONE_UNSPECIFIED; + self.counterparty.clear(); + self.connection_hops.clear(); + self.version.clear(); + self.port_id.clear(); + self.channel_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for IdentifiedChannel { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for IdentifiedChannel { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct Counterparty { + // message fields + pub port_id: ::std::string::String, + pub channel_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Counterparty { + fn default() -> &'a Counterparty { + ::default_instance() + } +} + +impl Counterparty { + pub fn new() -> Counterparty { + ::std::default::Default::default() + } + + // string port_id = 1; + + + pub fn get_port_id(&self) -> &str { + &self.port_id + } + pub fn clear_port_id(&mut self) { + self.port_id.clear(); + } + + // Param is passed by value, moved + pub fn set_port_id(&mut self, v: ::std::string::String) { + self.port_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_port_id(&mut self) -> &mut ::std::string::String { + &mut self.port_id + } + + // Take field + pub fn take_port_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.port_id, ::std::string::String::new()) + } + + // string channel_id = 2; + + + pub fn get_channel_id(&self) -> &str { + &self.channel_id + } + pub fn clear_channel_id(&mut self) { + self.channel_id.clear(); + } + + // Param is passed by value, moved + pub fn set_channel_id(&mut self, v: ::std::string::String) { + self.channel_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_channel_id(&mut self) -> &mut ::std::string::String { + &mut self.channel_id + } + + // Take field + pub fn take_channel_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.channel_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for Counterparty { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.port_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.channel_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.port_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.port_id); + } + if !self.channel_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.channel_id); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.port_id.is_empty() { + os.write_string(1, &self.port_id)?; + } + if !self.channel_id.is_empty() { + os.write_string(2, &self.channel_id)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Counterparty { + Counterparty::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "port_id", + |m: &Counterparty| { &m.port_id }, + |m: &mut Counterparty| { &mut m.port_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "channel_id", + |m: &Counterparty| { &m.channel_id }, + |m: &mut Counterparty| { &mut m.channel_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Counterparty", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Counterparty { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Counterparty::new) + } +} + +impl ::protobuf::Clear for Counterparty { + fn clear(&mut self) { + self.port_id.clear(); + self.channel_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Counterparty { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Counterparty { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct Packet { + // message fields + pub sequence: u64, + pub source_port: ::std::string::String, + pub source_channel: ::std::string::String, + pub destination_port: ::std::string::String, + pub destination_channel: ::std::string::String, + pub data: ::std::vec::Vec, + pub timeout_height: ::protobuf::SingularPtrField, + pub timeout_timestamp: u64, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Packet { + fn default() -> &'a Packet { + ::default_instance() + } +} + +impl Packet { + pub fn new() -> Packet { + ::std::default::Default::default() + } + + // uint64 sequence = 1; + + + pub fn get_sequence(&self) -> u64 { + self.sequence + } + pub fn clear_sequence(&mut self) { + self.sequence = 0; + } + + // Param is passed by value, moved + pub fn set_sequence(&mut self, v: u64) { + self.sequence = v; + } + + // string source_port = 2; + + + pub fn get_source_port(&self) -> &str { + &self.source_port + } + pub fn clear_source_port(&mut self) { + self.source_port.clear(); + } + + // Param is passed by value, moved + pub fn set_source_port(&mut self, v: ::std::string::String) { + self.source_port = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_source_port(&mut self) -> &mut ::std::string::String { + &mut self.source_port + } + + // Take field + pub fn take_source_port(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.source_port, ::std::string::String::new()) + } + + // string source_channel = 3; + + + pub fn get_source_channel(&self) -> &str { + &self.source_channel + } + pub fn clear_source_channel(&mut self) { + self.source_channel.clear(); + } + + // Param is passed by value, moved + pub fn set_source_channel(&mut self, v: ::std::string::String) { + self.source_channel = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_source_channel(&mut self) -> &mut ::std::string::String { + &mut self.source_channel + } + + // Take field + pub fn take_source_channel(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.source_channel, ::std::string::String::new()) + } + + // string destination_port = 4; + + + pub fn get_destination_port(&self) -> &str { + &self.destination_port + } + pub fn clear_destination_port(&mut self) { + self.destination_port.clear(); + } + + // Param is passed by value, moved + pub fn set_destination_port(&mut self, v: ::std::string::String) { + self.destination_port = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_destination_port(&mut self) -> &mut ::std::string::String { + &mut self.destination_port + } + + // Take field + pub fn take_destination_port(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.destination_port, ::std::string::String::new()) + } + + // string destination_channel = 5; + + + pub fn get_destination_channel(&self) -> &str { + &self.destination_channel + } + pub fn clear_destination_channel(&mut self) { + self.destination_channel.clear(); + } + + // Param is passed by value, moved + pub fn set_destination_channel(&mut self, v: ::std::string::String) { + self.destination_channel = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_destination_channel(&mut self) -> &mut ::std::string::String { + &mut self.destination_channel + } + + // Take field + pub fn take_destination_channel(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.destination_channel, ::std::string::String::new()) + } + + // bytes data = 6; + + + pub fn get_data(&self) -> &[u8] { + &self.data + } + pub fn clear_data(&mut self) { + self.data.clear(); + } + + // Param is passed by value, moved + pub fn set_data(&mut self, v: ::std::vec::Vec) { + self.data = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_data(&mut self) -> &mut ::std::vec::Vec { + &mut self.data + } + + // Take field + pub fn take_data(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.data, ::std::vec::Vec::new()) + } + + // .ibc.core.client.v1.Height timeout_height = 7; + + + pub fn get_timeout_height(&self) -> &super::client::Height { + self.timeout_height.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_timeout_height(&mut self) { + self.timeout_height.clear(); + } + + pub fn has_timeout_height(&self) -> bool { + self.timeout_height.is_some() + } + + // Param is passed by value, moved + pub fn set_timeout_height(&mut self, v: super::client::Height) { + self.timeout_height = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_timeout_height(&mut self) -> &mut super::client::Height { + if self.timeout_height.is_none() { + self.timeout_height.set_default(); + } + self.timeout_height.as_mut().unwrap() + } + + // Take field + pub fn take_timeout_height(&mut self) -> super::client::Height { + self.timeout_height.take().unwrap_or_else(|| super::client::Height::new()) + } + + // uint64 timeout_timestamp = 8; + + + pub fn get_timeout_timestamp(&self) -> u64 { + self.timeout_timestamp + } + pub fn clear_timeout_timestamp(&mut self) { + self.timeout_timestamp = 0; + } + + // Param is passed by value, moved + pub fn set_timeout_timestamp(&mut self, v: u64) { + self.timeout_timestamp = v; + } +} + +impl ::protobuf::Message for Packet { + fn is_initialized(&self) -> bool { + for v in &self.timeout_height { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_uint64()?; + self.sequence = tmp; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.source_port)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.source_channel)?; + }, + 4 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.destination_port)?; + }, + 5 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.destination_channel)?; + }, + 6 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.data)?; + }, + 7 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.timeout_height)?; + }, + 8 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_uint64()?; + self.timeout_timestamp = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.sequence != 0 { + my_size += ::protobuf::rt::value_size(1, self.sequence, ::protobuf::wire_format::WireTypeVarint); + } + if !self.source_port.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.source_port); + } + if !self.source_channel.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.source_channel); + } + if !self.destination_port.is_empty() { + my_size += ::protobuf::rt::string_size(4, &self.destination_port); + } + if !self.destination_channel.is_empty() { + my_size += ::protobuf::rt::string_size(5, &self.destination_channel); + } + if !self.data.is_empty() { + my_size += ::protobuf::rt::bytes_size(6, &self.data); + } + if let Some(ref v) = self.timeout_height.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if self.timeout_timestamp != 0 { + my_size += ::protobuf::rt::value_size(8, self.timeout_timestamp, ::protobuf::wire_format::WireTypeVarint); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.sequence != 0 { + os.write_uint64(1, self.sequence)?; + } + if !self.source_port.is_empty() { + os.write_string(2, &self.source_port)?; + } + if !self.source_channel.is_empty() { + os.write_string(3, &self.source_channel)?; + } + if !self.destination_port.is_empty() { + os.write_string(4, &self.destination_port)?; + } + if !self.destination_channel.is_empty() { + os.write_string(5, &self.destination_channel)?; + } + if !self.data.is_empty() { + os.write_bytes(6, &self.data)?; + } + if let Some(ref v) = self.timeout_height.as_ref() { + os.write_tag(7, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if self.timeout_timestamp != 0 { + os.write_uint64(8, self.timeout_timestamp)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Packet { + Packet::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint64>( + "sequence", + |m: &Packet| { &m.sequence }, + |m: &mut Packet| { &mut m.sequence }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "source_port", + |m: &Packet| { &m.source_port }, + |m: &mut Packet| { &mut m.source_port }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "source_channel", + |m: &Packet| { &m.source_channel }, + |m: &mut Packet| { &mut m.source_channel }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "destination_port", + |m: &Packet| { &m.destination_port }, + |m: &mut Packet| { &mut m.destination_port }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "destination_channel", + |m: &Packet| { &m.destination_channel }, + |m: &mut Packet| { &mut m.destination_channel }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "data", + |m: &Packet| { &m.data }, + |m: &mut Packet| { &mut m.data }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "timeout_height", + |m: &Packet| { &m.timeout_height }, + |m: &mut Packet| { &mut m.timeout_height }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint64>( + "timeout_timestamp", + |m: &Packet| { &m.timeout_timestamp }, + |m: &mut Packet| { &mut m.timeout_timestamp }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Packet", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Packet { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Packet::new) + } +} + +impl ::protobuf::Clear for Packet { + fn clear(&mut self) { + self.sequence = 0; + self.source_port.clear(); + self.source_channel.clear(); + self.destination_port.clear(); + self.destination_channel.clear(); + self.data.clear(); + self.timeout_height.clear(); + self.timeout_timestamp = 0; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Packet { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Packet { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct PacketState { + // message fields + pub port_id: ::std::string::String, + pub channel_id: ::std::string::String, + pub sequence: u64, + pub data: ::std::vec::Vec, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a PacketState { + fn default() -> &'a PacketState { + ::default_instance() + } +} + +impl PacketState { + pub fn new() -> PacketState { + ::std::default::Default::default() + } + + // string port_id = 1; + + + pub fn get_port_id(&self) -> &str { + &self.port_id + } + pub fn clear_port_id(&mut self) { + self.port_id.clear(); + } + + // Param is passed by value, moved + pub fn set_port_id(&mut self, v: ::std::string::String) { + self.port_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_port_id(&mut self) -> &mut ::std::string::String { + &mut self.port_id + } + + // Take field + pub fn take_port_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.port_id, ::std::string::String::new()) + } + + // string channel_id = 2; + + + pub fn get_channel_id(&self) -> &str { + &self.channel_id + } + pub fn clear_channel_id(&mut self) { + self.channel_id.clear(); + } + + // Param is passed by value, moved + pub fn set_channel_id(&mut self, v: ::std::string::String) { + self.channel_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_channel_id(&mut self) -> &mut ::std::string::String { + &mut self.channel_id + } + + // Take field + pub fn take_channel_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.channel_id, ::std::string::String::new()) + } + + // uint64 sequence = 3; + + + pub fn get_sequence(&self) -> u64 { + self.sequence + } + pub fn clear_sequence(&mut self) { + self.sequence = 0; + } + + // Param is passed by value, moved + pub fn set_sequence(&mut self, v: u64) { + self.sequence = v; + } + + // bytes data = 4; + + + pub fn get_data(&self) -> &[u8] { + &self.data + } + pub fn clear_data(&mut self) { + self.data.clear(); + } + + // Param is passed by value, moved + pub fn set_data(&mut self, v: ::std::vec::Vec) { + self.data = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_data(&mut self) -> &mut ::std::vec::Vec { + &mut self.data + } + + // Take field + pub fn take_data(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.data, ::std::vec::Vec::new()) + } +} + +impl ::protobuf::Message for PacketState { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.port_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.channel_id)?; + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_uint64()?; + self.sequence = tmp; + }, + 4 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.data)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.port_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.port_id); + } + if !self.channel_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.channel_id); + } + if self.sequence != 0 { + my_size += ::protobuf::rt::value_size(3, self.sequence, ::protobuf::wire_format::WireTypeVarint); + } + if !self.data.is_empty() { + my_size += ::protobuf::rt::bytes_size(4, &self.data); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.port_id.is_empty() { + os.write_string(1, &self.port_id)?; + } + if !self.channel_id.is_empty() { + os.write_string(2, &self.channel_id)?; + } + if self.sequence != 0 { + os.write_uint64(3, self.sequence)?; + } + if !self.data.is_empty() { + os.write_bytes(4, &self.data)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> PacketState { + PacketState::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "port_id", + |m: &PacketState| { &m.port_id }, + |m: &mut PacketState| { &mut m.port_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "channel_id", + |m: &PacketState| { &m.channel_id }, + |m: &mut PacketState| { &mut m.channel_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint64>( + "sequence", + |m: &PacketState| { &m.sequence }, + |m: &mut PacketState| { &mut m.sequence }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "data", + |m: &PacketState| { &m.data }, + |m: &mut PacketState| { &mut m.data }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "PacketState", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static PacketState { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(PacketState::new) + } +} + +impl ::protobuf::Clear for PacketState { + fn clear(&mut self) { + self.port_id.clear(); + self.channel_id.clear(); + self.sequence = 0; + self.data.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for PacketState { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for PacketState { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct PacketId { + // message fields + pub port_id: ::std::string::String, + pub channel_id: ::std::string::String, + pub sequence: u64, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a PacketId { + fn default() -> &'a PacketId { + ::default_instance() + } +} + +impl PacketId { + pub fn new() -> PacketId { + ::std::default::Default::default() + } + + // string port_id = 1; + + + pub fn get_port_id(&self) -> &str { + &self.port_id + } + pub fn clear_port_id(&mut self) { + self.port_id.clear(); + } + + // Param is passed by value, moved + pub fn set_port_id(&mut self, v: ::std::string::String) { + self.port_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_port_id(&mut self) -> &mut ::std::string::String { + &mut self.port_id + } + + // Take field + pub fn take_port_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.port_id, ::std::string::String::new()) + } + + // string channel_id = 2; + + + pub fn get_channel_id(&self) -> &str { + &self.channel_id + } + pub fn clear_channel_id(&mut self) { + self.channel_id.clear(); + } + + // Param is passed by value, moved + pub fn set_channel_id(&mut self, v: ::std::string::String) { + self.channel_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_channel_id(&mut self) -> &mut ::std::string::String { + &mut self.channel_id + } + + // Take field + pub fn take_channel_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.channel_id, ::std::string::String::new()) + } + + // uint64 sequence = 3; + + + pub fn get_sequence(&self) -> u64 { + self.sequence + } + pub fn clear_sequence(&mut self) { + self.sequence = 0; + } + + // Param is passed by value, moved + pub fn set_sequence(&mut self, v: u64) { + self.sequence = v; + } +} + +impl ::protobuf::Message for PacketId { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.port_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.channel_id)?; + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_uint64()?; + self.sequence = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.port_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.port_id); + } + if !self.channel_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.channel_id); + } + if self.sequence != 0 { + my_size += ::protobuf::rt::value_size(3, self.sequence, ::protobuf::wire_format::WireTypeVarint); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.port_id.is_empty() { + os.write_string(1, &self.port_id)?; + } + if !self.channel_id.is_empty() { + os.write_string(2, &self.channel_id)?; + } + if self.sequence != 0 { + os.write_uint64(3, self.sequence)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> PacketId { + PacketId::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "port_id", + |m: &PacketId| { &m.port_id }, + |m: &mut PacketId| { &mut m.port_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "channel_id", + |m: &PacketId| { &m.channel_id }, + |m: &mut PacketId| { &mut m.channel_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint64>( + "sequence", + |m: &PacketId| { &m.sequence }, + |m: &mut PacketId| { &mut m.sequence }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "PacketId", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static PacketId { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(PacketId::new) + } +} + +impl ::protobuf::Clear for PacketId { + fn clear(&mut self) { + self.port_id.clear(); + self.channel_id.clear(); + self.sequence = 0; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for PacketId { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for PacketId { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct Acknowledgement { + // message oneof groups + pub response: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Acknowledgement { + fn default() -> &'a Acknowledgement { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum Acknowledgement_oneof_response { + result(::std::vec::Vec), + error(::std::string::String), +} + +impl Acknowledgement { + pub fn new() -> Acknowledgement { + ::std::default::Default::default() + } + + // bytes result = 21; + + + pub fn get_result(&self) -> &[u8] { + match self.response { + ::std::option::Option::Some(Acknowledgement_oneof_response::result(ref v)) => v, + _ => &[], + } + } + pub fn clear_result(&mut self) { + self.response = ::std::option::Option::None; + } + + pub fn has_result(&self) -> bool { + match self.response { + ::std::option::Option::Some(Acknowledgement_oneof_response::result(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_result(&mut self, v: ::std::vec::Vec) { + self.response = ::std::option::Option::Some(Acknowledgement_oneof_response::result(v)) + } + + // Mutable pointer to the field. + pub fn mut_result(&mut self) -> &mut ::std::vec::Vec { + if let ::std::option::Option::Some(Acknowledgement_oneof_response::result(_)) = self.response { + } else { + self.response = ::std::option::Option::Some(Acknowledgement_oneof_response::result(::std::vec::Vec::new())); + } + match self.response { + ::std::option::Option::Some(Acknowledgement_oneof_response::result(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_result(&mut self) -> ::std::vec::Vec { + if self.has_result() { + match self.response.take() { + ::std::option::Option::Some(Acknowledgement_oneof_response::result(v)) => v, + _ => panic!(), + } + } else { + ::std::vec::Vec::new() + } + } + + // string error = 22; + + + pub fn get_error(&self) -> &str { + match self.response { + ::std::option::Option::Some(Acknowledgement_oneof_response::error(ref v)) => v, + _ => "", + } + } + pub fn clear_error(&mut self) { + self.response = ::std::option::Option::None; + } + + pub fn has_error(&self) -> bool { + match self.response { + ::std::option::Option::Some(Acknowledgement_oneof_response::error(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_error(&mut self, v: ::std::string::String) { + self.response = ::std::option::Option::Some(Acknowledgement_oneof_response::error(v)) + } + + // Mutable pointer to the field. + pub fn mut_error(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(Acknowledgement_oneof_response::error(_)) = self.response { + } else { + self.response = ::std::option::Option::Some(Acknowledgement_oneof_response::error(::std::string::String::new())); + } + match self.response { + ::std::option::Option::Some(Acknowledgement_oneof_response::error(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_error(&mut self) -> ::std::string::String { + if self.has_error() { + match self.response.take() { + ::std::option::Option::Some(Acknowledgement_oneof_response::error(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } +} + +impl ::protobuf::Message for Acknowledgement { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 21 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.response = ::std::option::Option::Some(Acknowledgement_oneof_response::result(is.read_bytes()?)); + }, + 22 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.response = ::std::option::Option::Some(Acknowledgement_oneof_response::error(is.read_string()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let ::std::option::Option::Some(ref v) = self.response { + match v { + &Acknowledgement_oneof_response::result(ref v) => { + my_size += ::protobuf::rt::bytes_size(21, &v); + }, + &Acknowledgement_oneof_response::error(ref v) => { + my_size += ::protobuf::rt::string_size(22, &v); + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if let ::std::option::Option::Some(ref v) = self.response { + match v { + &Acknowledgement_oneof_response::result(ref v) => { + os.write_bytes(21, v)?; + }, + &Acknowledgement_oneof_response::error(ref v) => { + os.write_string(22, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Acknowledgement { + Acknowledgement::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_bytes_accessor::<_>( + "result", + Acknowledgement::has_result, + Acknowledgement::get_result, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "error", + Acknowledgement::has_error, + Acknowledgement::get_error, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Acknowledgement", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Acknowledgement { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Acknowledgement::new) + } +} + +impl ::protobuf::Clear for Acknowledgement { + fn clear(&mut self) { + self.response = ::std::option::Option::None; + self.response = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Acknowledgement { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Acknowledgement { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum State { + STATE_UNINITIALIZED_UNSPECIFIED = 0, + STATE_INIT = 1, + STATE_TRYOPEN = 2, + STATE_OPEN = 3, + STATE_CLOSED = 4, +} + +impl ::protobuf::ProtobufEnum for State { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(State::STATE_UNINITIALIZED_UNSPECIFIED), + 1 => ::std::option::Option::Some(State::STATE_INIT), + 2 => ::std::option::Option::Some(State::STATE_TRYOPEN), + 3 => ::std::option::Option::Some(State::STATE_OPEN), + 4 => ::std::option::Option::Some(State::STATE_CLOSED), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [State] = &[ + State::STATE_UNINITIALIZED_UNSPECIFIED, + State::STATE_INIT, + State::STATE_TRYOPEN, + State::STATE_OPEN, + State::STATE_CLOSED, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("State", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for State { +} + +impl ::std::default::Default for State { + fn default() -> Self { + State::STATE_UNINITIALIZED_UNSPECIFIED + } +} + +impl ::protobuf::reflect::ProtobufValue for State { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum Order { + ORDER_NONE_UNSPECIFIED = 0, + ORDER_UNORDERED = 1, + ORDER_ORDERED = 2, +} + +impl ::protobuf::ProtobufEnum for Order { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(Order::ORDER_NONE_UNSPECIFIED), + 1 => ::std::option::Option::Some(Order::ORDER_UNORDERED), + 2 => ::std::option::Option::Some(Order::ORDER_ORDERED), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [Order] = &[ + Order::ORDER_NONE_UNSPECIFIED, + Order::ORDER_UNORDERED, + Order::ORDER_ORDERED, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("Order", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for Order { +} + +impl ::std::default::Default for Order { + fn default() -> Self { + Order::ORDER_NONE_UNSPECIFIED + } +} + +impl ::protobuf::reflect::ProtobufValue for Order { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n!ibc/core/channel/v1/channel.proto\x12\x13ibc.core.channel.v1\x1a\x14g\ + ogoproto/gogo.proto\x1a\x1fibc/core/client/v1/client.proto\"\xa5\x02\n\ + \x07Channel\x120\n\x05state\x18\x01\x20\x01(\x0e2\x1a.ibc.core.channel.v\ + 1.StateR\x05state\x126\n\x08ordering\x18\x02\x20\x01(\x0e2\x1a.ibc.core.\ + channel.v1.OrderR\x08ordering\x12K\n\x0ccounterparty\x18\x03\x20\x01(\ + \x0b2!.ibc.core.channel.v1.CounterpartyR\x0ccounterpartyB\x04\xc8\xde\ + \x1f\0\x12C\n\x0fconnection_hops\x18\x04\x20\x03(\tR\x0econnectionHopsB\ + \x1a\xf2\xde\x1f\x16yaml:\"connection_hops\"\x12\x18\n\x07version\x18\ + \x05\x20\x01(\tR\x07version:\x04\x88\xa0\x1f\0\"\xe7\x02\n\x11Identified\ + Channel\x120\n\x05state\x18\x01\x20\x01(\x0e2\x1a.ibc.core.channel.v1.St\ + ateR\x05state\x126\n\x08ordering\x18\x02\x20\x01(\x0e2\x1a.ibc.core.chan\ + nel.v1.OrderR\x08ordering\x12K\n\x0ccounterparty\x18\x03\x20\x01(\x0b2!.\ + ibc.core.channel.v1.CounterpartyR\x0ccounterpartyB\x04\xc8\xde\x1f\0\x12\ + C\n\x0fconnection_hops\x18\x04\x20\x03(\tR\x0econnectionHopsB\x1a\xf2\ + \xde\x1f\x16yaml:\"connection_hops\"\x12\x18\n\x07version\x18\x05\x20\ + \x01(\tR\x07version\x12\x17\n\x07port_id\x18\x06\x20\x01(\tR\x06portId\ + \x12\x1d\n\nchannel_id\x18\x07\x20\x01(\tR\tchannelId:\x04\x88\xa0\x1f\0\ + \"w\n\x0cCounterparty\x12+\n\x07port_id\x18\x01\x20\x01(\tR\x06portIdB\ + \x12\xf2\xde\x1f\x0eyaml:\"port_id\"\x124\n\nchannel_id\x18\x02\x20\x01(\ + \tR\tchannelIdB\x15\xf2\xde\x1f\x11yaml:\"channel_id\":\x04\x88\xa0\x1f\ + \0\"\xff\x03\n\x06Packet\x12\x1a\n\x08sequence\x18\x01\x20\x01(\x04R\x08\ + sequence\x127\n\x0bsource_port\x18\x02\x20\x01(\tR\nsourcePortB\x16\xf2\ + \xde\x1f\x12yaml:\"source_port\"\x12@\n\x0esource_channel\x18\x03\x20\ + \x01(\tR\rsourceChannelB\x19\xf2\xde\x1f\x15yaml:\"source_channel\"\x12F\ + \n\x10destination_port\x18\x04\x20\x01(\tR\x0fdestinationPortB\x1b\xf2\ + \xde\x1f\x17yaml:\"destination_port\"\x12O\n\x13destination_channel\x18\ + \x05\x20\x01(\tR\x12destinationChannelB\x1e\xf2\xde\x1f\x1ayaml:\"destin\ + ation_channel\"\x12\x12\n\x04data\x18\x06\x20\x01(\x0cR\x04data\x12`\n\ + \x0etimeout_height\x18\x07\x20\x01(\x0b2\x1a.ibc.core.client.v1.HeightR\ + \rtimeoutHeightB\x1d\xf2\xde\x1f\x15yaml:\"timeout_height\"\xc8\xde\x1f\ + \0\x12I\n\x11timeout_timestamp\x18\x08\x20\x01(\x04R\x10timeoutTimestamp\ + B\x1c\xf2\xde\x1f\x18yaml:\"timeout_timestamp\":\x04\x88\xa0\x1f\0\"\xa6\ + \x01\n\x0bPacketState\x12+\n\x07port_id\x18\x01\x20\x01(\tR\x06portIdB\ + \x12\xf2\xde\x1f\x0eyaml:\"port_id\"\x124\n\nchannel_id\x18\x02\x20\x01(\ + \tR\tchannelIdB\x15\xf2\xde\x1f\x11yaml:\"channel_id\"\x12\x1a\n\x08sequ\ + ence\x18\x03\x20\x01(\x04R\x08sequence\x12\x12\n\x04data\x18\x04\x20\x01\ + (\x0cR\x04data:\x04\x88\xa0\x1f\0\"\x8f\x01\n\x08PacketId\x12+\n\x07port\ + _id\x18\x01\x20\x01(\tR\x06portIdB\x12\xf2\xde\x1f\x0eyaml:\"port_id\"\ + \x124\n\nchannel_id\x18\x02\x20\x01(\tR\tchannelIdB\x15\xf2\xde\x1f\x11y\ + aml:\"channel_id\"\x12\x1a\n\x08sequence\x18\x03\x20\x01(\x04R\x08sequen\ + ce:\x04\x88\xa0\x1f\0\"O\n\x0fAcknowledgement\x12\x18\n\x06result\x18\ + \x15\x20\x01(\x0cH\0R\x06result\x12\x16\n\x05error\x18\x16\x20\x01(\tH\0\ + R\x05errorB\n\n\x08response*\xb7\x01\n\x05State\x126\n\x1fSTATE_UNINITIA\ + LIZED_UNSPECIFIED\x10\0\x1a\x11\x8a\x9d\x20\rUNINITIALIZED\x12\x18\n\nST\ + ATE_INIT\x10\x01\x1a\x08\x8a\x9d\x20\x04INIT\x12\x1e\n\rSTATE_TRYOPEN\ + \x10\x02\x1a\x0b\x8a\x9d\x20\x07TRYOPEN\x12\x18\n\nSTATE_OPEN\x10\x03\ + \x1a\x08\x8a\x9d\x20\x04OPEN\x12\x1c\n\x0cSTATE_CLOSED\x10\x04\x1a\n\x8a\ + \x9d\x20\x06CLOSED\x1a\x04\x88\xa3\x1e\0*w\n\x05Order\x12$\n\x16ORDER_NO\ + NE_UNSPECIFIED\x10\0\x1a\x08\x8a\x9d\x20\x04NONE\x12\"\n\x0fORDER_UNORDE\ + RED\x10\x01\x1a\r\x8a\x9d\x20\tUNORDERED\x12\x1e\n\rORDER_ORDERED\x10\ + \x02\x1a\x0b\x8a\x9d\x20\x07ORDERED\x1a\x04\x88\xa3\x1e\0B;Z9github.com/\ + cosmos/ibc-go/v4/modules/core/04-channel/typesb\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/cosmwasm/enclaves/shared/cosmos-proto/src/ibc/client.rs b/cosmwasm/enclaves/shared/cosmos-proto/src/ibc/client.rs new file mode 100644 index 000000000..5ef049f36 --- /dev/null +++ b/cosmwasm/enclaves/shared/cosmos-proto/src/ibc/client.rs @@ -0,0 +1,1673 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `ibc/core/client/v1/client.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct IdentifiedClientState { + // message fields + pub client_id: ::std::string::String, + pub client_state: ::protobuf::SingularPtrField<::protobuf::well_known_types::Any>, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a IdentifiedClientState { + fn default() -> &'a IdentifiedClientState { + ::default_instance() + } +} + +impl IdentifiedClientState { + pub fn new() -> IdentifiedClientState { + ::std::default::Default::default() + } + + // string client_id = 1; + + + pub fn get_client_id(&self) -> &str { + &self.client_id + } + pub fn clear_client_id(&mut self) { + self.client_id.clear(); + } + + // Param is passed by value, moved + pub fn set_client_id(&mut self, v: ::std::string::String) { + self.client_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_client_id(&mut self) -> &mut ::std::string::String { + &mut self.client_id + } + + // Take field + pub fn take_client_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.client_id, ::std::string::String::new()) + } + + // .google.protobuf.Any client_state = 2; + + + pub fn get_client_state(&self) -> &::protobuf::well_known_types::Any { + self.client_state.as_ref().unwrap_or_else(|| <::protobuf::well_known_types::Any as ::protobuf::Message>::default_instance()) + } + pub fn clear_client_state(&mut self) { + self.client_state.clear(); + } + + pub fn has_client_state(&self) -> bool { + self.client_state.is_some() + } + + // Param is passed by value, moved + pub fn set_client_state(&mut self, v: ::protobuf::well_known_types::Any) { + self.client_state = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_client_state(&mut self) -> &mut ::protobuf::well_known_types::Any { + if self.client_state.is_none() { + self.client_state.set_default(); + } + self.client_state.as_mut().unwrap() + } + + // Take field + pub fn take_client_state(&mut self) -> ::protobuf::well_known_types::Any { + self.client_state.take().unwrap_or_else(|| ::protobuf::well_known_types::Any::new()) + } +} + +impl ::protobuf::Message for IdentifiedClientState { + fn is_initialized(&self) -> bool { + for v in &self.client_state { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.client_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.client_state)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.client_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.client_id); + } + if let Some(ref v) = self.client_state.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.client_id.is_empty() { + os.write_string(1, &self.client_id)?; + } + if let Some(ref v) = self.client_state.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> IdentifiedClientState { + IdentifiedClientState::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "client_id", + |m: &IdentifiedClientState| { &m.client_id }, + |m: &mut IdentifiedClientState| { &mut m.client_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<::protobuf::well_known_types::Any>>( + "client_state", + |m: &IdentifiedClientState| { &m.client_state }, + |m: &mut IdentifiedClientState| { &mut m.client_state }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "IdentifiedClientState", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static IdentifiedClientState { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(IdentifiedClientState::new) + } +} + +impl ::protobuf::Clear for IdentifiedClientState { + fn clear(&mut self) { + self.client_id.clear(); + self.client_state.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for IdentifiedClientState { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for IdentifiedClientState { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct ConsensusStateWithHeight { + // message fields + pub height: ::protobuf::SingularPtrField, + pub consensus_state: ::protobuf::SingularPtrField<::protobuf::well_known_types::Any>, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a ConsensusStateWithHeight { + fn default() -> &'a ConsensusStateWithHeight { + ::default_instance() + } +} + +impl ConsensusStateWithHeight { + pub fn new() -> ConsensusStateWithHeight { + ::std::default::Default::default() + } + + // .ibc.core.client.v1.Height height = 1; + + + pub fn get_height(&self) -> &Height { + self.height.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_height(&mut self) { + self.height.clear(); + } + + pub fn has_height(&self) -> bool { + self.height.is_some() + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: Height) { + self.height = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_height(&mut self) -> &mut Height { + if self.height.is_none() { + self.height.set_default(); + } + self.height.as_mut().unwrap() + } + + // Take field + pub fn take_height(&mut self) -> Height { + self.height.take().unwrap_or_else(|| Height::new()) + } + + // .google.protobuf.Any consensus_state = 2; + + + pub fn get_consensus_state(&self) -> &::protobuf::well_known_types::Any { + self.consensus_state.as_ref().unwrap_or_else(|| <::protobuf::well_known_types::Any as ::protobuf::Message>::default_instance()) + } + pub fn clear_consensus_state(&mut self) { + self.consensus_state.clear(); + } + + pub fn has_consensus_state(&self) -> bool { + self.consensus_state.is_some() + } + + // Param is passed by value, moved + pub fn set_consensus_state(&mut self, v: ::protobuf::well_known_types::Any) { + self.consensus_state = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_consensus_state(&mut self) -> &mut ::protobuf::well_known_types::Any { + if self.consensus_state.is_none() { + self.consensus_state.set_default(); + } + self.consensus_state.as_mut().unwrap() + } + + // Take field + pub fn take_consensus_state(&mut self) -> ::protobuf::well_known_types::Any { + self.consensus_state.take().unwrap_or_else(|| ::protobuf::well_known_types::Any::new()) + } +} + +impl ::protobuf::Message for ConsensusStateWithHeight { + fn is_initialized(&self) -> bool { + for v in &self.height { + if !v.is_initialized() { + return false; + } + }; + for v in &self.consensus_state { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.height)?; + }, + 2 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.consensus_state)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.height.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let Some(ref v) = self.consensus_state.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if let Some(ref v) = self.height.as_ref() { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if let Some(ref v) = self.consensus_state.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> ConsensusStateWithHeight { + ConsensusStateWithHeight::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "height", + |m: &ConsensusStateWithHeight| { &m.height }, + |m: &mut ConsensusStateWithHeight| { &mut m.height }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<::protobuf::well_known_types::Any>>( + "consensus_state", + |m: &ConsensusStateWithHeight| { &m.consensus_state }, + |m: &mut ConsensusStateWithHeight| { &mut m.consensus_state }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ConsensusStateWithHeight", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static ConsensusStateWithHeight { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ConsensusStateWithHeight::new) + } +} + +impl ::protobuf::Clear for ConsensusStateWithHeight { + fn clear(&mut self) { + self.height.clear(); + self.consensus_state.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for ConsensusStateWithHeight { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ConsensusStateWithHeight { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct ClientConsensusStates { + // message fields + pub client_id: ::std::string::String, + pub consensus_states: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a ClientConsensusStates { + fn default() -> &'a ClientConsensusStates { + ::default_instance() + } +} + +impl ClientConsensusStates { + pub fn new() -> ClientConsensusStates { + ::std::default::Default::default() + } + + // string client_id = 1; + + + pub fn get_client_id(&self) -> &str { + &self.client_id + } + pub fn clear_client_id(&mut self) { + self.client_id.clear(); + } + + // Param is passed by value, moved + pub fn set_client_id(&mut self, v: ::std::string::String) { + self.client_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_client_id(&mut self) -> &mut ::std::string::String { + &mut self.client_id + } + + // Take field + pub fn take_client_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.client_id, ::std::string::String::new()) + } + + // repeated .ibc.core.client.v1.ConsensusStateWithHeight consensus_states = 2; + + + pub fn get_consensus_states(&self) -> &[ConsensusStateWithHeight] { + &self.consensus_states + } + pub fn clear_consensus_states(&mut self) { + self.consensus_states.clear(); + } + + // Param is passed by value, moved + pub fn set_consensus_states(&mut self, v: ::protobuf::RepeatedField) { + self.consensus_states = v; + } + + // Mutable pointer to the field. + pub fn mut_consensus_states(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.consensus_states + } + + // Take field + pub fn take_consensus_states(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.consensus_states, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for ClientConsensusStates { + fn is_initialized(&self) -> bool { + for v in &self.consensus_states { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.client_id)?; + }, + 2 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.consensus_states)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.client_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.client_id); + } + for value in &self.consensus_states { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.client_id.is_empty() { + os.write_string(1, &self.client_id)?; + } + for v in &self.consensus_states { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> ClientConsensusStates { + ClientConsensusStates::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "client_id", + |m: &ClientConsensusStates| { &m.client_id }, + |m: &mut ClientConsensusStates| { &mut m.client_id }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "consensus_states", + |m: &ClientConsensusStates| { &m.consensus_states }, + |m: &mut ClientConsensusStates| { &mut m.consensus_states }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ClientConsensusStates", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static ClientConsensusStates { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ClientConsensusStates::new) + } +} + +impl ::protobuf::Clear for ClientConsensusStates { + fn clear(&mut self) { + self.client_id.clear(); + self.consensus_states.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for ClientConsensusStates { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ClientConsensusStates { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct ClientUpdateProposal { + // message fields + pub title: ::std::string::String, + pub description: ::std::string::String, + pub subject_client_id: ::std::string::String, + pub substitute_client_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a ClientUpdateProposal { + fn default() -> &'a ClientUpdateProposal { + ::default_instance() + } +} + +impl ClientUpdateProposal { + pub fn new() -> ClientUpdateProposal { + ::std::default::Default::default() + } + + // string title = 1; + + + pub fn get_title(&self) -> &str { + &self.title + } + pub fn clear_title(&mut self) { + self.title.clear(); + } + + // Param is passed by value, moved + pub fn set_title(&mut self, v: ::std::string::String) { + self.title = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_title(&mut self) -> &mut ::std::string::String { + &mut self.title + } + + // Take field + pub fn take_title(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.title, ::std::string::String::new()) + } + + // string description = 2; + + + pub fn get_description(&self) -> &str { + &self.description + } + pub fn clear_description(&mut self) { + self.description.clear(); + } + + // Param is passed by value, moved + pub fn set_description(&mut self, v: ::std::string::String) { + self.description = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_description(&mut self) -> &mut ::std::string::String { + &mut self.description + } + + // Take field + pub fn take_description(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.description, ::std::string::String::new()) + } + + // string subject_client_id = 3; + + + pub fn get_subject_client_id(&self) -> &str { + &self.subject_client_id + } + pub fn clear_subject_client_id(&mut self) { + self.subject_client_id.clear(); + } + + // Param is passed by value, moved + pub fn set_subject_client_id(&mut self, v: ::std::string::String) { + self.subject_client_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_subject_client_id(&mut self) -> &mut ::std::string::String { + &mut self.subject_client_id + } + + // Take field + pub fn take_subject_client_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.subject_client_id, ::std::string::String::new()) + } + + // string substitute_client_id = 4; + + + pub fn get_substitute_client_id(&self) -> &str { + &self.substitute_client_id + } + pub fn clear_substitute_client_id(&mut self) { + self.substitute_client_id.clear(); + } + + // Param is passed by value, moved + pub fn set_substitute_client_id(&mut self, v: ::std::string::String) { + self.substitute_client_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_substitute_client_id(&mut self) -> &mut ::std::string::String { + &mut self.substitute_client_id + } + + // Take field + pub fn take_substitute_client_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.substitute_client_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for ClientUpdateProposal { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.title)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.description)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.subject_client_id)?; + }, + 4 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.substitute_client_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.title.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.title); + } + if !self.description.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.description); + } + if !self.subject_client_id.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.subject_client_id); + } + if !self.substitute_client_id.is_empty() { + my_size += ::protobuf::rt::string_size(4, &self.substitute_client_id); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.title.is_empty() { + os.write_string(1, &self.title)?; + } + if !self.description.is_empty() { + os.write_string(2, &self.description)?; + } + if !self.subject_client_id.is_empty() { + os.write_string(3, &self.subject_client_id)?; + } + if !self.substitute_client_id.is_empty() { + os.write_string(4, &self.substitute_client_id)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> ClientUpdateProposal { + ClientUpdateProposal::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "title", + |m: &ClientUpdateProposal| { &m.title }, + |m: &mut ClientUpdateProposal| { &mut m.title }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "description", + |m: &ClientUpdateProposal| { &m.description }, + |m: &mut ClientUpdateProposal| { &mut m.description }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "subject_client_id", + |m: &ClientUpdateProposal| { &m.subject_client_id }, + |m: &mut ClientUpdateProposal| { &mut m.subject_client_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "substitute_client_id", + |m: &ClientUpdateProposal| { &m.substitute_client_id }, + |m: &mut ClientUpdateProposal| { &mut m.substitute_client_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ClientUpdateProposal", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static ClientUpdateProposal { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ClientUpdateProposal::new) + } +} + +impl ::protobuf::Clear for ClientUpdateProposal { + fn clear(&mut self) { + self.title.clear(); + self.description.clear(); + self.subject_client_id.clear(); + self.substitute_client_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for ClientUpdateProposal { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ClientUpdateProposal { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct UpgradeProposal { + // message fields + pub title: ::std::string::String, + pub description: ::std::string::String, + pub plan: ::protobuf::SingularPtrField, + pub upgraded_client_state: ::protobuf::SingularPtrField<::protobuf::well_known_types::Any>, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a UpgradeProposal { + fn default() -> &'a UpgradeProposal { + ::default_instance() + } +} + +impl UpgradeProposal { + pub fn new() -> UpgradeProposal { + ::std::default::Default::default() + } + + // string title = 1; + + + pub fn get_title(&self) -> &str { + &self.title + } + pub fn clear_title(&mut self) { + self.title.clear(); + } + + // Param is passed by value, moved + pub fn set_title(&mut self, v: ::std::string::String) { + self.title = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_title(&mut self) -> &mut ::std::string::String { + &mut self.title + } + + // Take field + pub fn take_title(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.title, ::std::string::String::new()) + } + + // string description = 2; + + + pub fn get_description(&self) -> &str { + &self.description + } + pub fn clear_description(&mut self) { + self.description.clear(); + } + + // Param is passed by value, moved + pub fn set_description(&mut self, v: ::std::string::String) { + self.description = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_description(&mut self) -> &mut ::std::string::String { + &mut self.description + } + + // Take field + pub fn take_description(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.description, ::std::string::String::new()) + } + + // .cosmos.upgrade.v1beta1.Plan plan = 3; + + + pub fn get_plan(&self) -> &super::upgrade::Plan { + self.plan.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_plan(&mut self) { + self.plan.clear(); + } + + pub fn has_plan(&self) -> bool { + self.plan.is_some() + } + + // Param is passed by value, moved + pub fn set_plan(&mut self, v: super::upgrade::Plan) { + self.plan = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_plan(&mut self) -> &mut super::upgrade::Plan { + if self.plan.is_none() { + self.plan.set_default(); + } + self.plan.as_mut().unwrap() + } + + // Take field + pub fn take_plan(&mut self) -> super::upgrade::Plan { + self.plan.take().unwrap_or_else(|| super::upgrade::Plan::new()) + } + + // .google.protobuf.Any upgraded_client_state = 4; + + + pub fn get_upgraded_client_state(&self) -> &::protobuf::well_known_types::Any { + self.upgraded_client_state.as_ref().unwrap_or_else(|| <::protobuf::well_known_types::Any as ::protobuf::Message>::default_instance()) + } + pub fn clear_upgraded_client_state(&mut self) { + self.upgraded_client_state.clear(); + } + + pub fn has_upgraded_client_state(&self) -> bool { + self.upgraded_client_state.is_some() + } + + // Param is passed by value, moved + pub fn set_upgraded_client_state(&mut self, v: ::protobuf::well_known_types::Any) { + self.upgraded_client_state = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_upgraded_client_state(&mut self) -> &mut ::protobuf::well_known_types::Any { + if self.upgraded_client_state.is_none() { + self.upgraded_client_state.set_default(); + } + self.upgraded_client_state.as_mut().unwrap() + } + + // Take field + pub fn take_upgraded_client_state(&mut self) -> ::protobuf::well_known_types::Any { + self.upgraded_client_state.take().unwrap_or_else(|| ::protobuf::well_known_types::Any::new()) + } +} + +impl ::protobuf::Message for UpgradeProposal { + fn is_initialized(&self) -> bool { + for v in &self.plan { + if !v.is_initialized() { + return false; + } + }; + for v in &self.upgraded_client_state { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.title)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.description)?; + }, + 3 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.plan)?; + }, + 4 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.upgraded_client_state)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.title.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.title); + } + if !self.description.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.description); + } + if let Some(ref v) = self.plan.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let Some(ref v) = self.upgraded_client_state.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.title.is_empty() { + os.write_string(1, &self.title)?; + } + if !self.description.is_empty() { + os.write_string(2, &self.description)?; + } + if let Some(ref v) = self.plan.as_ref() { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if let Some(ref v) = self.upgraded_client_state.as_ref() { + os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> UpgradeProposal { + UpgradeProposal::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "title", + |m: &UpgradeProposal| { &m.title }, + |m: &mut UpgradeProposal| { &mut m.title }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "description", + |m: &UpgradeProposal| { &m.description }, + |m: &mut UpgradeProposal| { &mut m.description }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "plan", + |m: &UpgradeProposal| { &m.plan }, + |m: &mut UpgradeProposal| { &mut m.plan }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<::protobuf::well_known_types::Any>>( + "upgraded_client_state", + |m: &UpgradeProposal| { &m.upgraded_client_state }, + |m: &mut UpgradeProposal| { &mut m.upgraded_client_state }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "UpgradeProposal", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static UpgradeProposal { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(UpgradeProposal::new) + } +} + +impl ::protobuf::Clear for UpgradeProposal { + fn clear(&mut self) { + self.title.clear(); + self.description.clear(); + self.plan.clear(); + self.upgraded_client_state.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for UpgradeProposal { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for UpgradeProposal { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct Height { + // message fields + pub revision_number: u64, + pub revision_height: u64, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Height { + fn default() -> &'a Height { + ::default_instance() + } +} + +impl Height { + pub fn new() -> Height { + ::std::default::Default::default() + } + + // uint64 revision_number = 1; + + + pub fn get_revision_number(&self) -> u64 { + self.revision_number + } + pub fn clear_revision_number(&mut self) { + self.revision_number = 0; + } + + // Param is passed by value, moved + pub fn set_revision_number(&mut self, v: u64) { + self.revision_number = v; + } + + // uint64 revision_height = 2; + + + pub fn get_revision_height(&self) -> u64 { + self.revision_height + } + pub fn clear_revision_height(&mut self) { + self.revision_height = 0; + } + + // Param is passed by value, moved + pub fn set_revision_height(&mut self, v: u64) { + self.revision_height = v; + } +} + +impl ::protobuf::Message for Height { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_uint64()?; + self.revision_number = tmp; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_uint64()?; + self.revision_height = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.revision_number != 0 { + my_size += ::protobuf::rt::value_size(1, self.revision_number, ::protobuf::wire_format::WireTypeVarint); + } + if self.revision_height != 0 { + my_size += ::protobuf::rt::value_size(2, self.revision_height, ::protobuf::wire_format::WireTypeVarint); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.revision_number != 0 { + os.write_uint64(1, self.revision_number)?; + } + if self.revision_height != 0 { + os.write_uint64(2, self.revision_height)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Height { + Height::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint64>( + "revision_number", + |m: &Height| { &m.revision_number }, + |m: &mut Height| { &mut m.revision_number }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint64>( + "revision_height", + |m: &Height| { &m.revision_height }, + |m: &mut Height| { &mut m.revision_height }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Height", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Height { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Height::new) + } +} + +impl ::protobuf::Clear for Height { + fn clear(&mut self) { + self.revision_number = 0; + self.revision_height = 0; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Height { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Height { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct Params { + // message fields + pub allowed_clients: ::protobuf::RepeatedField<::std::string::String>, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Params { + fn default() -> &'a Params { + ::default_instance() + } +} + +impl Params { + pub fn new() -> Params { + ::std::default::Default::default() + } + + // repeated string allowed_clients = 1; + + + pub fn get_allowed_clients(&self) -> &[::std::string::String] { + &self.allowed_clients + } + pub fn clear_allowed_clients(&mut self) { + self.allowed_clients.clear(); + } + + // Param is passed by value, moved + pub fn set_allowed_clients(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) { + self.allowed_clients = v; + } + + // Mutable pointer to the field. + pub fn mut_allowed_clients(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> { + &mut self.allowed_clients + } + + // Take field + pub fn take_allowed_clients(&mut self) -> ::protobuf::RepeatedField<::std::string::String> { + ::std::mem::replace(&mut self.allowed_clients, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for Params { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.allowed_clients)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.allowed_clients { + my_size += ::protobuf::rt::string_size(1, &value); + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.allowed_clients { + os.write_string(1, &v)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Params { + Params::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "allowed_clients", + |m: &Params| { &m.allowed_clients }, + |m: &mut Params| { &mut m.allowed_clients }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Params", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Params { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Params::new) + } +} + +impl ::protobuf::Clear for Params { + fn clear(&mut self) { + self.allowed_clients.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Params { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Params { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x1fibc/core/client/v1/client.proto\x12\x12ibc.core.client.v1\x1a\x14g\ + ogoproto/gogo.proto\x1a\x19google/protobuf/any.proto\x1a$cosmos/upgrade/\ + v1beta1/upgrade.proto\x1a\x19cosmos_proto/cosmos.proto\"\x9c\x01\n\x15Id\ + entifiedClientState\x121\n\tclient_id\x18\x01\x20\x01(\tR\x08clientIdB\ + \x14\xf2\xde\x1f\x10yaml:\"client_id\"\x12P\n\x0cclient_state\x18\x02\ + \x20\x01(\x0b2\x14.google.protobuf.AnyR\x0bclientStateB\x17\xf2\xde\x1f\ + \x13yaml:\"client_state\"\"\xaf\x01\n\x18ConsensusStateWithHeight\x128\n\ + \x06height\x18\x01\x20\x01(\x0b2\x1a.ibc.core.client.v1.HeightR\x06heigh\ + tB\x04\xc8\xde\x1f\0\x12Y\n\x0fconsensus_state\x18\x02\x20\x01(\x0b2\x14\ + .google.protobuf.AnyR\x0econsensusStateB\x1a\xf2\xde\x1f\x16yaml:\"conse\ + nsus_state\"\"\xc4\x01\n\x15ClientConsensusStates\x121\n\tclient_id\x18\ + \x01\x20\x01(\tR\x08clientIdB\x14\xf2\xde\x1f\x10yaml:\"client_id\"\x12x\ + \n\x10consensus_states\x18\x02\x20\x03(\x0b2,.ibc.core.client.v1.Consens\ + usStateWithHeightR\x0fconsensusStatesB\x1f\xf2\xde\x1f\x17yaml:\"consens\ + us_states\"\xc8\xde\x1f\0\"\x8f\x02\n\x14ClientUpdateProposal\x12\x14\n\ + \x05title\x18\x01\x20\x01(\tR\x05title\x12\x20\n\x0bdescription\x18\x02\ + \x20\x01(\tR\x0bdescription\x12H\n\x11subject_client_id\x18\x03\x20\x01(\ + \tR\x0fsubjectClientIdB\x1c\xf2\xde\x1f\x18yaml:\"subject_client_id\"\ + \x12Q\n\x14substitute_client_id\x18\x04\x20\x01(\tR\x12substituteClientI\ + dB\x1f\xf2\xde\x1f\x1byaml:\"substitute_client_id\":\"\xd2\xb4-\x1acosmo\ + s.gov.v1beta1.Content\x88\xa0\x1f\0\"\x99\x02\n\x0fUpgradeProposal\x12\ + \x14\n\x05title\x18\x01\x20\x01(\tR\x05title\x12\x20\n\x0bdescription\ + \x18\x02\x20\x01(\tR\x0bdescription\x126\n\x04plan\x18\x03\x20\x01(\x0b2\ + \x1c.cosmos.upgrade.v1beta1.PlanR\x04planB\x04\xc8\xde\x1f\0\x12j\n\x15u\ + pgraded_client_state\x18\x04\x20\x01(\x0b2\x14.google.protobuf.AnyR\x13u\ + pgradedClientStateB\x20\xf2\xde\x1f\x1cyaml:\"upgraded_client_state\":*\ + \xd2\xb4-\x1acosmos.gov.v1beta1.Content\xe8\xa0\x1f\x01\x88\xa0\x1f\0\ + \x98\xa0\x1f\0\"\x9c\x01\n\x06Height\x12C\n\x0frevision_number\x18\x01\ + \x20\x01(\x04R\x0erevisionNumberB\x1a\xf2\xde\x1f\x16yaml:\"revision_num\ + ber\"\x12C\n\x0frevision_height\x18\x02\x20\x01(\x04R\x0erevisionHeightB\ + \x1a\xf2\xde\x1f\x16yaml:\"revision_height\":\x08\x88\xa0\x1f\0\x98\xa0\ + \x1f\0\"M\n\x06Params\x12C\n\x0fallowed_clients\x18\x01\x20\x03(\tR\x0ea\ + llowedClientsB\x1a\xf2\xde\x1f\x16yaml:\"allowed_clients\"B:Z8github.com\ + /cosmos/ibc-go/v4/modules/core/02-client/typesb\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/cosmwasm/enclaves/shared/cosmos-proto/src/ibc/tx.rs b/cosmwasm/enclaves/shared/cosmos-proto/src/ibc/tx.rs new file mode 100644 index 000000000..6ed967706 --- /dev/null +++ b/cosmwasm/enclaves/shared/cosmos-proto/src/ibc/tx.rs @@ -0,0 +1,5090 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `ibc/core/channel/v1/tx.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct MsgChannelOpenInit { + // message fields + pub port_id: ::std::string::String, + pub channel: ::protobuf::SingularPtrField, + pub signer: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgChannelOpenInit { + fn default() -> &'a MsgChannelOpenInit { + ::default_instance() + } +} + +impl MsgChannelOpenInit { + pub fn new() -> MsgChannelOpenInit { + ::std::default::Default::default() + } + + // string port_id = 1; + + + pub fn get_port_id(&self) -> &str { + &self.port_id + } + pub fn clear_port_id(&mut self) { + self.port_id.clear(); + } + + // Param is passed by value, moved + pub fn set_port_id(&mut self, v: ::std::string::String) { + self.port_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_port_id(&mut self) -> &mut ::std::string::String { + &mut self.port_id + } + + // Take field + pub fn take_port_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.port_id, ::std::string::String::new()) + } + + // .ibc.core.channel.v1.Channel channel = 2; + + + pub fn get_channel(&self) -> &super::channel::Channel { + self.channel.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_channel(&mut self) { + self.channel.clear(); + } + + pub fn has_channel(&self) -> bool { + self.channel.is_some() + } + + // Param is passed by value, moved + pub fn set_channel(&mut self, v: super::channel::Channel) { + self.channel = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_channel(&mut self) -> &mut super::channel::Channel { + if self.channel.is_none() { + self.channel.set_default(); + } + self.channel.as_mut().unwrap() + } + + // Take field + pub fn take_channel(&mut self) -> super::channel::Channel { + self.channel.take().unwrap_or_else(|| super::channel::Channel::new()) + } + + // string signer = 3; + + + pub fn get_signer(&self) -> &str { + &self.signer + } + pub fn clear_signer(&mut self) { + self.signer.clear(); + } + + // Param is passed by value, moved + pub fn set_signer(&mut self, v: ::std::string::String) { + self.signer = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_signer(&mut self) -> &mut ::std::string::String { + &mut self.signer + } + + // Take field + pub fn take_signer(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.signer, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for MsgChannelOpenInit { + fn is_initialized(&self) -> bool { + for v in &self.channel { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.port_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.channel)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.signer)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.port_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.port_id); + } + if let Some(ref v) = self.channel.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.signer.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.signer); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.port_id.is_empty() { + os.write_string(1, &self.port_id)?; + } + if let Some(ref v) = self.channel.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if !self.signer.is_empty() { + os.write_string(3, &self.signer)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgChannelOpenInit { + MsgChannelOpenInit::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "port_id", + |m: &MsgChannelOpenInit| { &m.port_id }, + |m: &mut MsgChannelOpenInit| { &mut m.port_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "channel", + |m: &MsgChannelOpenInit| { &m.channel }, + |m: &mut MsgChannelOpenInit| { &mut m.channel }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "signer", + |m: &MsgChannelOpenInit| { &m.signer }, + |m: &mut MsgChannelOpenInit| { &mut m.signer }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgChannelOpenInit", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgChannelOpenInit { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgChannelOpenInit::new) + } +} + +impl ::protobuf::Clear for MsgChannelOpenInit { + fn clear(&mut self) { + self.port_id.clear(); + self.channel.clear(); + self.signer.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgChannelOpenInit { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgChannelOpenInit { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgChannelOpenInitResponse { + // message fields + pub channel_id: ::std::string::String, + pub version: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgChannelOpenInitResponse { + fn default() -> &'a MsgChannelOpenInitResponse { + ::default_instance() + } +} + +impl MsgChannelOpenInitResponse { + pub fn new() -> MsgChannelOpenInitResponse { + ::std::default::Default::default() + } + + // string channel_id = 1; + + + pub fn get_channel_id(&self) -> &str { + &self.channel_id + } + pub fn clear_channel_id(&mut self) { + self.channel_id.clear(); + } + + // Param is passed by value, moved + pub fn set_channel_id(&mut self, v: ::std::string::String) { + self.channel_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_channel_id(&mut self) -> &mut ::std::string::String { + &mut self.channel_id + } + + // Take field + pub fn take_channel_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.channel_id, ::std::string::String::new()) + } + + // string version = 2; + + + pub fn get_version(&self) -> &str { + &self.version + } + pub fn clear_version(&mut self) { + self.version.clear(); + } + + // Param is passed by value, moved + pub fn set_version(&mut self, v: ::std::string::String) { + self.version = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_version(&mut self) -> &mut ::std::string::String { + &mut self.version + } + + // Take field + pub fn take_version(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.version, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for MsgChannelOpenInitResponse { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.channel_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.version)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.channel_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.channel_id); + } + if !self.version.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.version); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.channel_id.is_empty() { + os.write_string(1, &self.channel_id)?; + } + if !self.version.is_empty() { + os.write_string(2, &self.version)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgChannelOpenInitResponse { + MsgChannelOpenInitResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "channel_id", + |m: &MsgChannelOpenInitResponse| { &m.channel_id }, + |m: &mut MsgChannelOpenInitResponse| { &mut m.channel_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "version", + |m: &MsgChannelOpenInitResponse| { &m.version }, + |m: &mut MsgChannelOpenInitResponse| { &mut m.version }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgChannelOpenInitResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgChannelOpenInitResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgChannelOpenInitResponse::new) + } +} + +impl ::protobuf::Clear for MsgChannelOpenInitResponse { + fn clear(&mut self) { + self.channel_id.clear(); + self.version.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgChannelOpenInitResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgChannelOpenInitResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgChannelOpenTry { + // message fields + pub port_id: ::std::string::String, + pub previous_channel_id: ::std::string::String, + pub channel: ::protobuf::SingularPtrField, + pub counterparty_version: ::std::string::String, + pub proof_init: ::std::vec::Vec, + pub proof_height: ::protobuf::SingularPtrField, + pub signer: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgChannelOpenTry { + fn default() -> &'a MsgChannelOpenTry { + ::default_instance() + } +} + +impl MsgChannelOpenTry { + pub fn new() -> MsgChannelOpenTry { + ::std::default::Default::default() + } + + // string port_id = 1; + + + pub fn get_port_id(&self) -> &str { + &self.port_id + } + pub fn clear_port_id(&mut self) { + self.port_id.clear(); + } + + // Param is passed by value, moved + pub fn set_port_id(&mut self, v: ::std::string::String) { + self.port_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_port_id(&mut self) -> &mut ::std::string::String { + &mut self.port_id + } + + // Take field + pub fn take_port_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.port_id, ::std::string::String::new()) + } + + // string previous_channel_id = 2; + + + pub fn get_previous_channel_id(&self) -> &str { + &self.previous_channel_id + } + pub fn clear_previous_channel_id(&mut self) { + self.previous_channel_id.clear(); + } + + // Param is passed by value, moved + pub fn set_previous_channel_id(&mut self, v: ::std::string::String) { + self.previous_channel_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_previous_channel_id(&mut self) -> &mut ::std::string::String { + &mut self.previous_channel_id + } + + // Take field + pub fn take_previous_channel_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.previous_channel_id, ::std::string::String::new()) + } + + // .ibc.core.channel.v1.Channel channel = 3; + + + pub fn get_channel(&self) -> &super::channel::Channel { + self.channel.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_channel(&mut self) { + self.channel.clear(); + } + + pub fn has_channel(&self) -> bool { + self.channel.is_some() + } + + // Param is passed by value, moved + pub fn set_channel(&mut self, v: super::channel::Channel) { + self.channel = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_channel(&mut self) -> &mut super::channel::Channel { + if self.channel.is_none() { + self.channel.set_default(); + } + self.channel.as_mut().unwrap() + } + + // Take field + pub fn take_channel(&mut self) -> super::channel::Channel { + self.channel.take().unwrap_or_else(|| super::channel::Channel::new()) + } + + // string counterparty_version = 4; + + + pub fn get_counterparty_version(&self) -> &str { + &self.counterparty_version + } + pub fn clear_counterparty_version(&mut self) { + self.counterparty_version.clear(); + } + + // Param is passed by value, moved + pub fn set_counterparty_version(&mut self, v: ::std::string::String) { + self.counterparty_version = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_counterparty_version(&mut self) -> &mut ::std::string::String { + &mut self.counterparty_version + } + + // Take field + pub fn take_counterparty_version(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.counterparty_version, ::std::string::String::new()) + } + + // bytes proof_init = 5; + + + pub fn get_proof_init(&self) -> &[u8] { + &self.proof_init + } + pub fn clear_proof_init(&mut self) { + self.proof_init.clear(); + } + + // Param is passed by value, moved + pub fn set_proof_init(&mut self, v: ::std::vec::Vec) { + self.proof_init = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_init(&mut self) -> &mut ::std::vec::Vec { + &mut self.proof_init + } + + // Take field + pub fn take_proof_init(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.proof_init, ::std::vec::Vec::new()) + } + + // .ibc.core.client.v1.Height proof_height = 6; + + + pub fn get_proof_height(&self) -> &super::client::Height { + self.proof_height.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_proof_height(&mut self) { + self.proof_height.clear(); + } + + pub fn has_proof_height(&self) -> bool { + self.proof_height.is_some() + } + + // Param is passed by value, moved + pub fn set_proof_height(&mut self, v: super::client::Height) { + self.proof_height = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_height(&mut self) -> &mut super::client::Height { + if self.proof_height.is_none() { + self.proof_height.set_default(); + } + self.proof_height.as_mut().unwrap() + } + + // Take field + pub fn take_proof_height(&mut self) -> super::client::Height { + self.proof_height.take().unwrap_or_else(|| super::client::Height::new()) + } + + // string signer = 7; + + + pub fn get_signer(&self) -> &str { + &self.signer + } + pub fn clear_signer(&mut self) { + self.signer.clear(); + } + + // Param is passed by value, moved + pub fn set_signer(&mut self, v: ::std::string::String) { + self.signer = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_signer(&mut self) -> &mut ::std::string::String { + &mut self.signer + } + + // Take field + pub fn take_signer(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.signer, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for MsgChannelOpenTry { + fn is_initialized(&self) -> bool { + for v in &self.channel { + if !v.is_initialized() { + return false; + } + }; + for v in &self.proof_height { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.port_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.previous_channel_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.channel)?; + }, + 4 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.counterparty_version)?; + }, + 5 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.proof_init)?; + }, + 6 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.proof_height)?; + }, + 7 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.signer)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.port_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.port_id); + } + if !self.previous_channel_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.previous_channel_id); + } + if let Some(ref v) = self.channel.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.counterparty_version.is_empty() { + my_size += ::protobuf::rt::string_size(4, &self.counterparty_version); + } + if !self.proof_init.is_empty() { + my_size += ::protobuf::rt::bytes_size(5, &self.proof_init); + } + if let Some(ref v) = self.proof_height.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.signer.is_empty() { + my_size += ::protobuf::rt::string_size(7, &self.signer); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.port_id.is_empty() { + os.write_string(1, &self.port_id)?; + } + if !self.previous_channel_id.is_empty() { + os.write_string(2, &self.previous_channel_id)?; + } + if let Some(ref v) = self.channel.as_ref() { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if !self.counterparty_version.is_empty() { + os.write_string(4, &self.counterparty_version)?; + } + if !self.proof_init.is_empty() { + os.write_bytes(5, &self.proof_init)?; + } + if let Some(ref v) = self.proof_height.as_ref() { + os.write_tag(6, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if !self.signer.is_empty() { + os.write_string(7, &self.signer)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgChannelOpenTry { + MsgChannelOpenTry::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "port_id", + |m: &MsgChannelOpenTry| { &m.port_id }, + |m: &mut MsgChannelOpenTry| { &mut m.port_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "previous_channel_id", + |m: &MsgChannelOpenTry| { &m.previous_channel_id }, + |m: &mut MsgChannelOpenTry| { &mut m.previous_channel_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "channel", + |m: &MsgChannelOpenTry| { &m.channel }, + |m: &mut MsgChannelOpenTry| { &mut m.channel }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "counterparty_version", + |m: &MsgChannelOpenTry| { &m.counterparty_version }, + |m: &mut MsgChannelOpenTry| { &mut m.counterparty_version }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "proof_init", + |m: &MsgChannelOpenTry| { &m.proof_init }, + |m: &mut MsgChannelOpenTry| { &mut m.proof_init }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "proof_height", + |m: &MsgChannelOpenTry| { &m.proof_height }, + |m: &mut MsgChannelOpenTry| { &mut m.proof_height }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "signer", + |m: &MsgChannelOpenTry| { &m.signer }, + |m: &mut MsgChannelOpenTry| { &mut m.signer }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgChannelOpenTry", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgChannelOpenTry { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgChannelOpenTry::new) + } +} + +impl ::protobuf::Clear for MsgChannelOpenTry { + fn clear(&mut self) { + self.port_id.clear(); + self.previous_channel_id.clear(); + self.channel.clear(); + self.counterparty_version.clear(); + self.proof_init.clear(); + self.proof_height.clear(); + self.signer.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgChannelOpenTry { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgChannelOpenTry { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgChannelOpenTryResponse { + // message fields + pub version: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgChannelOpenTryResponse { + fn default() -> &'a MsgChannelOpenTryResponse { + ::default_instance() + } +} + +impl MsgChannelOpenTryResponse { + pub fn new() -> MsgChannelOpenTryResponse { + ::std::default::Default::default() + } + + // string version = 1; + + + pub fn get_version(&self) -> &str { + &self.version + } + pub fn clear_version(&mut self) { + self.version.clear(); + } + + // Param is passed by value, moved + pub fn set_version(&mut self, v: ::std::string::String) { + self.version = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_version(&mut self) -> &mut ::std::string::String { + &mut self.version + } + + // Take field + pub fn take_version(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.version, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for MsgChannelOpenTryResponse { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.version)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.version.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.version); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.version.is_empty() { + os.write_string(1, &self.version)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgChannelOpenTryResponse { + MsgChannelOpenTryResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "version", + |m: &MsgChannelOpenTryResponse| { &m.version }, + |m: &mut MsgChannelOpenTryResponse| { &mut m.version }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgChannelOpenTryResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgChannelOpenTryResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgChannelOpenTryResponse::new) + } +} + +impl ::protobuf::Clear for MsgChannelOpenTryResponse { + fn clear(&mut self) { + self.version.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgChannelOpenTryResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgChannelOpenTryResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgChannelOpenAck { + // message fields + pub port_id: ::std::string::String, + pub channel_id: ::std::string::String, + pub counterparty_channel_id: ::std::string::String, + pub counterparty_version: ::std::string::String, + pub proof_try: ::std::vec::Vec, + pub proof_height: ::protobuf::SingularPtrField, + pub signer: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgChannelOpenAck { + fn default() -> &'a MsgChannelOpenAck { + ::default_instance() + } +} + +impl MsgChannelOpenAck { + pub fn new() -> MsgChannelOpenAck { + ::std::default::Default::default() + } + + // string port_id = 1; + + + pub fn get_port_id(&self) -> &str { + &self.port_id + } + pub fn clear_port_id(&mut self) { + self.port_id.clear(); + } + + // Param is passed by value, moved + pub fn set_port_id(&mut self, v: ::std::string::String) { + self.port_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_port_id(&mut self) -> &mut ::std::string::String { + &mut self.port_id + } + + // Take field + pub fn take_port_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.port_id, ::std::string::String::new()) + } + + // string channel_id = 2; + + + pub fn get_channel_id(&self) -> &str { + &self.channel_id + } + pub fn clear_channel_id(&mut self) { + self.channel_id.clear(); + } + + // Param is passed by value, moved + pub fn set_channel_id(&mut self, v: ::std::string::String) { + self.channel_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_channel_id(&mut self) -> &mut ::std::string::String { + &mut self.channel_id + } + + // Take field + pub fn take_channel_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.channel_id, ::std::string::String::new()) + } + + // string counterparty_channel_id = 3; + + + pub fn get_counterparty_channel_id(&self) -> &str { + &self.counterparty_channel_id + } + pub fn clear_counterparty_channel_id(&mut self) { + self.counterparty_channel_id.clear(); + } + + // Param is passed by value, moved + pub fn set_counterparty_channel_id(&mut self, v: ::std::string::String) { + self.counterparty_channel_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_counterparty_channel_id(&mut self) -> &mut ::std::string::String { + &mut self.counterparty_channel_id + } + + // Take field + pub fn take_counterparty_channel_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.counterparty_channel_id, ::std::string::String::new()) + } + + // string counterparty_version = 4; + + + pub fn get_counterparty_version(&self) -> &str { + &self.counterparty_version + } + pub fn clear_counterparty_version(&mut self) { + self.counterparty_version.clear(); + } + + // Param is passed by value, moved + pub fn set_counterparty_version(&mut self, v: ::std::string::String) { + self.counterparty_version = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_counterparty_version(&mut self) -> &mut ::std::string::String { + &mut self.counterparty_version + } + + // Take field + pub fn take_counterparty_version(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.counterparty_version, ::std::string::String::new()) + } + + // bytes proof_try = 5; + + + pub fn get_proof_try(&self) -> &[u8] { + &self.proof_try + } + pub fn clear_proof_try(&mut self) { + self.proof_try.clear(); + } + + // Param is passed by value, moved + pub fn set_proof_try(&mut self, v: ::std::vec::Vec) { + self.proof_try = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_try(&mut self) -> &mut ::std::vec::Vec { + &mut self.proof_try + } + + // Take field + pub fn take_proof_try(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.proof_try, ::std::vec::Vec::new()) + } + + // .ibc.core.client.v1.Height proof_height = 6; + + + pub fn get_proof_height(&self) -> &super::client::Height { + self.proof_height.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_proof_height(&mut self) { + self.proof_height.clear(); + } + + pub fn has_proof_height(&self) -> bool { + self.proof_height.is_some() + } + + // Param is passed by value, moved + pub fn set_proof_height(&mut self, v: super::client::Height) { + self.proof_height = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_height(&mut self) -> &mut super::client::Height { + if self.proof_height.is_none() { + self.proof_height.set_default(); + } + self.proof_height.as_mut().unwrap() + } + + // Take field + pub fn take_proof_height(&mut self) -> super::client::Height { + self.proof_height.take().unwrap_or_else(|| super::client::Height::new()) + } + + // string signer = 7; + + + pub fn get_signer(&self) -> &str { + &self.signer + } + pub fn clear_signer(&mut self) { + self.signer.clear(); + } + + // Param is passed by value, moved + pub fn set_signer(&mut self, v: ::std::string::String) { + self.signer = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_signer(&mut self) -> &mut ::std::string::String { + &mut self.signer + } + + // Take field + pub fn take_signer(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.signer, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for MsgChannelOpenAck { + fn is_initialized(&self) -> bool { + for v in &self.proof_height { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.port_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.channel_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.counterparty_channel_id)?; + }, + 4 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.counterparty_version)?; + }, + 5 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.proof_try)?; + }, + 6 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.proof_height)?; + }, + 7 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.signer)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.port_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.port_id); + } + if !self.channel_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.channel_id); + } + if !self.counterparty_channel_id.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.counterparty_channel_id); + } + if !self.counterparty_version.is_empty() { + my_size += ::protobuf::rt::string_size(4, &self.counterparty_version); + } + if !self.proof_try.is_empty() { + my_size += ::protobuf::rt::bytes_size(5, &self.proof_try); + } + if let Some(ref v) = self.proof_height.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.signer.is_empty() { + my_size += ::protobuf::rt::string_size(7, &self.signer); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.port_id.is_empty() { + os.write_string(1, &self.port_id)?; + } + if !self.channel_id.is_empty() { + os.write_string(2, &self.channel_id)?; + } + if !self.counterparty_channel_id.is_empty() { + os.write_string(3, &self.counterparty_channel_id)?; + } + if !self.counterparty_version.is_empty() { + os.write_string(4, &self.counterparty_version)?; + } + if !self.proof_try.is_empty() { + os.write_bytes(5, &self.proof_try)?; + } + if let Some(ref v) = self.proof_height.as_ref() { + os.write_tag(6, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if !self.signer.is_empty() { + os.write_string(7, &self.signer)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgChannelOpenAck { + MsgChannelOpenAck::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "port_id", + |m: &MsgChannelOpenAck| { &m.port_id }, + |m: &mut MsgChannelOpenAck| { &mut m.port_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "channel_id", + |m: &MsgChannelOpenAck| { &m.channel_id }, + |m: &mut MsgChannelOpenAck| { &mut m.channel_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "counterparty_channel_id", + |m: &MsgChannelOpenAck| { &m.counterparty_channel_id }, + |m: &mut MsgChannelOpenAck| { &mut m.counterparty_channel_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "counterparty_version", + |m: &MsgChannelOpenAck| { &m.counterparty_version }, + |m: &mut MsgChannelOpenAck| { &mut m.counterparty_version }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "proof_try", + |m: &MsgChannelOpenAck| { &m.proof_try }, + |m: &mut MsgChannelOpenAck| { &mut m.proof_try }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "proof_height", + |m: &MsgChannelOpenAck| { &m.proof_height }, + |m: &mut MsgChannelOpenAck| { &mut m.proof_height }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "signer", + |m: &MsgChannelOpenAck| { &m.signer }, + |m: &mut MsgChannelOpenAck| { &mut m.signer }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgChannelOpenAck", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgChannelOpenAck { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgChannelOpenAck::new) + } +} + +impl ::protobuf::Clear for MsgChannelOpenAck { + fn clear(&mut self) { + self.port_id.clear(); + self.channel_id.clear(); + self.counterparty_channel_id.clear(); + self.counterparty_version.clear(); + self.proof_try.clear(); + self.proof_height.clear(); + self.signer.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgChannelOpenAck { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgChannelOpenAck { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgChannelOpenAckResponse { + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgChannelOpenAckResponse { + fn default() -> &'a MsgChannelOpenAckResponse { + ::default_instance() + } +} + +impl MsgChannelOpenAckResponse { + pub fn new() -> MsgChannelOpenAckResponse { + ::std::default::Default::default() + } +} + +impl ::protobuf::Message for MsgChannelOpenAckResponse { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgChannelOpenAckResponse { + MsgChannelOpenAckResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let fields = ::std::vec::Vec::new(); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgChannelOpenAckResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgChannelOpenAckResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgChannelOpenAckResponse::new) + } +} + +impl ::protobuf::Clear for MsgChannelOpenAckResponse { + fn clear(&mut self) { + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgChannelOpenAckResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgChannelOpenAckResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgChannelOpenConfirm { + // message fields + pub port_id: ::std::string::String, + pub channel_id: ::std::string::String, + pub proof_ack: ::std::vec::Vec, + pub proof_height: ::protobuf::SingularPtrField, + pub signer: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgChannelOpenConfirm { + fn default() -> &'a MsgChannelOpenConfirm { + ::default_instance() + } +} + +impl MsgChannelOpenConfirm { + pub fn new() -> MsgChannelOpenConfirm { + ::std::default::Default::default() + } + + // string port_id = 1; + + + pub fn get_port_id(&self) -> &str { + &self.port_id + } + pub fn clear_port_id(&mut self) { + self.port_id.clear(); + } + + // Param is passed by value, moved + pub fn set_port_id(&mut self, v: ::std::string::String) { + self.port_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_port_id(&mut self) -> &mut ::std::string::String { + &mut self.port_id + } + + // Take field + pub fn take_port_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.port_id, ::std::string::String::new()) + } + + // string channel_id = 2; + + + pub fn get_channel_id(&self) -> &str { + &self.channel_id + } + pub fn clear_channel_id(&mut self) { + self.channel_id.clear(); + } + + // Param is passed by value, moved + pub fn set_channel_id(&mut self, v: ::std::string::String) { + self.channel_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_channel_id(&mut self) -> &mut ::std::string::String { + &mut self.channel_id + } + + // Take field + pub fn take_channel_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.channel_id, ::std::string::String::new()) + } + + // bytes proof_ack = 3; + + + pub fn get_proof_ack(&self) -> &[u8] { + &self.proof_ack + } + pub fn clear_proof_ack(&mut self) { + self.proof_ack.clear(); + } + + // Param is passed by value, moved + pub fn set_proof_ack(&mut self, v: ::std::vec::Vec) { + self.proof_ack = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_ack(&mut self) -> &mut ::std::vec::Vec { + &mut self.proof_ack + } + + // Take field + pub fn take_proof_ack(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.proof_ack, ::std::vec::Vec::new()) + } + + // .ibc.core.client.v1.Height proof_height = 4; + + + pub fn get_proof_height(&self) -> &super::client::Height { + self.proof_height.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_proof_height(&mut self) { + self.proof_height.clear(); + } + + pub fn has_proof_height(&self) -> bool { + self.proof_height.is_some() + } + + // Param is passed by value, moved + pub fn set_proof_height(&mut self, v: super::client::Height) { + self.proof_height = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_height(&mut self) -> &mut super::client::Height { + if self.proof_height.is_none() { + self.proof_height.set_default(); + } + self.proof_height.as_mut().unwrap() + } + + // Take field + pub fn take_proof_height(&mut self) -> super::client::Height { + self.proof_height.take().unwrap_or_else(|| super::client::Height::new()) + } + + // string signer = 5; + + + pub fn get_signer(&self) -> &str { + &self.signer + } + pub fn clear_signer(&mut self) { + self.signer.clear(); + } + + // Param is passed by value, moved + pub fn set_signer(&mut self, v: ::std::string::String) { + self.signer = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_signer(&mut self) -> &mut ::std::string::String { + &mut self.signer + } + + // Take field + pub fn take_signer(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.signer, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for MsgChannelOpenConfirm { + fn is_initialized(&self) -> bool { + for v in &self.proof_height { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.port_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.channel_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.proof_ack)?; + }, + 4 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.proof_height)?; + }, + 5 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.signer)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.port_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.port_id); + } + if !self.channel_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.channel_id); + } + if !self.proof_ack.is_empty() { + my_size += ::protobuf::rt::bytes_size(3, &self.proof_ack); + } + if let Some(ref v) = self.proof_height.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.signer.is_empty() { + my_size += ::protobuf::rt::string_size(5, &self.signer); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.port_id.is_empty() { + os.write_string(1, &self.port_id)?; + } + if !self.channel_id.is_empty() { + os.write_string(2, &self.channel_id)?; + } + if !self.proof_ack.is_empty() { + os.write_bytes(3, &self.proof_ack)?; + } + if let Some(ref v) = self.proof_height.as_ref() { + os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if !self.signer.is_empty() { + os.write_string(5, &self.signer)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgChannelOpenConfirm { + MsgChannelOpenConfirm::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "port_id", + |m: &MsgChannelOpenConfirm| { &m.port_id }, + |m: &mut MsgChannelOpenConfirm| { &mut m.port_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "channel_id", + |m: &MsgChannelOpenConfirm| { &m.channel_id }, + |m: &mut MsgChannelOpenConfirm| { &mut m.channel_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "proof_ack", + |m: &MsgChannelOpenConfirm| { &m.proof_ack }, + |m: &mut MsgChannelOpenConfirm| { &mut m.proof_ack }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "proof_height", + |m: &MsgChannelOpenConfirm| { &m.proof_height }, + |m: &mut MsgChannelOpenConfirm| { &mut m.proof_height }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "signer", + |m: &MsgChannelOpenConfirm| { &m.signer }, + |m: &mut MsgChannelOpenConfirm| { &mut m.signer }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgChannelOpenConfirm", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgChannelOpenConfirm { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgChannelOpenConfirm::new) + } +} + +impl ::protobuf::Clear for MsgChannelOpenConfirm { + fn clear(&mut self) { + self.port_id.clear(); + self.channel_id.clear(); + self.proof_ack.clear(); + self.proof_height.clear(); + self.signer.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgChannelOpenConfirm { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgChannelOpenConfirm { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgChannelOpenConfirmResponse { + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgChannelOpenConfirmResponse { + fn default() -> &'a MsgChannelOpenConfirmResponse { + ::default_instance() + } +} + +impl MsgChannelOpenConfirmResponse { + pub fn new() -> MsgChannelOpenConfirmResponse { + ::std::default::Default::default() + } +} + +impl ::protobuf::Message for MsgChannelOpenConfirmResponse { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgChannelOpenConfirmResponse { + MsgChannelOpenConfirmResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let fields = ::std::vec::Vec::new(); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgChannelOpenConfirmResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgChannelOpenConfirmResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgChannelOpenConfirmResponse::new) + } +} + +impl ::protobuf::Clear for MsgChannelOpenConfirmResponse { + fn clear(&mut self) { + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgChannelOpenConfirmResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgChannelOpenConfirmResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgChannelCloseInit { + // message fields + pub port_id: ::std::string::String, + pub channel_id: ::std::string::String, + pub signer: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgChannelCloseInit { + fn default() -> &'a MsgChannelCloseInit { + ::default_instance() + } +} + +impl MsgChannelCloseInit { + pub fn new() -> MsgChannelCloseInit { + ::std::default::Default::default() + } + + // string port_id = 1; + + + pub fn get_port_id(&self) -> &str { + &self.port_id + } + pub fn clear_port_id(&mut self) { + self.port_id.clear(); + } + + // Param is passed by value, moved + pub fn set_port_id(&mut self, v: ::std::string::String) { + self.port_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_port_id(&mut self) -> &mut ::std::string::String { + &mut self.port_id + } + + // Take field + pub fn take_port_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.port_id, ::std::string::String::new()) + } + + // string channel_id = 2; + + + pub fn get_channel_id(&self) -> &str { + &self.channel_id + } + pub fn clear_channel_id(&mut self) { + self.channel_id.clear(); + } + + // Param is passed by value, moved + pub fn set_channel_id(&mut self, v: ::std::string::String) { + self.channel_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_channel_id(&mut self) -> &mut ::std::string::String { + &mut self.channel_id + } + + // Take field + pub fn take_channel_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.channel_id, ::std::string::String::new()) + } + + // string signer = 3; + + + pub fn get_signer(&self) -> &str { + &self.signer + } + pub fn clear_signer(&mut self) { + self.signer.clear(); + } + + // Param is passed by value, moved + pub fn set_signer(&mut self, v: ::std::string::String) { + self.signer = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_signer(&mut self) -> &mut ::std::string::String { + &mut self.signer + } + + // Take field + pub fn take_signer(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.signer, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for MsgChannelCloseInit { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.port_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.channel_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.signer)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.port_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.port_id); + } + if !self.channel_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.channel_id); + } + if !self.signer.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.signer); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.port_id.is_empty() { + os.write_string(1, &self.port_id)?; + } + if !self.channel_id.is_empty() { + os.write_string(2, &self.channel_id)?; + } + if !self.signer.is_empty() { + os.write_string(3, &self.signer)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgChannelCloseInit { + MsgChannelCloseInit::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "port_id", + |m: &MsgChannelCloseInit| { &m.port_id }, + |m: &mut MsgChannelCloseInit| { &mut m.port_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "channel_id", + |m: &MsgChannelCloseInit| { &m.channel_id }, + |m: &mut MsgChannelCloseInit| { &mut m.channel_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "signer", + |m: &MsgChannelCloseInit| { &m.signer }, + |m: &mut MsgChannelCloseInit| { &mut m.signer }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgChannelCloseInit", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgChannelCloseInit { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgChannelCloseInit::new) + } +} + +impl ::protobuf::Clear for MsgChannelCloseInit { + fn clear(&mut self) { + self.port_id.clear(); + self.channel_id.clear(); + self.signer.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgChannelCloseInit { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgChannelCloseInit { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgChannelCloseInitResponse { + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgChannelCloseInitResponse { + fn default() -> &'a MsgChannelCloseInitResponse { + ::default_instance() + } +} + +impl MsgChannelCloseInitResponse { + pub fn new() -> MsgChannelCloseInitResponse { + ::std::default::Default::default() + } +} + +impl ::protobuf::Message for MsgChannelCloseInitResponse { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgChannelCloseInitResponse { + MsgChannelCloseInitResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let fields = ::std::vec::Vec::new(); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgChannelCloseInitResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgChannelCloseInitResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgChannelCloseInitResponse::new) + } +} + +impl ::protobuf::Clear for MsgChannelCloseInitResponse { + fn clear(&mut self) { + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgChannelCloseInitResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgChannelCloseInitResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgChannelCloseConfirm { + // message fields + pub port_id: ::std::string::String, + pub channel_id: ::std::string::String, + pub proof_init: ::std::vec::Vec, + pub proof_height: ::protobuf::SingularPtrField, + pub signer: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgChannelCloseConfirm { + fn default() -> &'a MsgChannelCloseConfirm { + ::default_instance() + } +} + +impl MsgChannelCloseConfirm { + pub fn new() -> MsgChannelCloseConfirm { + ::std::default::Default::default() + } + + // string port_id = 1; + + + pub fn get_port_id(&self) -> &str { + &self.port_id + } + pub fn clear_port_id(&mut self) { + self.port_id.clear(); + } + + // Param is passed by value, moved + pub fn set_port_id(&mut self, v: ::std::string::String) { + self.port_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_port_id(&mut self) -> &mut ::std::string::String { + &mut self.port_id + } + + // Take field + pub fn take_port_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.port_id, ::std::string::String::new()) + } + + // string channel_id = 2; + + + pub fn get_channel_id(&self) -> &str { + &self.channel_id + } + pub fn clear_channel_id(&mut self) { + self.channel_id.clear(); + } + + // Param is passed by value, moved + pub fn set_channel_id(&mut self, v: ::std::string::String) { + self.channel_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_channel_id(&mut self) -> &mut ::std::string::String { + &mut self.channel_id + } + + // Take field + pub fn take_channel_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.channel_id, ::std::string::String::new()) + } + + // bytes proof_init = 3; + + + pub fn get_proof_init(&self) -> &[u8] { + &self.proof_init + } + pub fn clear_proof_init(&mut self) { + self.proof_init.clear(); + } + + // Param is passed by value, moved + pub fn set_proof_init(&mut self, v: ::std::vec::Vec) { + self.proof_init = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_init(&mut self) -> &mut ::std::vec::Vec { + &mut self.proof_init + } + + // Take field + pub fn take_proof_init(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.proof_init, ::std::vec::Vec::new()) + } + + // .ibc.core.client.v1.Height proof_height = 4; + + + pub fn get_proof_height(&self) -> &super::client::Height { + self.proof_height.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_proof_height(&mut self) { + self.proof_height.clear(); + } + + pub fn has_proof_height(&self) -> bool { + self.proof_height.is_some() + } + + // Param is passed by value, moved + pub fn set_proof_height(&mut self, v: super::client::Height) { + self.proof_height = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_height(&mut self) -> &mut super::client::Height { + if self.proof_height.is_none() { + self.proof_height.set_default(); + } + self.proof_height.as_mut().unwrap() + } + + // Take field + pub fn take_proof_height(&mut self) -> super::client::Height { + self.proof_height.take().unwrap_or_else(|| super::client::Height::new()) + } + + // string signer = 5; + + + pub fn get_signer(&self) -> &str { + &self.signer + } + pub fn clear_signer(&mut self) { + self.signer.clear(); + } + + // Param is passed by value, moved + pub fn set_signer(&mut self, v: ::std::string::String) { + self.signer = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_signer(&mut self) -> &mut ::std::string::String { + &mut self.signer + } + + // Take field + pub fn take_signer(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.signer, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for MsgChannelCloseConfirm { + fn is_initialized(&self) -> bool { + for v in &self.proof_height { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.port_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.channel_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.proof_init)?; + }, + 4 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.proof_height)?; + }, + 5 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.signer)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.port_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.port_id); + } + if !self.channel_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.channel_id); + } + if !self.proof_init.is_empty() { + my_size += ::protobuf::rt::bytes_size(3, &self.proof_init); + } + if let Some(ref v) = self.proof_height.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.signer.is_empty() { + my_size += ::protobuf::rt::string_size(5, &self.signer); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.port_id.is_empty() { + os.write_string(1, &self.port_id)?; + } + if !self.channel_id.is_empty() { + os.write_string(2, &self.channel_id)?; + } + if !self.proof_init.is_empty() { + os.write_bytes(3, &self.proof_init)?; + } + if let Some(ref v) = self.proof_height.as_ref() { + os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if !self.signer.is_empty() { + os.write_string(5, &self.signer)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgChannelCloseConfirm { + MsgChannelCloseConfirm::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "port_id", + |m: &MsgChannelCloseConfirm| { &m.port_id }, + |m: &mut MsgChannelCloseConfirm| { &mut m.port_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "channel_id", + |m: &MsgChannelCloseConfirm| { &m.channel_id }, + |m: &mut MsgChannelCloseConfirm| { &mut m.channel_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "proof_init", + |m: &MsgChannelCloseConfirm| { &m.proof_init }, + |m: &mut MsgChannelCloseConfirm| { &mut m.proof_init }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "proof_height", + |m: &MsgChannelCloseConfirm| { &m.proof_height }, + |m: &mut MsgChannelCloseConfirm| { &mut m.proof_height }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "signer", + |m: &MsgChannelCloseConfirm| { &m.signer }, + |m: &mut MsgChannelCloseConfirm| { &mut m.signer }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgChannelCloseConfirm", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgChannelCloseConfirm { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgChannelCloseConfirm::new) + } +} + +impl ::protobuf::Clear for MsgChannelCloseConfirm { + fn clear(&mut self) { + self.port_id.clear(); + self.channel_id.clear(); + self.proof_init.clear(); + self.proof_height.clear(); + self.signer.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgChannelCloseConfirm { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgChannelCloseConfirm { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgChannelCloseConfirmResponse { + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgChannelCloseConfirmResponse { + fn default() -> &'a MsgChannelCloseConfirmResponse { + ::default_instance() + } +} + +impl MsgChannelCloseConfirmResponse { + pub fn new() -> MsgChannelCloseConfirmResponse { + ::std::default::Default::default() + } +} + +impl ::protobuf::Message for MsgChannelCloseConfirmResponse { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgChannelCloseConfirmResponse { + MsgChannelCloseConfirmResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let fields = ::std::vec::Vec::new(); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgChannelCloseConfirmResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgChannelCloseConfirmResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgChannelCloseConfirmResponse::new) + } +} + +impl ::protobuf::Clear for MsgChannelCloseConfirmResponse { + fn clear(&mut self) { + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgChannelCloseConfirmResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgChannelCloseConfirmResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgRecvPacket { + // message fields + pub packet: ::protobuf::SingularPtrField, + pub proof_commitment: ::std::vec::Vec, + pub proof_height: ::protobuf::SingularPtrField, + pub signer: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgRecvPacket { + fn default() -> &'a MsgRecvPacket { + ::default_instance() + } +} + +impl MsgRecvPacket { + pub fn new() -> MsgRecvPacket { + ::std::default::Default::default() + } + + // .ibc.core.channel.v1.Packet packet = 1; + + + pub fn get_packet(&self) -> &super::channel::Packet { + self.packet.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_packet(&mut self) { + self.packet.clear(); + } + + pub fn has_packet(&self) -> bool { + self.packet.is_some() + } + + // Param is passed by value, moved + pub fn set_packet(&mut self, v: super::channel::Packet) { + self.packet = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_packet(&mut self) -> &mut super::channel::Packet { + if self.packet.is_none() { + self.packet.set_default(); + } + self.packet.as_mut().unwrap() + } + + // Take field + pub fn take_packet(&mut self) -> super::channel::Packet { + self.packet.take().unwrap_or_else(|| super::channel::Packet::new()) + } + + // bytes proof_commitment = 2; + + + pub fn get_proof_commitment(&self) -> &[u8] { + &self.proof_commitment + } + pub fn clear_proof_commitment(&mut self) { + self.proof_commitment.clear(); + } + + // Param is passed by value, moved + pub fn set_proof_commitment(&mut self, v: ::std::vec::Vec) { + self.proof_commitment = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_commitment(&mut self) -> &mut ::std::vec::Vec { + &mut self.proof_commitment + } + + // Take field + pub fn take_proof_commitment(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.proof_commitment, ::std::vec::Vec::new()) + } + + // .ibc.core.client.v1.Height proof_height = 3; + + + pub fn get_proof_height(&self) -> &super::client::Height { + self.proof_height.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_proof_height(&mut self) { + self.proof_height.clear(); + } + + pub fn has_proof_height(&self) -> bool { + self.proof_height.is_some() + } + + // Param is passed by value, moved + pub fn set_proof_height(&mut self, v: super::client::Height) { + self.proof_height = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_height(&mut self) -> &mut super::client::Height { + if self.proof_height.is_none() { + self.proof_height.set_default(); + } + self.proof_height.as_mut().unwrap() + } + + // Take field + pub fn take_proof_height(&mut self) -> super::client::Height { + self.proof_height.take().unwrap_or_else(|| super::client::Height::new()) + } + + // string signer = 4; + + + pub fn get_signer(&self) -> &str { + &self.signer + } + pub fn clear_signer(&mut self) { + self.signer.clear(); + } + + // Param is passed by value, moved + pub fn set_signer(&mut self, v: ::std::string::String) { + self.signer = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_signer(&mut self) -> &mut ::std::string::String { + &mut self.signer + } + + // Take field + pub fn take_signer(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.signer, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for MsgRecvPacket { + fn is_initialized(&self) -> bool { + for v in &self.packet { + if !v.is_initialized() { + return false; + } + }; + for v in &self.proof_height { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.packet)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.proof_commitment)?; + }, + 3 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.proof_height)?; + }, + 4 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.signer)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.packet.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.proof_commitment.is_empty() { + my_size += ::protobuf::rt::bytes_size(2, &self.proof_commitment); + } + if let Some(ref v) = self.proof_height.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.signer.is_empty() { + my_size += ::protobuf::rt::string_size(4, &self.signer); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if let Some(ref v) = self.packet.as_ref() { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if !self.proof_commitment.is_empty() { + os.write_bytes(2, &self.proof_commitment)?; + } + if let Some(ref v) = self.proof_height.as_ref() { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if !self.signer.is_empty() { + os.write_string(4, &self.signer)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgRecvPacket { + MsgRecvPacket::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "packet", + |m: &MsgRecvPacket| { &m.packet }, + |m: &mut MsgRecvPacket| { &mut m.packet }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "proof_commitment", + |m: &MsgRecvPacket| { &m.proof_commitment }, + |m: &mut MsgRecvPacket| { &mut m.proof_commitment }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "proof_height", + |m: &MsgRecvPacket| { &m.proof_height }, + |m: &mut MsgRecvPacket| { &mut m.proof_height }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "signer", + |m: &MsgRecvPacket| { &m.signer }, + |m: &mut MsgRecvPacket| { &mut m.signer }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgRecvPacket", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgRecvPacket { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgRecvPacket::new) + } +} + +impl ::protobuf::Clear for MsgRecvPacket { + fn clear(&mut self) { + self.packet.clear(); + self.proof_commitment.clear(); + self.proof_height.clear(); + self.signer.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgRecvPacket { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgRecvPacket { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgRecvPacketResponse { + // message fields + pub result: ResponseResultType, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgRecvPacketResponse { + fn default() -> &'a MsgRecvPacketResponse { + ::default_instance() + } +} + +impl MsgRecvPacketResponse { + pub fn new() -> MsgRecvPacketResponse { + ::std::default::Default::default() + } + + // .ibc.core.channel.v1.ResponseResultType result = 1; + + + pub fn get_result(&self) -> ResponseResultType { + self.result + } + pub fn clear_result(&mut self) { + self.result = ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED; + } + + // Param is passed by value, moved + pub fn set_result(&mut self, v: ResponseResultType) { + self.result = v; + } +} + +impl ::protobuf::Message for MsgRecvPacketResponse { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.result, 1, &mut self.unknown_fields)? + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.result != ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED { + my_size += ::protobuf::rt::enum_size(1, self.result); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.result != ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED { + os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.result))?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgRecvPacketResponse { + MsgRecvPacketResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "result", + |m: &MsgRecvPacketResponse| { &m.result }, + |m: &mut MsgRecvPacketResponse| { &mut m.result }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgRecvPacketResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgRecvPacketResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgRecvPacketResponse::new) + } +} + +impl ::protobuf::Clear for MsgRecvPacketResponse { + fn clear(&mut self) { + self.result = ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgRecvPacketResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgRecvPacketResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgTimeout { + // message fields + pub packet: ::protobuf::SingularPtrField, + pub proof_unreceived: ::std::vec::Vec, + pub proof_height: ::protobuf::SingularPtrField, + pub next_sequence_recv: u64, + pub signer: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgTimeout { + fn default() -> &'a MsgTimeout { + ::default_instance() + } +} + +impl MsgTimeout { + pub fn new() -> MsgTimeout { + ::std::default::Default::default() + } + + // .ibc.core.channel.v1.Packet packet = 1; + + + pub fn get_packet(&self) -> &super::channel::Packet { + self.packet.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_packet(&mut self) { + self.packet.clear(); + } + + pub fn has_packet(&self) -> bool { + self.packet.is_some() + } + + // Param is passed by value, moved + pub fn set_packet(&mut self, v: super::channel::Packet) { + self.packet = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_packet(&mut self) -> &mut super::channel::Packet { + if self.packet.is_none() { + self.packet.set_default(); + } + self.packet.as_mut().unwrap() + } + + // Take field + pub fn take_packet(&mut self) -> super::channel::Packet { + self.packet.take().unwrap_or_else(|| super::channel::Packet::new()) + } + + // bytes proof_unreceived = 2; + + + pub fn get_proof_unreceived(&self) -> &[u8] { + &self.proof_unreceived + } + pub fn clear_proof_unreceived(&mut self) { + self.proof_unreceived.clear(); + } + + // Param is passed by value, moved + pub fn set_proof_unreceived(&mut self, v: ::std::vec::Vec) { + self.proof_unreceived = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_unreceived(&mut self) -> &mut ::std::vec::Vec { + &mut self.proof_unreceived + } + + // Take field + pub fn take_proof_unreceived(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.proof_unreceived, ::std::vec::Vec::new()) + } + + // .ibc.core.client.v1.Height proof_height = 3; + + + pub fn get_proof_height(&self) -> &super::client::Height { + self.proof_height.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_proof_height(&mut self) { + self.proof_height.clear(); + } + + pub fn has_proof_height(&self) -> bool { + self.proof_height.is_some() + } + + // Param is passed by value, moved + pub fn set_proof_height(&mut self, v: super::client::Height) { + self.proof_height = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_height(&mut self) -> &mut super::client::Height { + if self.proof_height.is_none() { + self.proof_height.set_default(); + } + self.proof_height.as_mut().unwrap() + } + + // Take field + pub fn take_proof_height(&mut self) -> super::client::Height { + self.proof_height.take().unwrap_or_else(|| super::client::Height::new()) + } + + // uint64 next_sequence_recv = 4; + + + pub fn get_next_sequence_recv(&self) -> u64 { + self.next_sequence_recv + } + pub fn clear_next_sequence_recv(&mut self) { + self.next_sequence_recv = 0; + } + + // Param is passed by value, moved + pub fn set_next_sequence_recv(&mut self, v: u64) { + self.next_sequence_recv = v; + } + + // string signer = 5; + + + pub fn get_signer(&self) -> &str { + &self.signer + } + pub fn clear_signer(&mut self) { + self.signer.clear(); + } + + // Param is passed by value, moved + pub fn set_signer(&mut self, v: ::std::string::String) { + self.signer = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_signer(&mut self) -> &mut ::std::string::String { + &mut self.signer + } + + // Take field + pub fn take_signer(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.signer, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for MsgTimeout { + fn is_initialized(&self) -> bool { + for v in &self.packet { + if !v.is_initialized() { + return false; + } + }; + for v in &self.proof_height { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.packet)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.proof_unreceived)?; + }, + 3 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.proof_height)?; + }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_uint64()?; + self.next_sequence_recv = tmp; + }, + 5 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.signer)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.packet.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.proof_unreceived.is_empty() { + my_size += ::protobuf::rt::bytes_size(2, &self.proof_unreceived); + } + if let Some(ref v) = self.proof_height.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if self.next_sequence_recv != 0 { + my_size += ::protobuf::rt::value_size(4, self.next_sequence_recv, ::protobuf::wire_format::WireTypeVarint); + } + if !self.signer.is_empty() { + my_size += ::protobuf::rt::string_size(5, &self.signer); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if let Some(ref v) = self.packet.as_ref() { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if !self.proof_unreceived.is_empty() { + os.write_bytes(2, &self.proof_unreceived)?; + } + if let Some(ref v) = self.proof_height.as_ref() { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if self.next_sequence_recv != 0 { + os.write_uint64(4, self.next_sequence_recv)?; + } + if !self.signer.is_empty() { + os.write_string(5, &self.signer)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgTimeout { + MsgTimeout::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "packet", + |m: &MsgTimeout| { &m.packet }, + |m: &mut MsgTimeout| { &mut m.packet }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "proof_unreceived", + |m: &MsgTimeout| { &m.proof_unreceived }, + |m: &mut MsgTimeout| { &mut m.proof_unreceived }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "proof_height", + |m: &MsgTimeout| { &m.proof_height }, + |m: &mut MsgTimeout| { &mut m.proof_height }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint64>( + "next_sequence_recv", + |m: &MsgTimeout| { &m.next_sequence_recv }, + |m: &mut MsgTimeout| { &mut m.next_sequence_recv }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "signer", + |m: &MsgTimeout| { &m.signer }, + |m: &mut MsgTimeout| { &mut m.signer }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgTimeout", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgTimeout { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgTimeout::new) + } +} + +impl ::protobuf::Clear for MsgTimeout { + fn clear(&mut self) { + self.packet.clear(); + self.proof_unreceived.clear(); + self.proof_height.clear(); + self.next_sequence_recv = 0; + self.signer.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgTimeout { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgTimeout { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgTimeoutResponse { + // message fields + pub result: ResponseResultType, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgTimeoutResponse { + fn default() -> &'a MsgTimeoutResponse { + ::default_instance() + } +} + +impl MsgTimeoutResponse { + pub fn new() -> MsgTimeoutResponse { + ::std::default::Default::default() + } + + // .ibc.core.channel.v1.ResponseResultType result = 1; + + + pub fn get_result(&self) -> ResponseResultType { + self.result + } + pub fn clear_result(&mut self) { + self.result = ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED; + } + + // Param is passed by value, moved + pub fn set_result(&mut self, v: ResponseResultType) { + self.result = v; + } +} + +impl ::protobuf::Message for MsgTimeoutResponse { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.result, 1, &mut self.unknown_fields)? + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.result != ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED { + my_size += ::protobuf::rt::enum_size(1, self.result); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.result != ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED { + os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.result))?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgTimeoutResponse { + MsgTimeoutResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "result", + |m: &MsgTimeoutResponse| { &m.result }, + |m: &mut MsgTimeoutResponse| { &mut m.result }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgTimeoutResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgTimeoutResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgTimeoutResponse::new) + } +} + +impl ::protobuf::Clear for MsgTimeoutResponse { + fn clear(&mut self) { + self.result = ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgTimeoutResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgTimeoutResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgTimeoutOnClose { + // message fields + pub packet: ::protobuf::SingularPtrField, + pub proof_unreceived: ::std::vec::Vec, + pub proof_close: ::std::vec::Vec, + pub proof_height: ::protobuf::SingularPtrField, + pub next_sequence_recv: u64, + pub signer: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgTimeoutOnClose { + fn default() -> &'a MsgTimeoutOnClose { + ::default_instance() + } +} + +impl MsgTimeoutOnClose { + pub fn new() -> MsgTimeoutOnClose { + ::std::default::Default::default() + } + + // .ibc.core.channel.v1.Packet packet = 1; + + + pub fn get_packet(&self) -> &super::channel::Packet { + self.packet.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_packet(&mut self) { + self.packet.clear(); + } + + pub fn has_packet(&self) -> bool { + self.packet.is_some() + } + + // Param is passed by value, moved + pub fn set_packet(&mut self, v: super::channel::Packet) { + self.packet = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_packet(&mut self) -> &mut super::channel::Packet { + if self.packet.is_none() { + self.packet.set_default(); + } + self.packet.as_mut().unwrap() + } + + // Take field + pub fn take_packet(&mut self) -> super::channel::Packet { + self.packet.take().unwrap_or_else(|| super::channel::Packet::new()) + } + + // bytes proof_unreceived = 2; + + + pub fn get_proof_unreceived(&self) -> &[u8] { + &self.proof_unreceived + } + pub fn clear_proof_unreceived(&mut self) { + self.proof_unreceived.clear(); + } + + // Param is passed by value, moved + pub fn set_proof_unreceived(&mut self, v: ::std::vec::Vec) { + self.proof_unreceived = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_unreceived(&mut self) -> &mut ::std::vec::Vec { + &mut self.proof_unreceived + } + + // Take field + pub fn take_proof_unreceived(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.proof_unreceived, ::std::vec::Vec::new()) + } + + // bytes proof_close = 3; + + + pub fn get_proof_close(&self) -> &[u8] { + &self.proof_close + } + pub fn clear_proof_close(&mut self) { + self.proof_close.clear(); + } + + // Param is passed by value, moved + pub fn set_proof_close(&mut self, v: ::std::vec::Vec) { + self.proof_close = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_close(&mut self) -> &mut ::std::vec::Vec { + &mut self.proof_close + } + + // Take field + pub fn take_proof_close(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.proof_close, ::std::vec::Vec::new()) + } + + // .ibc.core.client.v1.Height proof_height = 4; + + + pub fn get_proof_height(&self) -> &super::client::Height { + self.proof_height.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_proof_height(&mut self) { + self.proof_height.clear(); + } + + pub fn has_proof_height(&self) -> bool { + self.proof_height.is_some() + } + + // Param is passed by value, moved + pub fn set_proof_height(&mut self, v: super::client::Height) { + self.proof_height = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_height(&mut self) -> &mut super::client::Height { + if self.proof_height.is_none() { + self.proof_height.set_default(); + } + self.proof_height.as_mut().unwrap() + } + + // Take field + pub fn take_proof_height(&mut self) -> super::client::Height { + self.proof_height.take().unwrap_or_else(|| super::client::Height::new()) + } + + // uint64 next_sequence_recv = 5; + + + pub fn get_next_sequence_recv(&self) -> u64 { + self.next_sequence_recv + } + pub fn clear_next_sequence_recv(&mut self) { + self.next_sequence_recv = 0; + } + + // Param is passed by value, moved + pub fn set_next_sequence_recv(&mut self, v: u64) { + self.next_sequence_recv = v; + } + + // string signer = 6; + + + pub fn get_signer(&self) -> &str { + &self.signer + } + pub fn clear_signer(&mut self) { + self.signer.clear(); + } + + // Param is passed by value, moved + pub fn set_signer(&mut self, v: ::std::string::String) { + self.signer = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_signer(&mut self) -> &mut ::std::string::String { + &mut self.signer + } + + // Take field + pub fn take_signer(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.signer, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for MsgTimeoutOnClose { + fn is_initialized(&self) -> bool { + for v in &self.packet { + if !v.is_initialized() { + return false; + } + }; + for v in &self.proof_height { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.packet)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.proof_unreceived)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.proof_close)?; + }, + 4 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.proof_height)?; + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_uint64()?; + self.next_sequence_recv = tmp; + }, + 6 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.signer)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.packet.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.proof_unreceived.is_empty() { + my_size += ::protobuf::rt::bytes_size(2, &self.proof_unreceived); + } + if !self.proof_close.is_empty() { + my_size += ::protobuf::rt::bytes_size(3, &self.proof_close); + } + if let Some(ref v) = self.proof_height.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if self.next_sequence_recv != 0 { + my_size += ::protobuf::rt::value_size(5, self.next_sequence_recv, ::protobuf::wire_format::WireTypeVarint); + } + if !self.signer.is_empty() { + my_size += ::protobuf::rt::string_size(6, &self.signer); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if let Some(ref v) = self.packet.as_ref() { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if !self.proof_unreceived.is_empty() { + os.write_bytes(2, &self.proof_unreceived)?; + } + if !self.proof_close.is_empty() { + os.write_bytes(3, &self.proof_close)?; + } + if let Some(ref v) = self.proof_height.as_ref() { + os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if self.next_sequence_recv != 0 { + os.write_uint64(5, self.next_sequence_recv)?; + } + if !self.signer.is_empty() { + os.write_string(6, &self.signer)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgTimeoutOnClose { + MsgTimeoutOnClose::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "packet", + |m: &MsgTimeoutOnClose| { &m.packet }, + |m: &mut MsgTimeoutOnClose| { &mut m.packet }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "proof_unreceived", + |m: &MsgTimeoutOnClose| { &m.proof_unreceived }, + |m: &mut MsgTimeoutOnClose| { &mut m.proof_unreceived }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "proof_close", + |m: &MsgTimeoutOnClose| { &m.proof_close }, + |m: &mut MsgTimeoutOnClose| { &mut m.proof_close }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "proof_height", + |m: &MsgTimeoutOnClose| { &m.proof_height }, + |m: &mut MsgTimeoutOnClose| { &mut m.proof_height }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint64>( + "next_sequence_recv", + |m: &MsgTimeoutOnClose| { &m.next_sequence_recv }, + |m: &mut MsgTimeoutOnClose| { &mut m.next_sequence_recv }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "signer", + |m: &MsgTimeoutOnClose| { &m.signer }, + |m: &mut MsgTimeoutOnClose| { &mut m.signer }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgTimeoutOnClose", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgTimeoutOnClose { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgTimeoutOnClose::new) + } +} + +impl ::protobuf::Clear for MsgTimeoutOnClose { + fn clear(&mut self) { + self.packet.clear(); + self.proof_unreceived.clear(); + self.proof_close.clear(); + self.proof_height.clear(); + self.next_sequence_recv = 0; + self.signer.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgTimeoutOnClose { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgTimeoutOnClose { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgTimeoutOnCloseResponse { + // message fields + pub result: ResponseResultType, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgTimeoutOnCloseResponse { + fn default() -> &'a MsgTimeoutOnCloseResponse { + ::default_instance() + } +} + +impl MsgTimeoutOnCloseResponse { + pub fn new() -> MsgTimeoutOnCloseResponse { + ::std::default::Default::default() + } + + // .ibc.core.channel.v1.ResponseResultType result = 1; + + + pub fn get_result(&self) -> ResponseResultType { + self.result + } + pub fn clear_result(&mut self) { + self.result = ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED; + } + + // Param is passed by value, moved + pub fn set_result(&mut self, v: ResponseResultType) { + self.result = v; + } +} + +impl ::protobuf::Message for MsgTimeoutOnCloseResponse { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.result, 1, &mut self.unknown_fields)? + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.result != ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED { + my_size += ::protobuf::rt::enum_size(1, self.result); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.result != ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED { + os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.result))?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgTimeoutOnCloseResponse { + MsgTimeoutOnCloseResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "result", + |m: &MsgTimeoutOnCloseResponse| { &m.result }, + |m: &mut MsgTimeoutOnCloseResponse| { &mut m.result }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgTimeoutOnCloseResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgTimeoutOnCloseResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgTimeoutOnCloseResponse::new) + } +} + +impl ::protobuf::Clear for MsgTimeoutOnCloseResponse { + fn clear(&mut self) { + self.result = ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgTimeoutOnCloseResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgTimeoutOnCloseResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgAcknowledgement { + // message fields + pub packet: ::protobuf::SingularPtrField, + pub acknowledgement: ::std::vec::Vec, + pub proof_acked: ::std::vec::Vec, + pub proof_height: ::protobuf::SingularPtrField, + pub signer: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgAcknowledgement { + fn default() -> &'a MsgAcknowledgement { + ::default_instance() + } +} + +impl MsgAcknowledgement { + pub fn new() -> MsgAcknowledgement { + ::std::default::Default::default() + } + + // .ibc.core.channel.v1.Packet packet = 1; + + + pub fn get_packet(&self) -> &super::channel::Packet { + self.packet.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_packet(&mut self) { + self.packet.clear(); + } + + pub fn has_packet(&self) -> bool { + self.packet.is_some() + } + + // Param is passed by value, moved + pub fn set_packet(&mut self, v: super::channel::Packet) { + self.packet = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_packet(&mut self) -> &mut super::channel::Packet { + if self.packet.is_none() { + self.packet.set_default(); + } + self.packet.as_mut().unwrap() + } + + // Take field + pub fn take_packet(&mut self) -> super::channel::Packet { + self.packet.take().unwrap_or_else(|| super::channel::Packet::new()) + } + + // bytes acknowledgement = 2; + + + pub fn get_acknowledgement(&self) -> &[u8] { + &self.acknowledgement + } + pub fn clear_acknowledgement(&mut self) { + self.acknowledgement.clear(); + } + + // Param is passed by value, moved + pub fn set_acknowledgement(&mut self, v: ::std::vec::Vec) { + self.acknowledgement = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_acknowledgement(&mut self) -> &mut ::std::vec::Vec { + &mut self.acknowledgement + } + + // Take field + pub fn take_acknowledgement(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.acknowledgement, ::std::vec::Vec::new()) + } + + // bytes proof_acked = 3; + + + pub fn get_proof_acked(&self) -> &[u8] { + &self.proof_acked + } + pub fn clear_proof_acked(&mut self) { + self.proof_acked.clear(); + } + + // Param is passed by value, moved + pub fn set_proof_acked(&mut self, v: ::std::vec::Vec) { + self.proof_acked = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_acked(&mut self) -> &mut ::std::vec::Vec { + &mut self.proof_acked + } + + // Take field + pub fn take_proof_acked(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.proof_acked, ::std::vec::Vec::new()) + } + + // .ibc.core.client.v1.Height proof_height = 4; + + + pub fn get_proof_height(&self) -> &super::client::Height { + self.proof_height.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_proof_height(&mut self) { + self.proof_height.clear(); + } + + pub fn has_proof_height(&self) -> bool { + self.proof_height.is_some() + } + + // Param is passed by value, moved + pub fn set_proof_height(&mut self, v: super::client::Height) { + self.proof_height = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_proof_height(&mut self) -> &mut super::client::Height { + if self.proof_height.is_none() { + self.proof_height.set_default(); + } + self.proof_height.as_mut().unwrap() + } + + // Take field + pub fn take_proof_height(&mut self) -> super::client::Height { + self.proof_height.take().unwrap_or_else(|| super::client::Height::new()) + } + + // string signer = 5; + + + pub fn get_signer(&self) -> &str { + &self.signer + } + pub fn clear_signer(&mut self) { + self.signer.clear(); + } + + // Param is passed by value, moved + pub fn set_signer(&mut self, v: ::std::string::String) { + self.signer = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_signer(&mut self) -> &mut ::std::string::String { + &mut self.signer + } + + // Take field + pub fn take_signer(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.signer, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for MsgAcknowledgement { + fn is_initialized(&self) -> bool { + for v in &self.packet { + if !v.is_initialized() { + return false; + } + }; + for v in &self.proof_height { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.packet)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.acknowledgement)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.proof_acked)?; + }, + 4 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.proof_height)?; + }, + 5 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.signer)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.packet.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.acknowledgement.is_empty() { + my_size += ::protobuf::rt::bytes_size(2, &self.acknowledgement); + } + if !self.proof_acked.is_empty() { + my_size += ::protobuf::rt::bytes_size(3, &self.proof_acked); + } + if let Some(ref v) = self.proof_height.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if !self.signer.is_empty() { + my_size += ::protobuf::rt::string_size(5, &self.signer); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if let Some(ref v) = self.packet.as_ref() { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if !self.acknowledgement.is_empty() { + os.write_bytes(2, &self.acknowledgement)?; + } + if !self.proof_acked.is_empty() { + os.write_bytes(3, &self.proof_acked)?; + } + if let Some(ref v) = self.proof_height.as_ref() { + os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if !self.signer.is_empty() { + os.write_string(5, &self.signer)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgAcknowledgement { + MsgAcknowledgement::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "packet", + |m: &MsgAcknowledgement| { &m.packet }, + |m: &mut MsgAcknowledgement| { &mut m.packet }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "acknowledgement", + |m: &MsgAcknowledgement| { &m.acknowledgement }, + |m: &mut MsgAcknowledgement| { &mut m.acknowledgement }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "proof_acked", + |m: &MsgAcknowledgement| { &m.proof_acked }, + |m: &mut MsgAcknowledgement| { &mut m.proof_acked }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "proof_height", + |m: &MsgAcknowledgement| { &m.proof_height }, + |m: &mut MsgAcknowledgement| { &mut m.proof_height }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "signer", + |m: &MsgAcknowledgement| { &m.signer }, + |m: &mut MsgAcknowledgement| { &mut m.signer }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgAcknowledgement", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgAcknowledgement { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgAcknowledgement::new) + } +} + +impl ::protobuf::Clear for MsgAcknowledgement { + fn clear(&mut self) { + self.packet.clear(); + self.acknowledgement.clear(); + self.proof_acked.clear(); + self.proof_height.clear(); + self.signer.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgAcknowledgement { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgAcknowledgement { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MsgAcknowledgementResponse { + // message fields + pub result: ResponseResultType, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MsgAcknowledgementResponse { + fn default() -> &'a MsgAcknowledgementResponse { + ::default_instance() + } +} + +impl MsgAcknowledgementResponse { + pub fn new() -> MsgAcknowledgementResponse { + ::std::default::Default::default() + } + + // .ibc.core.channel.v1.ResponseResultType result = 1; + + + pub fn get_result(&self) -> ResponseResultType { + self.result + } + pub fn clear_result(&mut self) { + self.result = ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED; + } + + // Param is passed by value, moved + pub fn set_result(&mut self, v: ResponseResultType) { + self.result = v; + } +} + +impl ::protobuf::Message for MsgAcknowledgementResponse { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.result, 1, &mut self.unknown_fields)? + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.result != ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED { + my_size += ::protobuf::rt::enum_size(1, self.result); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.result != ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED { + os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.result))?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MsgAcknowledgementResponse { + MsgAcknowledgementResponse::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "result", + |m: &MsgAcknowledgementResponse| { &m.result }, + |m: &mut MsgAcknowledgementResponse| { &mut m.result }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MsgAcknowledgementResponse", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MsgAcknowledgementResponse { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MsgAcknowledgementResponse::new) + } +} + +impl ::protobuf::Clear for MsgAcknowledgementResponse { + fn clear(&mut self) { + self.result = ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MsgAcknowledgementResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MsgAcknowledgementResponse { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum ResponseResultType { + RESPONSE_RESULT_TYPE_UNSPECIFIED = 0, + RESPONSE_RESULT_TYPE_NOOP = 1, + RESPONSE_RESULT_TYPE_SUCCESS = 2, +} + +impl ::protobuf::ProtobufEnum for ResponseResultType { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED), + 1 => ::std::option::Option::Some(ResponseResultType::RESPONSE_RESULT_TYPE_NOOP), + 2 => ::std::option::Option::Some(ResponseResultType::RESPONSE_RESULT_TYPE_SUCCESS), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [ResponseResultType] = &[ + ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED, + ResponseResultType::RESPONSE_RESULT_TYPE_NOOP, + ResponseResultType::RESPONSE_RESULT_TYPE_SUCCESS, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("ResponseResultType", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for ResponseResultType { +} + +impl ::std::default::Default for ResponseResultType { + fn default() -> Self { + ResponseResultType::RESPONSE_RESULT_TYPE_UNSPECIFIED + } +} + +impl ::protobuf::reflect::ProtobufValue for ResponseResultType { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x1cibc/core/channel/v1/tx.proto\x12\x13ibc.core.channel.v1\x1a\x14gog\ + oproto/gogo.proto\x1a\x1fibc/core/client/v1/client.proto\x1a!ibc/core/ch\ + annel/v1/channel.proto\"\xa1\x01\n\x12MsgChannelOpenInit\x12+\n\x07port_\ + id\x18\x01\x20\x01(\tR\x06portIdB\x12\xf2\xde\x1f\x0eyaml:\"port_id\"\ + \x12<\n\x07channel\x18\x02\x20\x01(\x0b2\x1c.ibc.core.channel.v1.Channel\ + R\x07channelB\x04\xc8\xde\x1f\0\x12\x16\n\x06signer\x18\x03\x20\x01(\tR\ + \x06signer:\x08\x88\xa0\x1f\0\xe8\xa0\x1f\0\"l\n\x1aMsgChannelOpenInitRe\ + sponse\x124\n\nchannel_id\x18\x01\x20\x01(\tR\tchannelIdB\x15\xf2\xde\ + \x1f\x11yaml:\"channel_id\"\x12\x18\n\x07version\x18\x02\x20\x01(\tR\x07\ + version\"\xd8\x03\n\x11MsgChannelOpenTry\x12+\n\x07port_id\x18\x01\x20\ + \x01(\tR\x06portIdB\x12\xf2\xde\x1f\x0eyaml:\"port_id\"\x12P\n\x13previo\ + us_channel_id\x18\x02\x20\x01(\tR\x11previousChannelIdB\x20\x18\x01\xf2\ + \xde\x1f\x1ayaml:\"previous_channel_id\"\x12<\n\x07channel\x18\x03\x20\ + \x01(\x0b2\x1c.ibc.core.channel.v1.ChannelR\x07channelB\x04\xc8\xde\x1f\ + \0\x12R\n\x14counterparty_version\x18\x04\x20\x01(\tR\x13counterpartyVer\ + sionB\x1f\xf2\xde\x1f\x1byaml:\"counterparty_version\"\x124\n\nproof_ini\ + t\x18\x05\x20\x01(\x0cR\tproofInitB\x15\xf2\xde\x1f\x11yaml:\"proof_init\ + \"\x12Z\n\x0cproof_height\x18\x06\x20\x01(\x0b2\x1a.ibc.core.client.v1.H\ + eightR\x0bproofHeightB\x1b\xf2\xde\x1f\x13yaml:\"proof_height\"\xc8\xde\ + \x1f\0\x12\x16\n\x06signer\x18\x07\x20\x01(\tR\x06signer:\x08\x88\xa0\ + \x1f\0\xe8\xa0\x1f\0\"5\n\x19MsgChannelOpenTryResponse\x12\x18\n\x07vers\ + ion\x18\x01\x20\x01(\tR\x07version\"\xd7\x03\n\x11MsgChannelOpenAck\x12+\ + \n\x07port_id\x18\x01\x20\x01(\tR\x06portIdB\x12\xf2\xde\x1f\x0eyaml:\"p\ + ort_id\"\x124\n\nchannel_id\x18\x02\x20\x01(\tR\tchannelIdB\x15\xf2\xde\ + \x1f\x11yaml:\"channel_id\"\x12Z\n\x17counterparty_channel_id\x18\x03\ + \x20\x01(\tR\x15counterpartyChannelIdB\"\xf2\xde\x1f\x1eyaml:\"counterpa\ + rty_channel_id\"\x12R\n\x14counterparty_version\x18\x04\x20\x01(\tR\x13c\ + ounterpartyVersionB\x1f\xf2\xde\x1f\x1byaml:\"counterparty_version\"\x12\ + 1\n\tproof_try\x18\x05\x20\x01(\x0cR\x08proofTryB\x14\xf2\xde\x1f\x10yam\ + l:\"proof_try\"\x12Z\n\x0cproof_height\x18\x06\x20\x01(\x0b2\x1a.ibc.cor\ + e.client.v1.HeightR\x0bproofHeightB\x1b\xf2\xde\x1f\x13yaml:\"proof_heig\ + ht\"\xc8\xde\x1f\0\x12\x16\n\x06signer\x18\x07\x20\x01(\tR\x06signer:\ + \x08\x88\xa0\x1f\0\xe8\xa0\x1f\0\"\x1b\n\x19MsgChannelOpenAckResponse\"\ + \xab\x02\n\x15MsgChannelOpenConfirm\x12+\n\x07port_id\x18\x01\x20\x01(\t\ + R\x06portIdB\x12\xf2\xde\x1f\x0eyaml:\"port_id\"\x124\n\nchannel_id\x18\ + \x02\x20\x01(\tR\tchannelIdB\x15\xf2\xde\x1f\x11yaml:\"channel_id\"\x121\ + \n\tproof_ack\x18\x03\x20\x01(\x0cR\x08proofAckB\x14\xf2\xde\x1f\x10yaml\ + :\"proof_ack\"\x12Z\n\x0cproof_height\x18\x04\x20\x01(\x0b2\x1a.ibc.core\ + .client.v1.HeightR\x0bproofHeightB\x1b\xf2\xde\x1f\x13yaml:\"proof_heigh\ + t\"\xc8\xde\x1f\0\x12\x16\n\x06signer\x18\x05\x20\x01(\tR\x06signer:\x08\ + \x88\xa0\x1f\0\xe8\xa0\x1f\0\"\x1f\n\x1dMsgChannelOpenConfirmResponse\"\ + \x9a\x01\n\x13MsgChannelCloseInit\x12+\n\x07port_id\x18\x01\x20\x01(\tR\ + \x06portIdB\x12\xf2\xde\x1f\x0eyaml:\"port_id\"\x124\n\nchannel_id\x18\ + \x02\x20\x01(\tR\tchannelIdB\x15\xf2\xde\x1f\x11yaml:\"channel_id\"\x12\ + \x16\n\x06signer\x18\x03\x20\x01(\tR\x06signer:\x08\x88\xa0\x1f\0\xe8\ + \xa0\x1f\0\"\x1d\n\x1bMsgChannelCloseInitResponse\"\xaf\x02\n\x16MsgChan\ + nelCloseConfirm\x12+\n\x07port_id\x18\x01\x20\x01(\tR\x06portIdB\x12\xf2\ + \xde\x1f\x0eyaml:\"port_id\"\x124\n\nchannel_id\x18\x02\x20\x01(\tR\tcha\ + nnelIdB\x15\xf2\xde\x1f\x11yaml:\"channel_id\"\x124\n\nproof_init\x18\ + \x03\x20\x01(\x0cR\tproofInitB\x15\xf2\xde\x1f\x11yaml:\"proof_init\"\ + \x12Z\n\x0cproof_height\x18\x04\x20\x01(\x0b2\x1a.ibc.core.client.v1.Hei\ + ghtR\x0bproofHeightB\x1b\xf2\xde\x1f\x13yaml:\"proof_height\"\xc8\xde\ + \x1f\0\x12\x16\n\x06signer\x18\x05\x20\x01(\tR\x06signer:\x08\x88\xa0\ + \x1f\0\xe8\xa0\x1f\0\"\x20\n\x1eMsgChannelCloseConfirmResponse\"\x90\x02\ + \n\rMsgRecvPacket\x129\n\x06packet\x18\x01\x20\x01(\x0b2\x1b.ibc.core.ch\ + annel.v1.PacketR\x06packetB\x04\xc8\xde\x1f\0\x12F\n\x10proof_commitment\ + \x18\x02\x20\x01(\x0cR\x0fproofCommitmentB\x1b\xf2\xde\x1f\x17yaml:\"pro\ + of_commitment\"\x12Z\n\x0cproof_height\x18\x03\x20\x01(\x0b2\x1a.ibc.cor\ + e.client.v1.HeightR\x0bproofHeightB\x1b\xf2\xde\x1f\x13yaml:\"proof_heig\ + ht\"\xc8\xde\x1f\0\x12\x16\n\x06signer\x18\x04\x20\x01(\tR\x06signer:\ + \x08\x88\xa0\x1f\0\xe8\xa0\x1f\0\"^\n\x15MsgRecvPacketResponse\x12?\n\ + \x06result\x18\x01\x20\x01(\x0e2'.ibc.core.channel.v1.ResponseResultType\ + R\x06result:\x04\x88\xa0\x1f\0\"\xda\x02\n\nMsgTimeout\x129\n\x06packet\ + \x18\x01\x20\x01(\x0b2\x1b.ibc.core.channel.v1.PacketR\x06packetB\x04\ + \xc8\xde\x1f\0\x12F\n\x10proof_unreceived\x18\x02\x20\x01(\x0cR\x0fproof\ + UnreceivedB\x1b\xf2\xde\x1f\x17yaml:\"proof_unreceived\"\x12Z\n\x0cproof\ + _height\x18\x03\x20\x01(\x0b2\x1a.ibc.core.client.v1.HeightR\x0bproofHei\ + ghtB\x1b\xf2\xde\x1f\x13yaml:\"proof_height\"\xc8\xde\x1f\0\x12K\n\x12ne\ + xt_sequence_recv\x18\x04\x20\x01(\x04R\x10nextSequenceRecvB\x1d\xf2\xde\ + \x1f\x19yaml:\"next_sequence_recv\"\x12\x16\n\x06signer\x18\x05\x20\x01(\ + \tR\x06signer:\x08\x88\xa0\x1f\0\xe8\xa0\x1f\0\"[\n\x12MsgTimeoutRespons\ + e\x12?\n\x06result\x18\x01\x20\x01(\x0e2'.ibc.core.channel.v1.ResponseRe\ + sultTypeR\x06result:\x04\x88\xa0\x1f\0\"\x9a\x03\n\x11MsgTimeoutOnClose\ + \x129\n\x06packet\x18\x01\x20\x01(\x0b2\x1b.ibc.core.channel.v1.PacketR\ + \x06packetB\x04\xc8\xde\x1f\0\x12F\n\x10proof_unreceived\x18\x02\x20\x01\ + (\x0cR\x0fproofUnreceivedB\x1b\xf2\xde\x1f\x17yaml:\"proof_unreceived\"\ + \x127\n\x0bproof_close\x18\x03\x20\x01(\x0cR\nproofCloseB\x16\xf2\xde\ + \x1f\x12yaml:\"proof_close\"\x12Z\n\x0cproof_height\x18\x04\x20\x01(\x0b\ + 2\x1a.ibc.core.client.v1.HeightR\x0bproofHeightB\x1b\xf2\xde\x1f\x13yaml\ + :\"proof_height\"\xc8\xde\x1f\0\x12K\n\x12next_sequence_recv\x18\x05\x20\ + \x01(\x04R\x10nextSequenceRecvB\x1d\xf2\xde\x1f\x19yaml:\"next_sequence_\ + recv\"\x12\x16\n\x06signer\x18\x06\x20\x01(\tR\x06signer:\x08\x88\xa0\ + \x1f\0\xe8\xa0\x1f\0\"b\n\x19MsgTimeoutOnCloseResponse\x12?\n\x06result\ + \x18\x01\x20\x01(\x0e2'.ibc.core.channel.v1.ResponseResultTypeR\x06resul\ + t:\x04\x88\xa0\x1f\0\"\xb0\x02\n\x12MsgAcknowledgement\x129\n\x06packet\ + \x18\x01\x20\x01(\x0b2\x1b.ibc.core.channel.v1.PacketR\x06packetB\x04\ + \xc8\xde\x1f\0\x12(\n\x0facknowledgement\x18\x02\x20\x01(\x0cR\x0facknow\ + ledgement\x127\n\x0bproof_acked\x18\x03\x20\x01(\x0cR\nproofAckedB\x16\ + \xf2\xde\x1f\x12yaml:\"proof_acked\"\x12Z\n\x0cproof_height\x18\x04\x20\ + \x01(\x0b2\x1a.ibc.core.client.v1.HeightR\x0bproofHeightB\x1b\xf2\xde\ + \x1f\x13yaml:\"proof_height\"\xc8\xde\x1f\0\x12\x16\n\x06signer\x18\x05\ + \x20\x01(\tR\x06signer:\x08\x88\xa0\x1f\0\xe8\xa0\x1f\0\"c\n\x1aMsgAckno\ + wledgementResponse\x12?\n\x06result\x18\x01\x20\x01(\x0e2'.ibc.core.chan\ + nel.v1.ResponseResultTypeR\x06result:\x04\x88\xa0\x1f\0*\xa9\x01\n\x12Re\ + sponseResultType\x125\n\x20RESPONSE_RESULT_TYPE_UNSPECIFIED\x10\0\x1a\ + \x0f\x8a\x9d\x20\x0bUNSPECIFIED\x12'\n\x19RESPONSE_RESULT_TYPE_NOOP\x10\ + \x01\x1a\x08\x8a\x9d\x20\x04NOOP\x12-\n\x1cRESPONSE_RESULT_TYPE_SUCCESS\ + \x10\x02\x1a\x0b\x8a\x9d\x20\x07SUCCESS\x1a\x04\x88\xa3\x1e\02\xaf\x08\n\ + \x03Msg\x12k\n\x0fChannelOpenInit\x12'.ibc.core.channel.v1.MsgChannelOpe\ + nInit\x1a/.ibc.core.channel.v1.MsgChannelOpenInitResponse\x12h\n\x0eChan\ + nelOpenTry\x12&.ibc.core.channel.v1.MsgChannelOpenTry\x1a..ibc.core.chan\ + nel.v1.MsgChannelOpenTryResponse\x12h\n\x0eChannelOpenAck\x12&.ibc.core.\ + channel.v1.MsgChannelOpenAck\x1a..ibc.core.channel.v1.MsgChannelOpenAckR\ + esponse\x12t\n\x12ChannelOpenConfirm\x12*.ibc.core.channel.v1.MsgChannel\ + OpenConfirm\x1a2.ibc.core.channel.v1.MsgChannelOpenConfirmResponse\x12n\ + \n\x10ChannelCloseInit\x12(.ibc.core.channel.v1.MsgChannelCloseInit\x1a0\ + .ibc.core.channel.v1.MsgChannelCloseInitResponse\x12w\n\x13ChannelCloseC\ + onfirm\x12+.ibc.core.channel.v1.MsgChannelCloseConfirm\x1a3.ibc.core.cha\ + nnel.v1.MsgChannelCloseConfirmResponse\x12\\\n\nRecvPacket\x12\".ibc.cor\ + e.channel.v1.MsgRecvPacket\x1a*.ibc.core.channel.v1.MsgRecvPacketRespons\ + e\x12S\n\x07Timeout\x12\x1f.ibc.core.channel.v1.MsgTimeout\x1a'.ibc.core\ + .channel.v1.MsgTimeoutResponse\x12h\n\x0eTimeoutOnClose\x12&.ibc.core.ch\ + annel.v1.MsgTimeoutOnClose\x1a..ibc.core.channel.v1.MsgTimeoutOnCloseRes\ + ponse\x12k\n\x0fAcknowledgement\x12'.ibc.core.channel.v1.MsgAcknowledgem\ + ent\x1a/.ibc.core.channel.v1.MsgAcknowledgementResponseB;Z9github.com/co\ + smos/ibc-go/v4/modules/core/04-channel/typesb\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/cosmwasm/enclaves/shared/cosmos-proto/src/lib.rs b/cosmwasm/enclaves/shared/cosmos-proto/src/lib.rs index 9585a20ca..bce066631 100644 --- a/cosmwasm/enclaves/shared/cosmos-proto/src/lib.rs +++ b/cosmwasm/enclaves/shared/cosmos-proto/src/lib.rs @@ -41,3 +41,9 @@ pub mod cosmwasm { use super::base::coin; } + +pub mod ibc { + pub mod channel; + pub mod client; + pub mod tx; +} diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 1f37bdd6b..7aa35c54e 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -311,6 +311,7 @@ pub enum StdCosmWasmMsg { label: String, callback_sig: Option>, }, + // The core IBC messages don't support Amino #[serde(other, deserialize_with = "deserialize_ignore_any")] Other, } @@ -386,6 +387,7 @@ impl StdCosmWasmMsg { #[derive(Debug)] pub enum CosmWasmMsg { + // CosmWasm: Execute { sender: CanonicalAddr, contract: HumanAddr, @@ -400,6 +402,19 @@ pub enum CosmWasmMsg { label: String, callback_sig: Option>, }, + // IBC: + // MsgChannelOpenInit {}, // TODO + // MsgChannelOpenTry {}, // TODO + // MsgChannelOpenAck {}, // TODO + // MsgChannelOpenConfirm {}, // TODO + // MsgChannelCloseInit {}, // TODO + // MsgChannelCloseConfirm {}, // TODO + // MsgAcknowledgement {}, // TODO + // MsgTimeout {}, // TODO + MsgRecvPacket { + data: Vec, + }, + // All else: Other, } @@ -407,6 +422,15 @@ impl CosmWasmMsg { pub fn from_bytes(bytes: &[u8]) -> Result { Self::try_parse_execute(bytes) .or_else(|_| Self::try_parse_instantiate(bytes)) + // .or_else(|_| Self::try_parse_msg_channel_open_init(bytes)) + // .or_else(|_| Self::try_parse_msg_channel_open_try(bytes)) + // .or_else(|_| Self::try_parse_msg_channel_open_ack(bytes)) + // .or_else(|_| Self::try_parse_msg_channel_open_confirm(bytes)) + // .or_else(|_| Self::try_parse_msg_channel_close_init(bytes)) + // .or_else(|_| Self::try_parse_msg_channel_close_confirm(bytes)) + // .or_else(|_| Self::try_parse_msg_acknowledgement(bytes)) + // .or_else(|_| Self::try_parse_msg_timeout(bytes)) + .or_else(|_| Self::try_parse_recv_packet(bytes)) .or_else(|_| { warn!( "got an error while trying to deserialize cosmwasm message bytes from protobuf: {}", @@ -416,6 +440,50 @@ impl CosmWasmMsg { }) } + // fn try_parse_msg_channel_open_init(bytes: &[u8]) -> Result { + // todo!() + // } + + // fn try_parse_msg_channel_open_try(bytes: &[u8]) -> Result { + // todo!() + // } + + // fn try_parse_msg_channel_open_ack(bytes: &[u8]) -> Result { + // todo!() + // } + + // fn try_parse_msg_channel_open_confirm(bytes: &[u8]) -> Result { + // todo!() + // } + + // fn try_parse_msg_channel_close_init(bytes: &[u8]) -> Result { + // todo!() + // } + + // fn try_parse_msg_channel_close_confirm(bytes: &[u8]) -> Result { + // todo!() + // } + + // fn try_parse_msg_acknowledgement(bytes: &[u8]) -> Result { + // todo!() + // } + + // fn try_parse_msg_timeout(bytes: &[u8]) -> Result { + // todo!() + // } + + fn try_parse_msg_recv_packet(bytes: &[u8]) -> Result { + use proto::ibc::tx::MsgRecvPacket; + + let raw_msg = MsgRecvPacket::parse_from_bytes(bytes) + .map_err(|_| EnclaveError::FailedToDeserialize)?; + + match raw_msg.packet.into_option() { + None => Err(EnclaveError::FailedToDeserialize), + Some(packet) => Ok(CosmWasmMsg::MsgRecvPacket { data: packet.data }), + } + } + fn try_parse_instantiate(bytes: &[u8]) -> Result { use proto::cosmwasm::msg::MsgInstantiateContract; From 9f98e8d7c861eb0c56a845c06e5da8f86065c37a Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 4 May 2023 20:02:22 +0300 Subject: [PATCH 02/54] Checkpoint: verify MsgRecvPacket inside the enclave & simplify msg verification process --- .vscode/settings.json | 7 +- cosmwasm/enclaves/Cargo.lock | 13 +- .../src/contract_operations.rs | 23 +- .../src/contract_validation.rs | 592 +++++++-- .../contract-engine/src/execute_message.rs | 2 + .../shared/contract-engine/src/ibc_message.rs | 10 +- .../shared/contract-engine/src/message.rs | 6 +- .../contract-engine/src/reply_message.rs | 2 + .../shared/contract-engine/src/types.rs | 1 + .../enclaves/shared/cosmos-proto/build.rs | 1 + .../shared/cosmos-proto/src/ibc/upgrade.rs | 1061 +++++++++++++++++ .../enclaves/shared/cosmos-proto/src/lib.rs | 1 + .../enclaves/shared/cosmos-types/Cargo.toml | 1 + .../enclaves/shared/cosmos-types/src/types.rs | 38 +- .../shared/cosmwasm-types/v0.10/src/types.rs | 8 + x/compute/internal/keeper/keeper.go | 60 +- x/compute/internal/keeper/relay.go | 7 +- x/ibc-hooks/README.md | 8 +- 18 files changed, 1662 insertions(+), 179 deletions(-) create mode 100644 cosmwasm/enclaves/shared/cosmos-proto/src/ibc/upgrade.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 2a35bf3e7..dbab00de1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,9 +13,7 @@ "integration-tests/contract-v1/Cargo.toml", "integration-tests/contract-v0.10/Cargo.toml", "go-cosmwasm/Cargo.toml", - "integration-tests/contract-v0.10/Cargo.toml", - "check-hw/Cargo.toml", - "./cosmwasm/enclaves/shared/cosmos-proto/Cargo.toml" + "cosmwasm/enclaves/shared/cosmos-proto/Cargo.toml" ], "rust-analyzer.diagnostics.experimental.enable": true, "rust-analyzer.rustfmt.rangeFormatting.enable": true, @@ -23,12 +21,11 @@ "unresolved-macro-call", "unresolved-proc-macro" ], - "rust-analyzer.cargo.features": ["light-client-validation", "build-protobuf"], + "rust-analyzer.cargo.features": "all", "[rust]": { "editor.formatOnSave": true, "editor.defaultFormatter": "rust-lang.rust-analyzer" }, - "go.testEnvVars": { "SGX_MODE": "SW", "RUST_BACKTRACE": "1" diff --git a/cosmwasm/enclaves/Cargo.lock b/cosmwasm/enclaves/Cargo.lock index 00183ca2f..ff51fc309 100644 --- a/cosmwasm/enclaves/Cargo.lock +++ b/cosmwasm/enclaves/Cargo.lock @@ -41,9 +41,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.19" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] @@ -663,6 +663,7 @@ dependencies = [ "prost 0.6.1", "protobuf", "serde 1.0.118", + "serde_json 1.0.60", "sgx_tstd", "sha2 0.8.2", ] @@ -1337,9 +1338,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ "aho-corasick", "memchr", @@ -1348,9 +1349,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "remove_dir_all" diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index aad300d24..dcf772879 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -112,6 +112,8 @@ pub fn init( contract_address, &secret_msg, msg, + true, + true, )?; // let duration = start.elapsed(); // trace!("Time elapsed in verify_params: {:?}", duration); @@ -262,6 +264,7 @@ pub fn handle( let ParsedMessage { should_validate_sig_info, + should_validate_input, was_msg_encrypted, should_encrypt_output, secret_msg, @@ -280,16 +283,16 @@ pub fn handle( // - Plaintext replies (resulting from an IBC call) // - IBC WASM Hooks // - (In the future:) ICA - if should_validate_sig_info { - verify_params( - &parsed_sig_info, - sent_funds, - &canonical_sender_address, - contract_address, - &secret_msg, - msg, - )?; - } + verify_params( + &parsed_sig_info, + sent_funds, + &canonical_sender_address, + contract_address, + &secret_msg, + msg, + should_validate_sig_info, + should_validate_input, + )?; let mut validated_msg = decrypted_msg.clone(); let mut reply_params: Option> = None; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index f66648259..6a472f0d5 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -8,7 +8,8 @@ use cw_types_generic::BaseEnv; use cw_types_v010::types::{CanonicalAddr, Coin, HumanAddr}; use enclave_cosmos_types::traits::CosmosAminoPubkey; use enclave_cosmos_types::types::{ - ContractCode, CosmWasmMsg, CosmosPubKey, HandleType, SigInfo, SignDoc, StdSignDoc, + ContractCode, CosmWasmMsg, CosmosPubKey, FungibleTokenPacketData, HandleType, IbcHooksWasmMsg, + SigInfo, SignDoc, StdSignDoc, }; use enclave_crypto::traits::VerifyingKey; use enclave_crypto::{sha_256, AESKey, Hmac, Kdf, HASH_SIZE, KEY_MANAGER}; @@ -21,6 +22,9 @@ use crate::types::SecretMessage; #[cfg(feature = "light-client-validation")] use block_verifier::VERIFIED_MESSAGES; +use sha2::{Digest, Sha256}; +extern crate hex; + pub type ContractKey = [u8; CONTRACT_KEY_LENGTH]; pub const CONTRACT_KEY_LENGTH: usize = HASH_SIZE + HASH_SIZE; @@ -359,88 +363,100 @@ pub fn verify_params( contract_address: &HumanAddr, msg: &SecretMessage, og_msg: &[u8], + should_validate_sig_info: bool, + should_validate_input: bool, ) -> Result<(), EnclaveError> { - debug!("Verifying message signatures for: {:?}", sig_info); - - //let start = Instant::now(); - // If there's no callback signature - it's not a callback and there has to be a tx signer + signature - if let Some(callback_sig) = &sig_info.callback_sig { - return verify_callback_sig(callback_sig.as_slice(), sender, msg, sent_funds); - } - // let duration = start.elapsed(); - // trace!( - // "verify_params: Time elapsed in verify_callback_sig: {:?}", - // duration - // ); - #[cfg(feature = "light-client-validation")] - if !check_msg_matches_state(og_msg) { - return Err(EnclaveError::ValidationFailure); - } - // check if sign_bytes are in approved tx list + if should_validate_sig_info { + debug!("Verifying message signatures for: {:?}", sig_info); - trace!( - "Sign bytes are: {:?}", - String::from_utf8_lossy(sig_info.sign_bytes.as_slice()) - ); + //let start = Instant::now(); + // If there's no callback signature - it's not a callback and there has to be a tx signer + signature + if let Some(callback_sig) = &sig_info.callback_sig { + return verify_callback_sig(callback_sig.as_slice(), sender, msg, sent_funds); + } + // let duration = start.elapsed(); + // trace!( + // "verify_params: Time elapsed in verify_callback_sig: {:?}", + // duration + // ); + #[cfg(feature = "light-client-validation")] + if !check_msg_matches_state(og_msg) { + return Err(EnclaveError::ValidationFailure); + } + // check if sign_bytes are in approved tx list - //let start = Instant::now(); - let (sender_public_key, messages) = get_signer_and_messages(sig_info, sender)?; - // let duration = start.elapsed(); - // trace!( - // "verify_params: Time elapsed in get_signer_and_messages: {:?}", - // duration - // ); - - trace!( - "sender canonical address is: {:?}", - sender_public_key.get_address().0 .0 - ); - trace!("sender signature is: {:?}", sig_info.signature); - trace!("sign bytes are: {:?}", sig_info.sign_bytes); - - //let start = Instant::now(); - sender_public_key - .verify_bytes( - sig_info.sign_bytes.as_slice(), - sig_info.signature.as_slice(), - sig_info.sign_mode, - ) - .map_err(|err| { - warn!("Signature verification failed: {:?}", err); - EnclaveError::FailedTxVerification - })?; - // let duration = start.elapsed(); - // trace!( - // "verify_params: Time elapsed in verify_bytes: {:?}", - // duration - // ); - - // let start = Instant::now(); - if verify_message_params( - &messages, - sender, - sent_funds, - contract_address, - &sender_public_key, - msg, - ) { - info!("Parameters verified successfully"); - return Ok(()); + trace!( + "Sign bytes are: {:?}", + String::from_utf8_lossy(sig_info.sign_bytes.as_slice()) + ); + + //let start = Instant::now(); + let sender_public_key = get_signer(sig_info, sender)?; + // let duration = start.elapsed(); + // trace!( + // "verify_params: Time elapsed in get_signer_and_messages: {:?}", + // duration + // ); + + trace!( + "sender canonical address is: {:?}", + sender_public_key.get_address().0 .0 + ); + trace!("sender signature is: {:?}", sig_info.signature); + trace!("sign bytes are: {:?}", sig_info.sign_bytes); + + //let start = Instant::now(); + sender_public_key + .verify_bytes( + sig_info.sign_bytes.as_slice(), + sig_info.signature.as_slice(), + sig_info.sign_mode, + ) + .map_err(|err| { + warn!("Signature verification failed: {:?}", err); + EnclaveError::FailedTxVerification + })?; + // let duration = start.elapsed(); + // trace!( + // "verify_params: Time elapsed in verify_bytes: {:?}", + // duration + // ); + + let signer_addr = sender_public_key.get_address(); + if &signer_addr != sender { + warn!("Sender verification failed!"); + trace!( + "Message sender {:?} does not match with the message signer {:?}", + sender, + signer_addr + ); + return Err(EnclaveError::FailedTxVerification); + } } - // let duration = start.elapsed(); - // trace!( - // "verify_params: Time elapsed in verify_message_params: {:?}", - // duration - // ); - warn!("Parameter verification failed"); - Err(EnclaveError::FailedTxVerification) + if should_validate_input { + let messages = get_messages(sig_info)?; + + // let start = Instant::now(); + let is_verified = + verify_message_params(&messages, sender, sent_funds, contract_address, msg); + // let duration = start.elapsed(); + // trace!( + // "verify_params: Time elapsed in verify_message_params: {:?}", + // duration + // ); + + if !is_verified { + warn!("Parameter verification failed"); + return Err(EnclaveError::FailedTxVerification); + } + } + + info!("Parameters verified successfully"); + return Ok(()); } -fn get_signer_and_messages( - sign_info: &SigInfo, - sender: &CanonicalAddr, -) -> Result<(CosmosPubKey, Vec), EnclaveError> { +fn get_signer(sign_info: &SigInfo, sender: &CanonicalAddr) -> Result { use cosmos_proto::tx::signing::SignMode::*; match sign_info.sign_mode { SIGN_MODE_DIRECT => { @@ -457,7 +473,7 @@ fn get_signer_and_messages( EnclaveError::FailedTxVerification })?; - Ok((sender_public_key.clone(), sign_doc.body.messages)) + Ok(sender_public_key.clone()) } SIGN_MODE_LEGACY_AMINO_JSON => { use protobuf::well_known_types::Any as AnyProto; @@ -472,17 +488,8 @@ fn get_signer_and_messages( warn!("failure to parse pubkey: {:?}", err); EnclaveError::FailedTxVerification })?; - let sign_doc: StdSignDoc = serde_json::from_slice(sign_info.sign_bytes.as_slice()) - .map_err(|err| { - warn!("failure to parse StdSignDoc: {:?}", err); - EnclaveError::FailedTxVerification - })?; - let messages: Result, _> = sign_doc - .msgs - .iter() - .map(|x| x.clone().into_cosmwasm_msg()) - .collect(); - Ok((public_key, messages?)) + + Ok(public_key) } SIGN_MODE_EIP_191 => { use protobuf::well_known_types::Any as AnyProto; @@ -498,6 +505,41 @@ fn get_signer_and_messages( EnclaveError::FailedTxVerification })?; + Ok(public_key) + } + _ => { + warn!( + "get_signer(): unsupported signature mode: {:?}", + sign_info.sign_mode + ); + Err(EnclaveError::FailedTxVerification) + } + } +} + +fn get_messages(sign_info: &SigInfo) -> Result, EnclaveError> { + use cosmos_proto::tx::signing::SignMode::*; + match sign_info.sign_mode { + SIGN_MODE_DIRECT => { + let sign_doc = SignDoc::from_bytes(sign_info.sign_bytes.as_slice())?; + trace!("sign doc: {:?}", sign_doc); + + Ok(sign_doc.body.messages) + } + SIGN_MODE_LEGACY_AMINO_JSON => { + let sign_doc: StdSignDoc = serde_json::from_slice(sign_info.sign_bytes.as_slice()) + .map_err(|err| { + warn!("failure to parse StdSignDoc: {:?}", err); + EnclaveError::FailedTxVerification + })?; + let messages: Result, _> = sign_doc + .msgs + .iter() + .map(|x| x.clone().into_cosmwasm_msg()) + .collect(); + Ok(messages?) + } + SIGN_MODE_EIP_191 => { let sign_bytes_as_string = String::from_utf8_lossy(&sign_info.sign_bytes.0).to_string(); trace!( @@ -531,10 +573,13 @@ fn get_signer_and_messages( .iter() .map(|x| x.clone().into_cosmwasm_msg()) .collect(); - Ok((public_key, messages?)) + Ok(messages?) } _ => { - warn!("unsupported signature mode: {:?}", sign_info.sign_mode); + warn!( + "get_messages(): unsupported signature mode: {:?}", + sign_info.sign_mode + ); Err(EnclaveError::FailedTxVerification) } } @@ -596,6 +641,7 @@ fn get_verified_msg<'sd>( sender, .. } => msg_sender == sender && &sent_msg.to_vec() == msg, + CosmWasmMsg::MsgRecvPacket { data, .. } => sent_msg.msg == *data, CosmWasmMsg::Other => false, }) } @@ -618,6 +664,91 @@ fn verify_contract(msg: &CosmWasmMsg, contract_address: &HumanAddr) -> bool { } CosmWasmMsg::Instantiate { .. } => true, CosmWasmMsg::Other => false, + CosmWasmMsg::MsgRecvPacket { + destination_port, + data, + .. + } => { + if destination_port == "transfer" { + // Packet was routed here through ibc-hooks + + // Parse data as FungibleTokenPacketData JSON + let packet_data: FungibleTokenPacketData = match serde_json::from_slice( + data.as_slice(), + ) { + Ok(packet_data) => packet_data, + Err(err) => { + trace!( + "Contract was called via ibc-hooks but packet_data cannot be parsed as FungibleTokenPacketData: {:?} Error: {:?}", + String::from_utf8_lossy(data.as_slice()), + err, + ); + return false; + } + }; + + // memo must be set in ibc-hooks + let memo = match packet_data.memo { + Some(memo) => memo, + None => { + trace!("Contract was called via ibc-hooks but packet_data.memo is empty"); + return false; + } + }; + + // Parse data.memo as IbcHooksWasmMsg JSON + let wasm_msg: IbcHooksWasmMsg = match serde_json::from_slice(memo.as_bytes()) { + Ok(wasm_msg) => wasm_msg, + Err(err) => { + trace!( + "Contract was called via ibc-hooks but packet_data.memo cannot be parsed as IbcHooksWasmMsg: {:?} Error: {:?}", + memo, + err, + ); + return false; + } + }; + + // In ibc-hooks contract_address == packet_data.memo.wasm.contract == packet_data.receiver + let is_verified = *contract_address == packet_data.receiver + && *contract_address == wasm_msg.contract; + if !is_verified { + trace!( + "Contract address sent to enclave {:?} is not the same as in ibc-hooks packet receiver={:?} memo={:?}", + contract_address, + packet_data.receiver, + wasm_msg.contract + ); + } + is_verified + } else { + // Packet is for an IBC enabled contract + // destination_port is of the form "wasm.{contract_address}" + + // Extract contract_address from destination_port + // This also checks that destination_port starts with "wasm." + let contract_address_from_port = match destination_port.strip_prefix("wasm.") { + Some(contract_address) => contract_address, + None => { + trace!( + "Contract was called via MsgRecvPacket but destination_port doesn't start with \"wasm.\": {:?}", + destination_port, + ); + return false; + } + }; + + let is_verified = *contract_address == HumanAddr::from(contract_address_from_port); + if !is_verified { + trace!( + "Contract address sent to enclave {:?} is not the same as extracted from MsgRecvPacket but destination_port: {:?}", + contract_address, + contract_address_from_port, + ); + } + is_verified + } + } } } @@ -630,6 +761,113 @@ fn verify_funds(msg: &CosmWasmMsg, sent_funds_msg: &[Coin]) -> bool { .. } => sent_funds_msg == sent_funds, CosmWasmMsg::Other => false, + CosmWasmMsg::MsgRecvPacket { + data, + source_port, + source_channel, + destination_port, + destination_channel, + .. + } => { + if destination_port == "transfer" { + // Packet was routed here through ibc-hooks + + // Should be just one coin + if sent_funds_msg.len() != 1 { + trace!( + "Contract was called via ibc-hooks but sent_funds_msg.len() != 1: {:?}", + sent_funds_msg, + ); + return false; + } + + let sent_funds_msg_coin = &sent_funds_msg[0]; + + // Parse data as FungibleTokenPacketData JSON + let packet_data: FungibleTokenPacketData = match serde_json::from_slice( + data.as_slice(), + ) { + Ok(packet_data) => packet_data, + Err(err) => { + trace!( + "Contract was called via ibc-hooks but packet_data cannot be parsed as FungibleTokenPacketData: {:?} Error: {:?}", + String::from_utf8_lossy(data.as_slice()), + err, + ); + return false; + } + }; + + // Check amount + if sent_funds_msg_coin.amount != packet_data.amount { + trace!( + "Contract was called via ibc-hooks but sent_funds_msg_coin.amount != packet_data.amount: {:?} != {:?}", + sent_funds_msg_coin.amount, + packet_data.amount, + ); + return false; + } + + // The packet's denom is the denom in the sender chain. + // It needs to be converted to the local denom. + // Logic source: https://github.com/scrtlabs/SecretNetwork/blob/96b0ba7d6/x/ibc-hooks/wasm_hook.go#L483-L513 + let denom: String = if receiver_chain_is_source( + &source_port, + &source_channel, + &packet_data.denom, + ) { + // remove prefix added by sender chain + let voucher_prefix = get_denom_prefix(&source_port, &source_channel); + + let unprefixed_denom: String = match packet_data + .denom + .strip_prefix(&voucher_prefix) + { + Some(unprefixed_denom) => unprefixed_denom.to_string(), + None => { + trace!( + "Contract was called via ibc-hooks but packet_data.denom doesn't start with voucher_prefix: {:?} != {:?}", + packet_data.denom, + voucher_prefix, + ); + return false; + } + }; + + // The denomination used to send the coins is either the native denom or the hash of the path + // if the denomination is not native. + let denom_trace = parse_denom_trace(&unprefixed_denom); + if denom_trace.path != "" { + denom_trace.ibc_denom() + } else { + unprefixed_denom + } + } else { + let prefixed_denom = get_denom_prefix(&destination_port, &destination_channel) + + &packet_data.denom; + let denom = parse_denom_trace(&prefixed_denom).ibc_denom(); + + denom + }; + + // Check denom + if sent_funds_msg_coin.denom != denom { + trace!( + "Contract was called via ibc-hooks but sent_funds_msg_coin.denom != denom: {:?} != {:?}", + sent_funds_msg_coin.denom, + denom, + ); + return false; + } + + true + } else { + // Packet is for an IBC enabled contract + + // No funds should be sent + sent_funds_msg.len() == 0 + } + } } } @@ -638,28 +876,11 @@ fn verify_message_params( sender: &CanonicalAddr, sent_funds: &[Coin], contract_address: &HumanAddr, - signer_public_key: &CosmosPubKey, sent_msg: &SecretMessage, ) -> bool { - debug!("Verifying sender.."); + debug!("Verifying sender..."); - // let msg_sender = match CanonicalAddr::from_human(&env.message.sender) { - // Ok(msg_sender) => msg_sender, - // _ => return false, - // }; - - let signer_addr = signer_public_key.get_address(); - if &signer_addr != sender { - warn!("Sender verification failed!"); - trace!( - "Message sender {:?} does not match with the message signer {:?}", - sender, - signer_addr - ); - return false; - } - - info!("Verifying message.."); + info!("Verifying message..."); // If msg is not found (is None) then it means message verification failed, // since it didn't find a matching signed message let msg = get_verified_msg(messages, sender, sent_msg); @@ -675,14 +896,23 @@ fn verify_message_params( } let msg = msg.unwrap(); - if msg.sender() != Some(&signer_addr) { - warn!( - "message signer did not match cosmwasm message sender: {:?} {:?}", - signer_addr, msg - ); - return false; + match msg { + CosmWasmMsg::MsgRecvPacket { .. } => { + // No sender to verify. + // Going to pass null sender to the contract if all other checks pass. + } + CosmWasmMsg::Execute { .. } | CosmWasmMsg::Instantiate { .. } | CosmWasmMsg::Other => { + if msg.sender() != Some(&sender) { + warn!( + "message sender did not match cosmwasm message sender: {:?} {:?}", + sender, msg + ); + return false; + } + } } + info!("Verifying contract address.."); if !verify_contract(msg, contract_address) { warn!("Contract address verification failed!"); return false; @@ -696,3 +926,135 @@ fn verify_message_params( true } + +/// ReceiverChainIsSource returns true if the denomination originally came +/// from the receiving chain and false otherwise. +fn receiver_chain_is_source(source_port: &str, source_channel: &str, denom: &str) -> bool { + // The prefix passed in should contain the SourcePort and SourceChannel. + // If the receiver chain originally sent the token to the sender chain + // the denom will have the sender's SourcePort and SourceChannel as the + // prefix. + let voucher_prefix = get_denom_prefix(source_port, source_channel); + denom.starts_with(&voucher_prefix) +} + +/// GetDenomPrefix returns the receiving denomination prefix +fn get_denom_prefix(port_id: &str, channel_id: &str) -> String { + format!("{}/{}", port_id, channel_id) +} + +/// DenomTrace contains the base denomination for ICS20 fungible tokens and the +/// source tracing information path. +struct DenomTrace { + /// path defines the chain of port/channel identifiers used for tracing the + /// source of the fungible token. + path: String, + /// base denomination of the relayed fungible token. + base_denom: String, +} + +impl DenomTrace { + /// Hash returns the hex bytes of the SHA256 hash of the DenomTrace fields using the following formula: + /// hash = sha256(tracePath + "/" + baseDenom) + pub fn hash(&self) -> Vec { + let hash = Sha256::digest(self.get_full_denom_path().as_bytes()); + hash.to_vec() + } + + /// IBCDenom a coin denomination for an ICS20 fungible token in the format + /// 'ibc/{hash(tracePath + baseDenom)}'. If the trace is empty, it will return the base denomination. + pub fn ibc_denom(&self) -> String { + if !self.path.is_empty() { + format!("ibc/{}", hex::encode(self.hash())) + } else { + self.base_denom.clone() + } + } + + /// GetFullDenomPath returns the full denomination according to the ICS20 specification: + /// tracePath + "/" + baseDenom + /// If there exists no trace then the base denomination is returned. + pub fn get_full_denom_path(&self) -> String { + if self.path.is_empty() { + self.base_denom.clone() + } else { + self.get_prefix() + &self.base_denom + } + } + + // GetPrefix returns the receiving denomination prefix composed by the trace info and a separator. + fn get_prefix(&self) -> String { + return format!("{}/", self.path); + } +} + +/// ParseDenomTrace parses a string with the ibc prefix (denom trace) and the base denomination +/// into a DenomTrace type. +/// +/// Examples: +/// +/// - "portidone/channel-0/uatom" => DenomTrace{Path: "portidone/channel-0", BaseDenom: "uatom"} +/// - "portidone/channel-0/portidtwo/channel-1/uatom" => DenomTrace{Path: "portidone/channel-0/portidtwo/channel-1", BaseDenom: "uatom"} +/// - "portidone/channel-0/gamm/pool/1" => DenomTrace{Path: "portidone/channel-0", BaseDenom: "gamm/pool/1"} +/// - "gamm/pool/1" => DenomTrace{Path: "", BaseDenom: "gamm/pool/1"} +/// - "uatom" => DenomTrace{Path: "", BaseDenom: "uatom"} +fn parse_denom_trace(raw_denom: &str) -> DenomTrace { + let denom_split: Vec<&str> = raw_denom.split('/').collect(); + + if denom_split.len() == 1 { + return DenomTrace { + path: "".to_string(), + base_denom: raw_denom.to_string(), + }; + } + + let (path, base_denom) = extract_path_and_base_from_full_denom(&denom_split); + + DenomTrace { + path: path.to_string(), + base_denom: base_denom.to_string(), + } +} + +/// extract_path_and_base_from_full_denom returns the trace path and the base denom from +/// the elements that constitute the complete denom. +fn extract_path_and_base_from_full_denom(full_denom_items: &[&str]) -> (String, String) { + let mut path = vec![]; + let mut base_denom = vec![]; + + let length = full_denom_items.len(); + let mut i = 0; + + while i < length { + // The IBC specification does not guarantee the expected format of the + // destination port or destination channel identifier. A short term solution + // to determine base denomination is to expect the channel identifier to be the + // one ibc-go specifies. A longer term solution is to separate the path and base + // denomination in the ICS20 packet. If an intermediate hop prefixes the full denom + // with a channel identifier format different from our own, the base denomination + // will be incorrectly parsed, but the token will continue to be treated correctly + // as an IBC denomination. The hash used to store the token internally on our chain + // will be the same value as the base denomination being correctly parsed. + if i < length - 1 && length > 2 && is_valid_channel_id(full_denom_items[i + 1]) { + path.push(full_denom_items[i].to_owned()); + path.push(full_denom_items[i + 1].to_owned()); + i += 2; + } else { + base_denom = full_denom_items[i..].to_vec(); + break; + } + } + + (path.join("/"), base_denom.join("/")) +} + +/// IsValidChannelID checks if a channelID is valid and can be parsed to the channel +/// identifier format. +fn is_valid_channel_id(channel_id: &str) -> bool { + parse_channel_sequence(channel_id).is_some() +} + +/// ParseChannelSequence parses the channel sequence from the channel identifier. +fn parse_channel_sequence(channel_id: &str) -> Option<&str> { + channel_id.strip_prefix("channel-") +} diff --git a/cosmwasm/enclaves/shared/contract-engine/src/execute_message.rs b/cosmwasm/enclaves/shared/contract-engine/src/execute_message.rs index 9f09f34cc..a9f915930 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/execute_message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/execute_message.rs @@ -12,6 +12,7 @@ pub fn parse_execute_message(message: &[u8]) -> Result Result Result Result { trace!( @@ -32,7 +31,10 @@ pub fn parse_message( parse_plaintext_ibc_protocol_message(message) } - HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => parse_ibc_receive_message(message), + HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE + | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { + parse_ibc_receive_message(message) + } }; } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/reply_message.rs b/cosmwasm/enclaves/shared/contract-engine/src/reply_message.rs index 782fb895b..dd9899d64 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/reply_message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/reply_message.rs @@ -157,6 +157,7 @@ fn wrap_results_as_parsed_message( Ok(ParsedMessage { should_validate_sig_info: true, + should_validate_input: true, was_msg_encrypted: true, should_encrypt_output: true, secret_msg: reply_secret_msg, @@ -286,6 +287,7 @@ fn parse_plaintext_reply_message( // It's also not possible to validate with our current design, since contracts // don't know if their output is a reply to another contract, thus can't sign it as such should_validate_sig_info: false, + should_validate_input: false, was_msg_encrypted: false, should_encrypt_output: parsed_reply.was_orig_msg_encrypted, secret_msg: reply_secret_msg, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/types.rs b/cosmwasm/enclaves/shared/contract-engine/src/types.rs index 6ab9e9da0..616f31792 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/types.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/types.rs @@ -16,6 +16,7 @@ pub struct SecretMessage { pub struct ParsedMessage { pub should_validate_sig_info: bool, + pub should_validate_input: bool, pub was_msg_encrypted: bool, pub should_encrypt_output: bool, pub secret_msg: SecretMessage, diff --git a/cosmwasm/enclaves/shared/cosmos-proto/build.rs b/cosmwasm/enclaves/shared/cosmos-proto/build.rs index ccb854a7b..239c6f043 100644 --- a/cosmwasm/enclaves/shared/cosmos-proto/build.rs +++ b/cosmwasm/enclaves/shared/cosmos-proto/build.rs @@ -100,6 +100,7 @@ mod protobuf { from_ibc("core/client/v1/client.proto"), ], ), + ("src/ibc", &[from_cosmos("upgrade/v1beta1/upgrade.proto")]), ]; for (out_dir, inputs) in directories { diff --git a/cosmwasm/enclaves/shared/cosmos-proto/src/ibc/upgrade.rs b/cosmwasm/enclaves/shared/cosmos-proto/src/ibc/upgrade.rs new file mode 100644 index 000000000..3f1df19e0 --- /dev/null +++ b/cosmwasm/enclaves/shared/cosmos-proto/src/ibc/upgrade.rs @@ -0,0 +1,1061 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `cosmos/upgrade/v1beta1/upgrade.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct Plan { + // message fields + pub name: ::std::string::String, + pub time: ::protobuf::SingularPtrField<::protobuf::well_known_types::Timestamp>, + pub height: i64, + pub info: ::std::string::String, + pub upgraded_client_state: ::protobuf::SingularPtrField<::protobuf::well_known_types::Any>, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Plan { + fn default() -> &'a Plan { + ::default_instance() + } +} + +impl Plan { + pub fn new() -> Plan { + ::std::default::Default::default() + } + + // string name = 1; + + + pub fn get_name(&self) -> &str { + &self.name + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + &mut self.name + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.name, ::std::string::String::new()) + } + + // .google.protobuf.Timestamp time = 2; + + + pub fn get_time(&self) -> &::protobuf::well_known_types::Timestamp { + self.time.as_ref().unwrap_or_else(|| <::protobuf::well_known_types::Timestamp as ::protobuf::Message>::default_instance()) + } + pub fn clear_time(&mut self) { + self.time.clear(); + } + + pub fn has_time(&self) -> bool { + self.time.is_some() + } + + // Param is passed by value, moved + pub fn set_time(&mut self, v: ::protobuf::well_known_types::Timestamp) { + self.time = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_time(&mut self) -> &mut ::protobuf::well_known_types::Timestamp { + if self.time.is_none() { + self.time.set_default(); + } + self.time.as_mut().unwrap() + } + + // Take field + pub fn take_time(&mut self) -> ::protobuf::well_known_types::Timestamp { + self.time.take().unwrap_or_else(|| ::protobuf::well_known_types::Timestamp::new()) + } + + // int64 height = 3; + + + pub fn get_height(&self) -> i64 { + self.height + } + pub fn clear_height(&mut self) { + self.height = 0; + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i64) { + self.height = v; + } + + // string info = 4; + + + pub fn get_info(&self) -> &str { + &self.info + } + pub fn clear_info(&mut self) { + self.info.clear(); + } + + // Param is passed by value, moved + pub fn set_info(&mut self, v: ::std::string::String) { + self.info = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_info(&mut self) -> &mut ::std::string::String { + &mut self.info + } + + // Take field + pub fn take_info(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.info, ::std::string::String::new()) + } + + // .google.protobuf.Any upgraded_client_state = 5; + + + pub fn get_upgraded_client_state(&self) -> &::protobuf::well_known_types::Any { + self.upgraded_client_state.as_ref().unwrap_or_else(|| <::protobuf::well_known_types::Any as ::protobuf::Message>::default_instance()) + } + pub fn clear_upgraded_client_state(&mut self) { + self.upgraded_client_state.clear(); + } + + pub fn has_upgraded_client_state(&self) -> bool { + self.upgraded_client_state.is_some() + } + + // Param is passed by value, moved + pub fn set_upgraded_client_state(&mut self, v: ::protobuf::well_known_types::Any) { + self.upgraded_client_state = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_upgraded_client_state(&mut self) -> &mut ::protobuf::well_known_types::Any { + if self.upgraded_client_state.is_none() { + self.upgraded_client_state.set_default(); + } + self.upgraded_client_state.as_mut().unwrap() + } + + // Take field + pub fn take_upgraded_client_state(&mut self) -> ::protobuf::well_known_types::Any { + self.upgraded_client_state.take().unwrap_or_else(|| ::protobuf::well_known_types::Any::new()) + } +} + +impl ::protobuf::Message for Plan { + fn is_initialized(&self) -> bool { + for v in &self.time { + if !v.is_initialized() { + return false; + } + }; + for v in &self.upgraded_client_state { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; + }, + 2 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.time)?; + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int64()?; + self.height = tmp; + }, + 4 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.info)?; + }, + 5 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.upgraded_client_state)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.name.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.name); + } + if let Some(ref v) = self.time.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if self.height != 0 { + my_size += ::protobuf::rt::value_size(3, self.height, ::protobuf::wire_format::WireTypeVarint); + } + if !self.info.is_empty() { + my_size += ::protobuf::rt::string_size(4, &self.info); + } + if let Some(ref v) = self.upgraded_client_state.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.name.is_empty() { + os.write_string(1, &self.name)?; + } + if let Some(ref v) = self.time.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if self.height != 0 { + os.write_int64(3, self.height)?; + } + if !self.info.is_empty() { + os.write_string(4, &self.info)?; + } + if let Some(ref v) = self.upgraded_client_state.as_ref() { + os.write_tag(5, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Plan { + Plan::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &Plan| { &m.name }, + |m: &mut Plan| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<::protobuf::well_known_types::Timestamp>>( + "time", + |m: &Plan| { &m.time }, + |m: &mut Plan| { &mut m.time }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( + "height", + |m: &Plan| { &m.height }, + |m: &mut Plan| { &mut m.height }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "info", + |m: &Plan| { &m.info }, + |m: &mut Plan| { &mut m.info }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<::protobuf::well_known_types::Any>>( + "upgraded_client_state", + |m: &Plan| { &m.upgraded_client_state }, + |m: &mut Plan| { &mut m.upgraded_client_state }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Plan", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Plan { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Plan::new) + } +} + +impl ::protobuf::Clear for Plan { + fn clear(&mut self) { + self.name.clear(); + self.time.clear(); + self.height = 0; + self.info.clear(); + self.upgraded_client_state.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Plan { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Plan { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct SoftwareUpgradeProposal { + // message fields + pub title: ::std::string::String, + pub description: ::std::string::String, + pub plan: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a SoftwareUpgradeProposal { + fn default() -> &'a SoftwareUpgradeProposal { + ::default_instance() + } +} + +impl SoftwareUpgradeProposal { + pub fn new() -> SoftwareUpgradeProposal { + ::std::default::Default::default() + } + + // string title = 1; + + + pub fn get_title(&self) -> &str { + &self.title + } + pub fn clear_title(&mut self) { + self.title.clear(); + } + + // Param is passed by value, moved + pub fn set_title(&mut self, v: ::std::string::String) { + self.title = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_title(&mut self) -> &mut ::std::string::String { + &mut self.title + } + + // Take field + pub fn take_title(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.title, ::std::string::String::new()) + } + + // string description = 2; + + + pub fn get_description(&self) -> &str { + &self.description + } + pub fn clear_description(&mut self) { + self.description.clear(); + } + + // Param is passed by value, moved + pub fn set_description(&mut self, v: ::std::string::String) { + self.description = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_description(&mut self) -> &mut ::std::string::String { + &mut self.description + } + + // Take field + pub fn take_description(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.description, ::std::string::String::new()) + } + + // .cosmos.upgrade.v1beta1.Plan plan = 3; + + + pub fn get_plan(&self) -> &Plan { + self.plan.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_plan(&mut self) { + self.plan.clear(); + } + + pub fn has_plan(&self) -> bool { + self.plan.is_some() + } + + // Param is passed by value, moved + pub fn set_plan(&mut self, v: Plan) { + self.plan = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_plan(&mut self) -> &mut Plan { + if self.plan.is_none() { + self.plan.set_default(); + } + self.plan.as_mut().unwrap() + } + + // Take field + pub fn take_plan(&mut self) -> Plan { + self.plan.take().unwrap_or_else(|| Plan::new()) + } +} + +impl ::protobuf::Message for SoftwareUpgradeProposal { + fn is_initialized(&self) -> bool { + for v in &self.plan { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.title)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.description)?; + }, + 3 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.plan)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.title.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.title); + } + if !self.description.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.description); + } + if let Some(ref v) = self.plan.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.title.is_empty() { + os.write_string(1, &self.title)?; + } + if !self.description.is_empty() { + os.write_string(2, &self.description)?; + } + if let Some(ref v) = self.plan.as_ref() { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> SoftwareUpgradeProposal { + SoftwareUpgradeProposal::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "title", + |m: &SoftwareUpgradeProposal| { &m.title }, + |m: &mut SoftwareUpgradeProposal| { &mut m.title }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "description", + |m: &SoftwareUpgradeProposal| { &m.description }, + |m: &mut SoftwareUpgradeProposal| { &mut m.description }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "plan", + |m: &SoftwareUpgradeProposal| { &m.plan }, + |m: &mut SoftwareUpgradeProposal| { &mut m.plan }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SoftwareUpgradeProposal", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static SoftwareUpgradeProposal { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SoftwareUpgradeProposal::new) + } +} + +impl ::protobuf::Clear for SoftwareUpgradeProposal { + fn clear(&mut self) { + self.title.clear(); + self.description.clear(); + self.plan.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for SoftwareUpgradeProposal { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SoftwareUpgradeProposal { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct CancelSoftwareUpgradeProposal { + // message fields + pub title: ::std::string::String, + pub description: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CancelSoftwareUpgradeProposal { + fn default() -> &'a CancelSoftwareUpgradeProposal { + ::default_instance() + } +} + +impl CancelSoftwareUpgradeProposal { + pub fn new() -> CancelSoftwareUpgradeProposal { + ::std::default::Default::default() + } + + // string title = 1; + + + pub fn get_title(&self) -> &str { + &self.title + } + pub fn clear_title(&mut self) { + self.title.clear(); + } + + // Param is passed by value, moved + pub fn set_title(&mut self, v: ::std::string::String) { + self.title = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_title(&mut self) -> &mut ::std::string::String { + &mut self.title + } + + // Take field + pub fn take_title(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.title, ::std::string::String::new()) + } + + // string description = 2; + + + pub fn get_description(&self) -> &str { + &self.description + } + pub fn clear_description(&mut self) { + self.description.clear(); + } + + // Param is passed by value, moved + pub fn set_description(&mut self, v: ::std::string::String) { + self.description = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_description(&mut self) -> &mut ::std::string::String { + &mut self.description + } + + // Take field + pub fn take_description(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.description, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for CancelSoftwareUpgradeProposal { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.title)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.description)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.title.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.title); + } + if !self.description.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.description); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.title.is_empty() { + os.write_string(1, &self.title)?; + } + if !self.description.is_empty() { + os.write_string(2, &self.description)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> CancelSoftwareUpgradeProposal { + CancelSoftwareUpgradeProposal::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "title", + |m: &CancelSoftwareUpgradeProposal| { &m.title }, + |m: &mut CancelSoftwareUpgradeProposal| { &mut m.title }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "description", + |m: &CancelSoftwareUpgradeProposal| { &m.description }, + |m: &mut CancelSoftwareUpgradeProposal| { &mut m.description }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CancelSoftwareUpgradeProposal", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CancelSoftwareUpgradeProposal { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CancelSoftwareUpgradeProposal::new) + } +} + +impl ::protobuf::Clear for CancelSoftwareUpgradeProposal { + fn clear(&mut self) { + self.title.clear(); + self.description.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CancelSoftwareUpgradeProposal { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CancelSoftwareUpgradeProposal { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct ModuleVersion { + // message fields + pub name: ::std::string::String, + pub version: u64, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a ModuleVersion { + fn default() -> &'a ModuleVersion { + ::default_instance() + } +} + +impl ModuleVersion { + pub fn new() -> ModuleVersion { + ::std::default::Default::default() + } + + // string name = 1; + + + pub fn get_name(&self) -> &str { + &self.name + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + &mut self.name + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.name, ::std::string::String::new()) + } + + // uint64 version = 2; + + + pub fn get_version(&self) -> u64 { + self.version + } + pub fn clear_version(&mut self) { + self.version = 0; + } + + // Param is passed by value, moved + pub fn set_version(&mut self, v: u64) { + self.version = v; + } +} + +impl ::protobuf::Message for ModuleVersion { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_uint64()?; + self.version = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.name.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.name); + } + if self.version != 0 { + my_size += ::protobuf::rt::value_size(2, self.version, ::protobuf::wire_format::WireTypeVarint); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.name.is_empty() { + os.write_string(1, &self.name)?; + } + if self.version != 0 { + os.write_uint64(2, self.version)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> ModuleVersion { + ModuleVersion::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &ModuleVersion| { &m.name }, + |m: &mut ModuleVersion| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint64>( + "version", + |m: &ModuleVersion| { &m.version }, + |m: &mut ModuleVersion| { &mut m.version }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ModuleVersion", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static ModuleVersion { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ModuleVersion::new) + } +} + +impl ::protobuf::Clear for ModuleVersion { + fn clear(&mut self) { + self.name.clear(); + self.version = 0; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for ModuleVersion { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ModuleVersion { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n$cosmos/upgrade/v1beta1/upgrade.proto\x12\x16cosmos.upgrade.v1beta1\ + \x1a\x19google/protobuf/any.proto\x1a\x14gogoproto/gogo.proto\x1a\x1fgoo\ + gle/protobuf/timestamp.proto\"\xfa\x01\n\x04Plan\x12\x12\n\x04name\x18\ + \x01\x20\x01(\tR\x04name\x12:\n\x04time\x18\x02\x20\x01(\x0b2\x1a.google\ + .protobuf.TimestampR\x04timeB\n\x18\x01\x90\xdf\x1f\x01\xc8\xde\x1f\0\ + \x12\x16\n\x06height\x18\x03\x20\x01(\x03R\x06height\x12\x12\n\x04info\ + \x18\x04\x20\x01(\tR\x04info\x12l\n\x15upgraded_client_state\x18\x05\x20\ + \x01(\x0b2\x14.google.protobuf.AnyR\x13upgradedClientStateB\"\x18\x01\ + \xf2\xde\x1f\x1cyaml:\"upgraded_client_state\":\x08\xe8\xa0\x1f\x01\x98\ + \xa0\x1f\0\"\x93\x01\n\x17SoftwareUpgradeProposal\x12\x14\n\x05title\x18\ + \x01\x20\x01(\tR\x05title\x12\x20\n\x0bdescription\x18\x02\x20\x01(\tR\ + \x0bdescription\x126\n\x04plan\x18\x03\x20\x01(\x0b2\x1c.cosmos.upgrade.\ + v1beta1.PlanR\x04planB\x04\xc8\xde\x1f\0:\x08\xe8\xa0\x1f\x01\x98\xa0\ + \x1f\0\"a\n\x1dCancelSoftwareUpgradeProposal\x12\x14\n\x05title\x18\x01\ + \x20\x01(\tR\x05title\x12\x20\n\x0bdescription\x18\x02\x20\x01(\tR\x0bde\ + scription:\x08\xe8\xa0\x1f\x01\x98\xa0\x1f\0\"G\n\rModuleVersion\x12\x12\ + \n\x04name\x18\x01\x20\x01(\tR\x04name\x12\x18\n\x07version\x18\x02\x20\ + \x01(\x04R\x07version:\x08\xe8\xa0\x1f\x01\x98\xa0\x1f\x01B2Z,github.com\ + /cosmos/cosmos-sdk/x/upgrade/types\xc8\xe1\x1e\0b\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/cosmwasm/enclaves/shared/cosmos-proto/src/lib.rs b/cosmwasm/enclaves/shared/cosmos-proto/src/lib.rs index bce066631..6c6fa5882 100644 --- a/cosmwasm/enclaves/shared/cosmos-proto/src/lib.rs +++ b/cosmwasm/enclaves/shared/cosmos-proto/src/lib.rs @@ -46,4 +46,5 @@ pub mod ibc { pub mod channel; pub mod client; pub mod tx; + pub mod upgrade; } diff --git a/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml b/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml index 145383f29..8f6298eae 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml +++ b/cosmwasm/enclaves/shared/cosmos-types/Cargo.toml @@ -31,3 +31,4 @@ num_enum = { version = "0.5.7", default-features = false } prost = { git = "https://github.com/mesalock-linux/prost-sgx", rev = "cd3103a6d45cf7a43b6c1c5e4223428097d1c547", default-features = false, features = [ "prost-derive" ] } +serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" } diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 7aa35c54e..462f6bd40 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -385,6 +385,23 @@ impl StdCosmWasmMsg { } } +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] + +pub struct FungibleTokenPacketData { + pub denom: String, + pub amount: Uint128, + pub sender: HumanAddr, + pub receiver: HumanAddr, + pub memo: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] + +pub struct IbcHooksWasmMsg { + pub contract: HumanAddr, + pub msg: serde_json::Value, +} + #[derive(Debug)] pub enum CosmWasmMsg { // CosmWasm: @@ -412,6 +429,15 @@ pub enum CosmWasmMsg { // MsgAcknowledgement {}, // TODO // MsgTimeout {}, // TODO MsgRecvPacket { + sequence: u64, + source_port: String, + source_channel: String, + /// if the packet is sent into an IBC-enabled contract, `destination_port` will be `"wasm.{contract_address}"` + /// if the packet is rounted here via ibc-hooks, `destination_port` will be `"transfer"` + destination_port: String, + destination_channel: String, + /// if the packet is sent into an IBC-enabled contract, this will be raw bytes + /// if the packet is rounted here via ibc-hooks, this will be a JSON string of the type `FungibleTokenPacketData` (https://github.com/cosmos/ibc-go/blob/v4.3.0/modules/apps/transfer/types/packet.pb.go#L25-L39) data: Vec, }, // All else: @@ -472,7 +498,7 @@ impl CosmWasmMsg { // todo!() // } - fn try_parse_msg_recv_packet(bytes: &[u8]) -> Result { + fn try_parse_recv_packet(bytes: &[u8]) -> Result { use proto::ibc::tx::MsgRecvPacket; let raw_msg = MsgRecvPacket::parse_from_bytes(bytes) @@ -480,7 +506,14 @@ impl CosmWasmMsg { match raw_msg.packet.into_option() { None => Err(EnclaveError::FailedToDeserialize), - Some(packet) => Ok(CosmWasmMsg::MsgRecvPacket { data: packet.data }), + Some(packet) => Ok(CosmWasmMsg::MsgRecvPacket { + sequence: packet.sequence, + source_port: packet.source_port, + source_channel: packet.source_channel, + destination_port: packet.destination_port, + destination_channel: packet.destination_channel, + data: packet.data, + }), } } @@ -576,6 +609,7 @@ impl CosmWasmMsg { CosmWasmMsg::Execute { sender, .. } | CosmWasmMsg::Instantiate { sender, .. } => { Some(sender) } + CosmWasmMsg::MsgRecvPacket { .. } => None, CosmWasmMsg::Other => None, } } diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs index 30baacaad..3092b4108 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs @@ -37,6 +37,10 @@ impl HumanAddr { self.0.is_empty() } pub fn from_canonical(canonical_addr: &CanonicalAddr) -> Result { + if canonical_addr.is_empty() { + return Ok(HumanAddr::from("")); + } + let human_addr_str = bech32::encode( BECH32_PREFIX_ACC_ADDR, canonical_addr.as_slice().to_base32(), @@ -75,6 +79,10 @@ impl CanonicalAddr { self.0.is_empty() } pub fn from_human(human_addr: &HumanAddr) -> Result { + if human_addr.is_empty() { + return Ok(CanonicalAddr(Binary(vec![]))); + } + let (decoded_prefix, data) = bech32::decode(human_addr.as_str())?; let canonical = Vec::::from_base32(&data)?; diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 8332b48e8..1d85d80bd 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -21,6 +21,7 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" codedctypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/x/auth/ante" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" @@ -37,7 +38,6 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" sdktx "github.com/cosmos/cosmos-sdk/types/tx" sdktxsigning "github.com/cosmos/cosmos-sdk/types/tx/signing" - "github.com/cosmos/cosmos-sdk/x/auth/ante" wasm "github.com/scrtlabs/SecretNetwork/go-cosmwasm" v010wasmTypes "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types/v010" @@ -185,28 +185,13 @@ func (k Keeper) importCode(ctx sdk.Context, codeID uint64, codeInfo types.CodeIn return nil } -func (k Keeper) GetSignerInfo(ctx sdk.Context, signer sdk.AccAddress) ([]byte, sdktxsigning.SignMode, []byte, []byte, []byte, error) { +func (k Keeper) GetTxInfo(ctx sdk.Context, signer sdk.AccAddress) ([]byte, sdktxsigning.SignMode, []byte, []byte, []byte, error) { tx := sdktx.Tx{} err := k.cdc.Unmarshal(ctx.TxBytes(), &tx) if err != nil { return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to decode transaction from bytes: %s", err.Error())) } - // for MsgInstantiateContract, there is only one signer which is msg.Sender - // (https://github.com/scrtlabs/SecretNetwork/blob/d7813792fa07b93a10f0885eaa4c5e0a0a698854/x/compute/internal/types/msg.go#L192-L194) - signerAcc, err := ante.GetSignerAcc(ctx, k.accountKeeper, signer) - if err != nil { - return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to retrieve account by address: %s", err.Error())) - } - - txConfig := authtx.NewTxConfig(k.cdc.(*codec.ProtoCodec), authtx.DefaultSignModes) - modeHandler := txConfig.SignModeHandler() - signingData := authsigning.SignerData{ - ChainID: ctx.ChainID(), - AccountNumber: signerAcc.GetAccountNumber(), - Sequence: signerAcc.GetSequence() - 1, - } - protobufTx := authtx.WrapTx(&tx).GetTx() pubKeys, err := protobufTx.GetPubKeys() @@ -238,6 +223,31 @@ func (k Keeper) GetSignerInfo(ctx sdk.Context, signer sdk.AccAddress) ([]byte, s case *sdktxsigning.MultiSignatureData: signMode = sdktxsigning.SignMode_SIGN_MODE_LEGACY_AMINO_JSON } + + if signer == nil { + // Assaf: + // We are in a situation where the contract gets a null msg.sender, + // however we still need to get the sign bytes for verification against the wasm input msg inside the enclave. + // There can be multiple signers on the tx, for example one can be the msg.sender and the another can be the gas fee payer. Another example is if this tx also contains MsgMultiSend which supports multiple msg.senders thus requiring multiple signers. + // Not sure if we should support this or if this even matters here, as we're most likely here because it's an incoming IBC tx and the signer is the relayer. + // Gor now we will just take the first signer. + + signer = protobufTx.GetSigners()[0] + } + + signerAcc, err := ante.GetSignerAcc(ctx, k.accountKeeper, signer) + if err != nil { + return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to retrieve account by address: %s", err.Error())) + } + + txConfig := authtx.NewTxConfig(k.cdc.(*codec.ProtoCodec), authtx.DefaultSignModes) + modeHandler := txConfig.SignModeHandler() + signingData := authsigning.SignerData{ + ChainID: ctx.ChainID(), + AccountNumber: signerAcc.GetAccountNumber(), + Sequence: signerAcc.GetSequence() - 1, + } + signBytes, err := modeHandler.GetSignBytes(signMode, signingData, protobufTx) if err != nil { return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to recreate sign bytes for the tx: %s", err.Error())) @@ -338,7 +348,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre // If no callback signature - we should send the actual msg sender sign bytes and signature if callbackSig == nil { - signBytes, signMode, modeInfoBytes, pkBytes, signerSig, err = k.GetSignerInfo(ctx, creator) + signBytes, signMode, modeInfoBytes, pkBytes, signerSig, err = k.GetTxInfo(ctx, creator) if err != nil { return nil, nil, err } @@ -499,25 +509,15 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller signerSig := []byte{} var err error - ibcHooks := false - if handleType == wasmTypes.HandleTypeIbcWasmHooksIncomingTransfer || - handleType == wasmTypes.HandleTypeIbcWasmHooksOutgoingTransferAck || - handleType == wasmTypes.HandleTypeIbcWasmHooksOutgoingTransferTimeout { - ibcHooks = true - } - // If no callback signature - we should send the actual msg sender sign bytes and signature - if callbackSig == nil && !ibcHooks { - signBytes, signMode, modeInfoBytes, pkBytes, signerSig, err = k.GetSignerInfo(ctx, caller) + if callbackSig == nil { + signBytes, signMode, modeInfoBytes, pkBytes, signerSig, err = k.GetTxInfo(ctx, caller) if err != nil { return nil, err } } verificationInfo := types.NewVerificationInfo(signBytes, signMode, modeInfoBytes, pkBytes, signerSig, callbackSig) - if ibcHooks { - verificationInfo = types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_DIRECT, []byte{}, []byte{}, []byte{}, nil) - } contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) if err != nil { diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index ee3905b0a..b42b87b9e 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -22,7 +22,12 @@ func (k Keeper) ibcContractCall(ctx sdk.Context, msgBz []byte, callType wasmTypes.HandleType, ) (interface{}, error) { - verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) + signBytes, signMode, modeInfoBytes, pkBytes, signerSig, err := k.GetTxInfo(ctx, nil) + if err != nil { + return nil, err + } + + verificationInfo := types.NewVerificationInfo(signBytes, signMode, modeInfoBytes, pkBytes, signerSig, nil) _, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) if err != nil { diff --git a/x/ibc-hooks/README.md b/x/ibc-hooks/README.md index d7af83407..dca17b988 100644 --- a/x/ibc-hooks/README.md +++ b/x/ibc-hooks/README.md @@ -5,7 +5,7 @@ Different behaviors on Secret vs. Osmosis: - When receiving a token over IBC, instead of the scrambled sender on the Osmosis, on Secret the contract sees the sender as an empty string. -- When using `ibc_callback` with `IbcMsg::Transfer` from a non IBC contract, on Secret the ack/timeout will be sent to the `execute` endpoint instead of to the `sudo` endpoint. +- When using `ibc_callback` with `IbcMsg::Transfer` from a non IBC contract, on Secret the ack/timeout will be sent to the `execute` endpoint instead of to the `sudo` endpoint. ## Wasm Hooks @@ -70,8 +70,8 @@ ICS20 is JSON native, so we use JSON for the memo format. "data": { "denom": "denom on counterparty chain (e.g. uatom)", // will be transformed to the local denom (ibc/...) "amount": "1000", - "sender": "addr on counterparty chain", // will be transformed - "receiver": "contract addr or blank", + "sender": "addr on counterparty chain", // will be ignored and shown to the contract as a null sender (cannot be verifed over IBC) + "receiver": "secret1contractAddr", "memo": { "wasm": { "contract": "secret1contractAddr", @@ -91,7 +91,7 @@ An ICS20 packet is formatted correctly for wasmhooks iff the following all hold: - `memo` has at least one key, with value `"wasm"` - `memo["wasm"]` has exactly two entries, `"contract"` and `"msg"` - `memo["wasm"]["msg"]` is a valid JSON object -- `receiver == "" || receiver == memo["wasm"]["contract"]` +- `receiver == memo["wasm"]["contract"]` We consider an ICS20 packet as directed towards wasmhooks iff all of the following hold: From 9e10473f24e820affe4db418daae65d0e48d1170 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 8 May 2023 14:59:21 +0300 Subject: [PATCH 03/54] Miscellaneous --- .vscode/settings.json | 3 ++- cmd/secretd/root.go | 2 +- x/compute/client/cli/query.go | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index dbab00de1..572c8be72 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,7 +13,8 @@ "integration-tests/contract-v1/Cargo.toml", "integration-tests/contract-v0.10/Cargo.toml", "go-cosmwasm/Cargo.toml", - "cosmwasm/enclaves/shared/cosmos-proto/Cargo.toml" + "cosmwasm/enclaves/shared/cosmos-proto/Cargo.toml", + "cosmwasm/enclaves/shared/contract-engine/Cargo.toml" ], "rust-analyzer.diagnostics.experimental.enable": true, "rust-analyzer.rustfmt.rangeFormatting.enable": true, diff --git a/cmd/secretd/root.go b/cmd/secretd/root.go index 9b473ccc2..53a0bc7d1 100644 --- a/cmd/secretd/root.go +++ b/cmd/secretd/root.go @@ -286,7 +286,7 @@ func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts serverty bootstrap := cast.ToBool(appOpts.Get("bootstrap")) - // fmt.Printf("bootstrap: %s", cast.ToString(bootstrap)) + // fmt.Printf("bootstrap: %s\n", cast.ToString(bootstrap)) return app.NewSecretNetworkApp(logger, db, traceStore, true, skipUpgradeHeights, cast.ToString(appOpts.Get(flags.FlagHome)), diff --git a/x/compute/client/cli/query.go b/x/compute/client/cli/query.go index e3bf8f93d..6e17166a2 100644 --- a/x/compute/client/cli/query.go +++ b/x/compute/client/cli/query.go @@ -141,7 +141,7 @@ func GetCmdCodeHashByContractAddress() *cobra.Command { } addr := hex.EncodeToString(res) - fmt.Printf("0x%s", addr) + fmt.Printf("0x%s\n", addr) return nil }, } @@ -332,7 +332,7 @@ func CmdDecryptText() *cobra.Command { return fmt.Errorf("error while trying to decrypt the output data: %w", err) } - fmt.Printf("Decrypted data: %s", dataPlaintextB64Bz) + fmt.Printf("Decrypted data: %s\n", dataPlaintextB64Bz) return nil }, } From 3f61d64de1d84e0a54b1966cc384df432bec60e5 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 10 May 2023 13:25:24 +0300 Subject: [PATCH 04/54] Lint --- x/compute/internal/keeper/keeper.go | 14 +++++++------- x/compute/internal/keeper/test_common.go | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 1d85d80bd..89bfdae6e 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -920,12 +920,12 @@ func (k Keeper) generateContractAddress(ctx sdk.Context, codeID uint64, creator func contractAddress(codeID, instanceID uint64, creator sdk.AccAddress) sdk.AccAddress { contractId := codeID<<32 + instanceID - contractIdBytes := make([]byte, 8) - binary.BigEndian.PutUint64(contractIdBytes, contractId) + hashSourceBytes := make([]byte, 8) + binary.BigEndian.PutUint64(hashSourceBytes, contractId) - sourceBytes := append(contractIdBytes, creator...) + hashSourceBytes = append(hashSourceBytes, creator...) - sha := sha256.Sum256(sourceBytes) + sha := sha256.Sum256(hashSourceBytes) hasherRIPEMD160 := ripemd160.New() hasherRIPEMD160.Write(sha[:]) // does not error return sdk.AccAddress(hasherRIPEMD160.Sum(nil)) @@ -1059,11 +1059,11 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w // instantiate wasm contract gas := gasForContract(ctx) - marshaledReply, error := json.Marshal(reply) + marshaledReply, err := json.Marshal(reply) marshaledReply = append(ogTx[0:64], marshaledReply...) - if error != nil { - return nil, error + if err != nil { + return nil, err } response, gasUsed, execErr := k.wasmer.Execute(codeInfo.CodeHash, env, marshaledReply, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, ogSigInfo, wasmTypes.HandleTypeReply) diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index 96599b6db..895815707 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -524,7 +524,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc router.AddRoute(sdk.NewRoute(wasmtypes.RouterKey, TestHandler(keeper))) random := make([]byte, 32) - rand.Read(random) + _, _ = rand.Read(random) keeper.SetRandomSeed(ctx, random) am := module.NewManager( // minimal module set that we use for message/ query tests From 176d66b6e38161952f661a03607d3cd43266732d Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 10 May 2023 13:25:57 +0300 Subject: [PATCH 05/54] Checkpoint: continue to simplify msg verification process --- go-cosmwasm/types/v1/ibc.go | 9 + x/compute/internal/keeper/ibc_test.go | 214 ++++++++++++++++++----- x/compute/internal/keeper/keeper.go | 101 ++++++----- x/compute/internal/keeper/test_common.go | 41 ++++- 4 files changed, 272 insertions(+), 93 deletions(-) diff --git a/go-cosmwasm/types/v1/ibc.go b/go-cosmwasm/types/v1/ibc.go index 9cea18534..aa594c53e 100644 --- a/go-cosmwasm/types/v1/ibc.go +++ b/go-cosmwasm/types/v1/ibc.go @@ -1,6 +1,7 @@ package v1types import ( + ibcchanneltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" types "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types" v010msgtypes "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types/v010" ) @@ -164,6 +165,14 @@ const ( Ordered = "ORDER_ORDERED" ) +func IBCOrderToEnum(o IBCOrder) ibcchanneltypes.Order { + if o == Unordered { + return ibcchanneltypes.UNORDERED + } else { + return ibcchanneltypes.ORDERED + } +} + // IBCTimeoutBlock Height is a monotonically increasing data type // that can be compared against another Height for the purposes of updating and // freezing clients. diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index e53ba79b8..1629cd089 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -17,14 +17,23 @@ import ( "github.com/scrtlabs/SecretNetwork/x/compute/internal/types" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/libs/log" + + ibcclienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + ibcchanneltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" ) const defaultGasForIbcTests = 600_000 func ibcChannelConnectHelper( - t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, - gas uint64, shouldSendOpenAck bool, channel v1types.IBCChannel, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contract sdk.AccAddress, + relayer sdk.AccAddress, + relayerPrivkey crypto.PrivKey, + gas uint64, + shouldSendOpenAck bool, + channel v1types.IBCChannel, ) (sdk.Context, []ContractEvent, cosmwasm.StdError) { // create new ctx with the same storage and a gas limit // this is to reset the event manager, so we won't get @@ -46,6 +55,18 @@ func ibcChannelConnectHelper( }, OpenConfirm: nil, } + + msg := ibcchanneltypes.MsgChannelOpenAck{ + PortId: channel.Endpoint.PortID, + ChannelId: channel.Endpoint.ChannelID, + CounterpartyChannelId: channel.CounterpartyEndpoint.ChannelID, + CounterpartyVersion: channel.Version, + ProofTry: []byte{}, + ProofHeight: ibcclienttypes.Height{}, + Signer: relayer.String(), + } + + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &msg) } else { ibcChannelConnectMsg = v1types.IBCChannelConnectMsg{ OpenAck: nil, @@ -53,9 +74,19 @@ func ibcChannelConnectHelper( Channel: channel, }, } + + msg := ibcchanneltypes.MsgChannelOpenConfirm{ + PortId: channel.Endpoint.PortID, + ChannelId: channel.Endpoint.ChannelID, + ProofAck: []byte{}, + ProofHeight: ibcclienttypes.Height{}, + Signer: relayer.String(), + } + + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &msg) } - err := keeper.OnConnectChannel(ctx, contractAddr, ibcChannelConnectMsg) + err := keeper.OnConnectChannel(ctx, contract, ibcChannelConnectMsg) require.NotZero(t, gasMeter.GetWasmCounter(), err) @@ -70,9 +101,15 @@ func ibcChannelConnectHelper( } func ibcChannelOpenHelper( - t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, - gas uint64, shouldSendOpenTry bool, channel v1types.IBCChannel, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contract sdk.AccAddress, + relayer sdk.AccAddress, + relayerPrivkey crypto.PrivKey, + gas uint64, + shouldSendOpenTry bool, + channel v1types.IBCChannel, ) (string, cosmwasm.StdError) { // create new ctx with the same storage and a gas limit // this is to reset the event manager, so we won't get @@ -94,6 +131,26 @@ func ibcChannelOpenHelper( }, OpenInit: nil, } + + msg := ibcchanneltypes.MsgChannelOpenTry{ + PortId: channel.Endpoint.PortID, + PreviousChannelId: "", + Channel: ibcchanneltypes.Channel{ + State: ibcchanneltypes.TRYOPEN, + Ordering: v1types.IBCOrderToEnum(channel.Order), + Counterparty: ibcchanneltypes.Counterparty{ + PortId: channel.CounterpartyEndpoint.PortID, + ChannelId: channel.CounterpartyEndpoint.ChannelID, + }, + ConnectionHops: []string{}, + Version: channel.Version, + }, + CounterpartyVersion: channel.Version, + ProofInit: []byte{}, + ProofHeight: ibcclienttypes.Height{}, + Signer: relayer.String(), + } + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &msg) } else { ibcChannelOpenMsg = v1types.IBCChannelOpenMsg{ OpenTry: nil, @@ -101,9 +158,25 @@ func ibcChannelOpenHelper( Channel: channel, }, } + + msg := ibcchanneltypes.MsgChannelOpenInit{ + PortId: channel.Endpoint.PortID, + Channel: ibcchanneltypes.Channel{ + State: ibcchanneltypes.INIT, + Ordering: v1types.IBCOrderToEnum(channel.Order), + Counterparty: ibcchanneltypes.Counterparty{ + PortId: channel.CounterpartyEndpoint.PortID, + ChannelId: channel.CounterpartyEndpoint.ChannelID, + }, + ConnectionHops: []string{}, + Version: channel.Version, + }, + Signer: relayer.String(), + } + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &msg) } - res, err := keeper.OnOpenChannel(ctx, contractAddr, ibcChannelOpenMsg) + res, err := keeper.OnOpenChannel(ctx, contract, ibcChannelOpenMsg) require.NotZero(t, gasMeter.GetWasmCounter(), err) @@ -115,9 +188,15 @@ func ibcChannelOpenHelper( } func ibcChannelCloseHelper( - t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, - gas uint64, shouldSendCloseConfirn bool, channel v1types.IBCChannel, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contract sdk.AccAddress, + relayer sdk.AccAddress, + relayerPrivkey crypto.PrivKey, + gas uint64, + shouldSendCloseConfirn bool, + channel v1types.IBCChannel, ) (sdk.Context, []ContractEvent, cosmwasm.StdError) { // create new ctx with the same storage and a gas limit // this is to reset the event manager, so we won't get @@ -138,6 +217,15 @@ func ibcChannelCloseHelper( }, CloseInit: nil, } + + msg := ibcchanneltypes.MsgChannelCloseConfirm{ + PortId: channel.Endpoint.PortID, + ChannelId: channel.Endpoint.ChannelID, + ProofInit: []byte{}, + ProofHeight: ibcclienttypes.Height{}, + Signer: relayer.String(), + } + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &msg) } else { ibcChannelCloseMsg = v1types.IBCChannelCloseMsg{ CloseConfirm: nil, @@ -145,9 +233,16 @@ func ibcChannelCloseHelper( Channel: channel, }, } + + msg := ibcchanneltypes.MsgChannelCloseInit{ + PortId: channel.Endpoint.PortID, + ChannelId: channel.Endpoint.ChannelID, + Signer: relayer.String(), + } + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &msg) } - err := keeper.OnCloseChannel(ctx, contractAddr, ibcChannelCloseMsg) + err := keeper.OnCloseChannel(ctx, contract, ibcChannelCloseMsg) require.NotZero(t, gasMeter.GetWasmCounter(), err) @@ -186,9 +281,15 @@ func createIBCPacket(src v1types.IBCEndpoint, dest v1types.IBCEndpoint, sequence } func ibcPacketReceiveHelper( - t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, - shouldEncryptMsg bool, gas uint64, packet v1types.IBCPacket, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contractAddr sdk.AccAddress, + relayer sdk.AccAddress, + relayerPrivkey crypto.PrivKey, + shouldEncryptMsg bool, + gas uint64, + packet v1types.IBCPacket, ) (sdk.Context, []byte, []ContractEvent, []byte, cosmwasm.StdError) { var nonce []byte internalPacket := packet @@ -225,6 +326,27 @@ func ibcPacketReceiveHelper( Relayer: "relayer", } + msg := ibcchanneltypes.MsgRecvPacket{ + Packet: ibcchanneltypes.Packet{ + Sequence: internalPacket.Sequence, + SourcePort: internalPacket.Src.PortID, + SourceChannel: internalPacket.Src.ChannelID, + DestinationPort: internalPacket.Dest.PortID, + DestinationChannel: internalPacket.Dest.ChannelID, + Data: internalPacket.Data, + TimeoutHeight: ibcclienttypes.Height{ + RevisionNumber: internalPacket.Timeout.Block.Revision, + RevisionHeight: internalPacket.Timeout.Block.Height, + }, + TimeoutTimestamp: internalPacket.Timeout.Timestamp, + }, + ProofCommitment: []byte{}, + ProofHeight: ibcclienttypes.Height{}, + Signer: relayer.String(), + } + + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &msg) + res, err := keeper.OnRecvPacket(ctx, contractAddr, ibcPacketReceiveMsg) require.NotZero(t, gasMeter.GetWasmCounter(), err) @@ -320,9 +442,9 @@ func ibcPacketTimeoutHelper( } func TestIBCChannelOpen(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) require.Empty(t, err) ibcChannel := v1types.IBCChannel{ @@ -333,7 +455,7 @@ func TestIBCChannelOpen(t *testing.T) { ConnectionID: "1", } - version, err := ibcChannelOpenHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, false, ibcChannel) + version, err := ibcChannelOpenHelper(t, keeper, ctx, contractAddress, walletA, privkeyA, defaultGasForTests, false, ibcChannel) require.Empty(t, err) require.Equal(t, version, "ibc-v1") @@ -344,9 +466,9 @@ func TestIBCChannelOpen(t *testing.T) { } func TestIBCChannelOpenTry(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) require.Empty(t, err) ibcChannel := v1types.IBCChannel{ @@ -357,7 +479,7 @@ func TestIBCChannelOpenTry(t *testing.T) { ConnectionID: "1", } - version, err := ibcChannelOpenHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, true, ibcChannel) + version, err := ibcChannelOpenHelper(t, keeper, ctx, contractAddress, walletA, privkeyA, defaultGasForTests, true, ibcChannel) require.Empty(t, err) require.Equal(t, version, "ibc-v1") @@ -368,9 +490,9 @@ func TestIBCChannelOpenTry(t *testing.T) { } func TestIBCChannelConnect(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) require.Empty(t, err) for _, test := range []struct { @@ -439,7 +561,7 @@ func TestIBCChannelConnect(t *testing.T) { ConnectionID: test.connectionID, } - ctx, events, err := ibcChannelConnectHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForIbcTests, false, ibcChannel) + ctx, events, err := ibcChannelConnectHelper(t, keeper, ctx, contractAddress, walletA, privkeyA, defaultGasForIbcTests, false, ibcChannel) if !test.isSuccess { require.Contains(t, fmt.Sprintf("%+v", err), "Intentional") @@ -492,9 +614,9 @@ func TestIBCChannelConnect(t *testing.T) { } func TestIBCChannelConnectOpenAck(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) require.Empty(t, err) ibcChannel := v1types.IBCChannel{ @@ -505,7 +627,7 @@ func TestIBCChannelConnectOpenAck(t *testing.T) { ConnectionID: "1", } - ctx, _, err = ibcChannelConnectHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, true, ibcChannel) + ctx, _, err = ibcChannelConnectHelper(t, keeper, ctx, contractAddress, walletA, privkeyA, defaultGasForTests, true, ibcChannel) require.Empty(t, err) queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) @@ -515,9 +637,9 @@ func TestIBCChannelConnectOpenAck(t *testing.T) { } func TestIBCChannelClose(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) require.Empty(t, err) for _, test := range []struct { @@ -586,7 +708,7 @@ func TestIBCChannelClose(t *testing.T) { ConnectionID: test.connectionID, } - ctx, events, err := ibcChannelCloseHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForIbcTests, true, ibcChannel) + ctx, events, err := ibcChannelCloseHelper(t, keeper, ctx, contractAddress, walletA, privkeyA, defaultGasForIbcTests, true, ibcChannel) if !test.isSuccess { require.Contains(t, fmt.Sprintf("%+v", err), "Intentional") @@ -639,9 +761,9 @@ func TestIBCChannelClose(t *testing.T) { } func TestIBCChannelCloseInit(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) require.Empty(t, err) ibcChannel := v1types.IBCChannel{ @@ -652,7 +774,7 @@ func TestIBCChannelCloseInit(t *testing.T) { ConnectionID: "1", } - ctx, _, err = ibcChannelCloseHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForTests, false, ibcChannel) + ctx, _, err = ibcChannelCloseHelper(t, keeper, ctx, contractAddress, walletA, privkeyA, defaultGasForTests, false, ibcChannel) require.Empty(t, err) queryRes, err := queryHelper(t, keeper, ctx, contractAddress, `{"q":{}}`, true, true, math.MaxUint64) @@ -662,9 +784,9 @@ func TestIBCChannelCloseInit(t *testing.T) { } func TestIBCPacketReceive(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForTests) require.Empty(t, err) for _, isEncrypted := range []bool{false, true} { for _, test := range []struct { @@ -739,7 +861,7 @@ func TestIBCPacketReceive(t *testing.T) { createIBCTimeout(math.MaxUint64), []byte{}, ) - ctx, nonce, events, data, err := ibcPacketReceiveHelper(t, keeper, ctx, contractAddress, privKeyA, isEncrypted, defaultGasForIbcTests, ibcPacket) + ctx, nonce, events, data, err := ibcPacketReceiveHelper(t, keeper, ctx, contractAddress, walletA, privkeyA, isEncrypted, defaultGasForIbcTests, ibcPacket) if !test.isSuccess { require.Contains(t, fmt.Sprintf("%+v", err), "Intentional") @@ -799,7 +921,7 @@ type ContractInfo struct { } func TestIBCPacketReceiveCallsV010Contract(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) wasmCode, err := os.ReadFile(TestContractPaths[v010Contract]) require.NoError(t, err) @@ -811,9 +933,9 @@ func TestIBCPacketReceiveCallsV010Contract(t *testing.T) { require.NoError(t, err) v010CodeHash := hex.EncodeToString(codeInfo.CodeHash) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) require.Empty(t, err) - _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privKeyA, `{"counter":{"counter":10}}`, true, false, defaultGasForIbcTests) + _, _, v010ContractAddress, _, err := initHelper(t, keeper, ctx, v010CodeID, walletA, privkeyA, `{"counter":{"counter":10}}`, true, false, defaultGasForIbcTests) require.Empty(t, err) contractInfo := ContractInfo{ Address: v010ContractAddress.String(), @@ -834,7 +956,7 @@ func TestIBCPacketReceiveCallsV010Contract(t *testing.T) { for _, isEncrypted := range []bool{true, true} { t.Run(fmt.Sprintf("Encryption:%t", isEncrypted), func(t *testing.T) { - ctx, _, _, data, err := ibcPacketReceiveHelper(t, keeper, ctx, contractAddress, privKeyA, isEncrypted, defaultGasForIbcTests, ibcPacket) + ctx, _, _, data, err := ibcPacketReceiveHelper(t, keeper, ctx, contractAddress, walletA, privkeyA, isEncrypted, defaultGasForIbcTests, ibcPacket) require.Empty(t, err) require.Equal(t, "\"out\"", string(data)) @@ -856,9 +978,9 @@ func TestIBCPacketReceiveCallsV010Contract(t *testing.T) { } func TestIBCPacketAck(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) require.Empty(t, err) for _, test := range []struct { @@ -928,7 +1050,7 @@ func TestIBCPacketAck(t *testing.T) { ack := make([]byte, 8) binary.LittleEndian.PutUint64(ack, uint64(test.sequence)) - ctx, events, err := ibcPacketAckHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForIbcTests, ibcPacket, ack) + ctx, events, err := ibcPacketAckHelper(t, keeper, ctx, contractAddress, privkeyA, defaultGasForIbcTests, ibcPacket, ack) if !test.isSuccess { require.Contains(t, fmt.Sprintf("%+v", err), "Intentional") @@ -981,9 +1103,9 @@ func TestIBCPacketAck(t *testing.T) { } func TestIBCPacketTimeout(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) + ctx, keeper, codeID, _, walletA, privkeyA, _, _ := setupTest(t, TestContractPaths[ibcContract], sdk.NewCoins()) - _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) + _, _, contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privkeyA, `{"init":{}}`, true, true, defaultGasForIbcTests) require.Empty(t, err) for _, test := range []struct { @@ -1051,7 +1173,7 @@ func TestIBCPacketTimeout(t *testing.T) { []byte{}, ) - ctx, events, err := ibcPacketTimeoutHelper(t, keeper, ctx, contractAddress, privKeyA, defaultGasForIbcTests, ibcPacket) + ctx, events, err := ibcPacketTimeoutHelper(t, keeper, ctx, contractAddress, privkeyA, defaultGasForIbcTests, ibcPacket) if !test.isSuccess { require.Contains(t, fmt.Sprintf("%+v", err), "Intentional") diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 89bfdae6e..b04c43b5a 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -15,7 +15,7 @@ import ( channelkeeper "github.com/cosmos/ibc-go/v4/modules/core/04-channel/keeper" portkeeper "github.com/cosmos/ibc-go/v4/modules/core/05-port/keeper" wasmTypes "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types" - "golang.org/x/crypto/ripemd160" + "golang.org/x/crypto/ripemd160" //nolint:staticcheck "github.com/cosmos/cosmos-sdk/telemetry" @@ -23,7 +23,6 @@ import ( codedctypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/x/auth/ante" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" - authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" @@ -110,7 +109,7 @@ func NewKeeper( supportedFeatures string, customEncoders *MessageEncoders, customPlugins *QueryPlugins, - LastMsgManager *baseapp.LastMsgMarkerContainer, + lastMsgManager *baseapp.LastMsgMarkerContainer, ) Keeper { wasmer, err := wasm.NewWasmer(filepath.Join(homeDir, "wasm"), supportedFeatures, wasmConfig.CacheSize, wasmConfig.EnclaveCacheSize) if err != nil { @@ -129,7 +128,7 @@ func NewKeeper( messenger: NewMessageHandler(msgRouter, legacyMsgRouter, customEncoders, channelKeeper, capabilityKeeper, portSource, cdc), queryGasLimit: wasmConfig.SmartQueryGasLimit, HomeDir: homeDir, - LastMsgManager: LastMsgManager, + LastMsgManager: lastMsgManager, } keeper.queryPlugins = DefaultQueryPlugins(govKeeper, distKeeper, mintKeeper, bankKeeper, stakingKeeper, queryRouter, &keeper, channelKeeper).Merge(customPlugins) @@ -185,34 +184,69 @@ func (k Keeper) importCode(ctx sdk.Context, codeID uint64, codeInfo types.CodeIn return nil } -func (k Keeper) GetTxInfo(ctx sdk.Context, signer sdk.AccAddress) ([]byte, sdktxsigning.SignMode, []byte, []byte, []byte, error) { - tx := sdktx.Tx{} - err := k.cdc.Unmarshal(ctx.TxBytes(), &tx) +func (k Keeper) GetTxInfo(ctx sdk.Context, sender sdk.AccAddress) ([]byte, sdktxsigning.SignMode, []byte, []byte, []byte, error) { + var rawTx sdktx.TxRaw + err := k.cdc.Unmarshal(ctx.TxBytes(), &rawTx) if err != nil { - return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to decode transaction from bytes: %s", err.Error())) + return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to decode raw transaction from bytes: %s", err.Error())) } - protobufTx := authtx.WrapTx(&tx).GetTx() - - pubKeys, err := protobufTx.GetPubKeys() + var txAuthInfo sdktx.AuthInfo + err = k.cdc.Unmarshal(rawTx.AuthInfoBytes, &txAuthInfo) + if err != nil { + return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to decode transaction auth info from bytes: %s", err.Error())) + } + + // Assaf: + // We're not decoding Body as it is unnecessary in this context, + // and it fails decoding IBC messages with the error "no concrete type registered for type URL /ibc.core.channel.v1.MsgChannelOpenInit against interface *types.Msg". + // I think that's because the core IBC messages don't support Amino encoding, + // and a "concrete type" is used to refer to the mapping between the Go struct and the Amino type string (e.g. "cosmos-sdk/MsgSend") + // Therefore we'll ignore the Body here. + // Plus this probably saves CPU cycles to not decode the body. + tx := authtx.WrapTx(&sdktx.Tx{ + Body: nil, + AuthInfo: &txAuthInfo, + Signatures: rawTx.Signatures, + }).GetTx() + + pubKeys, err := tx.GetPubKeys() if err != nil { return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to get public keys for instantiate: %s", err.Error())) } pkIndex := -1 - var _signers [][]byte // This is just used for the error message below - for index, pubKey := range pubKeys { - thisSigner := pubKey.Address().Bytes() - _signers = append(_signers, thisSigner) - if bytes.Equal(thisSigner, signer.Bytes()) { - pkIndex = index + if sender == nil { + // Assaf: + // We are in a situation where the contract gets a null msg.sender, + // however we still need to get the sign bytes for verification against the wasm input msg inside the enclave. + // There can be multiple signers on the tx, for example one can be the msg.sender and the another can be the gas fee payer. Another example is if this tx also contains MsgMultiSend which supports multiple msg.senders thus requiring multiple signers. + // Not sure if we should support this or if this even matters here, as we're most likely here because it's an incoming IBC tx and the signer is the relayer. + // For now we will just take the first signer. + // Also, because we're not decoding the tx body anymore, we can't use tx.GetSigners() here. Therefore we'll convert the pubkey into an address. + + pubkeys, err := tx.GetPubKeys() + if err != nil { + return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to retrieve pubkeys from tx: %s", err.Error())) + } + + pkIndex = 0 + sender = sdk.AccAddress(pubkeys[pkIndex].Address()) + } else { + var _signers [][]byte // This is just used for the error message below + for index, pubKey := range pubKeys { + thisSigner := pubKey.Address().Bytes() + _signers = append(_signers, thisSigner) + if bytes.Equal(thisSigner, sender.Bytes()) { + pkIndex = index + } + } + if pkIndex == -1 { + return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Message sender: %v is not found in the tx signer set: %v, callback signature not provided", sender, _signers)) } - } - if pkIndex == -1 { - return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Message sender: %v is not found in the tx signer set: %v, callback signature not provided", signer, _signers)) } - signatures, err := protobufTx.GetSignaturesV2() + signatures, err := tx.GetSignaturesV2() if err != nil { return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to get signatures: %s", err.Error())) } @@ -224,31 +258,12 @@ func (k Keeper) GetTxInfo(ctx sdk.Context, signer sdk.AccAddress) ([]byte, sdktx signMode = sdktxsigning.SignMode_SIGN_MODE_LEGACY_AMINO_JSON } - if signer == nil { - // Assaf: - // We are in a situation where the contract gets a null msg.sender, - // however we still need to get the sign bytes for verification against the wasm input msg inside the enclave. - // There can be multiple signers on the tx, for example one can be the msg.sender and the another can be the gas fee payer. Another example is if this tx also contains MsgMultiSend which supports multiple msg.senders thus requiring multiple signers. - // Not sure if we should support this or if this even matters here, as we're most likely here because it's an incoming IBC tx and the signer is the relayer. - // Gor now we will just take the first signer. - - signer = protobufTx.GetSigners()[0] - } - - signerAcc, err := ante.GetSignerAcc(ctx, k.accountKeeper, signer) + signerAcc, err := ante.GetSignerAcc(ctx, k.accountKeeper, sender) if err != nil { return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to retrieve account by address: %s", err.Error())) } - txConfig := authtx.NewTxConfig(k.cdc.(*codec.ProtoCodec), authtx.DefaultSignModes) - modeHandler := txConfig.SignModeHandler() - signingData := authsigning.SignerData{ - ChainID: ctx.ChainID(), - AccountNumber: signerAcc.GetAccountNumber(), - Sequence: signerAcc.GetSequence() - 1, - } - - signBytes, err := modeHandler.GetSignBytes(signMode, signingData, protobufTx) + signBytes, err := authtx.DirectSignBytes(rawTx.BodyBytes, rawTx.AuthInfoBytes, ctx.ChainID(), signerAcc.GetAccountNumber()) if err != nil { return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to recreate sign bytes for the tx: %s", err.Error())) } @@ -268,7 +283,7 @@ func (k Keeper) GetTxInfo(ctx sdk.Context, signer sdk.AccAddress) ([]byte, sdktx if err != nil { return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, "couldn't marshal public key") } - return signBytes, signMode, modeInfoBytes, pkBytes, tx.Signatures[pkIndex], nil + return signBytes, signMode, modeInfoBytes, pkBytes, rawTx.Signatures[pkIndex], nil } func V010MsgToV1SubMsg(contractAddress string, msg v010wasmTypes.CosmosMsg) (v1wasmTypes.SubMsg, error) { diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index 895815707..9fd45fa36 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -10,6 +10,8 @@ import ( "testing" "time" + "github.com/cosmos/cosmos-sdk/x/auth/vesting" + authz "github.com/cosmos/cosmos-sdk/x/authz/module" cosmwasm "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types" v010cosmwasm "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types/v010" @@ -18,10 +20,14 @@ import ( capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" - "github.com/cosmos/cosmos-sdk/x/feegrant" + feegrant "github.com/cosmos/cosmos-sdk/x/feegrant" + feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module" + "github.com/cosmos/cosmos-sdk/x/genutil" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + "github.com/cosmos/ibc-go/v4/modules/apps/transfer" ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + ibcclient "github.com/cosmos/ibc-go/v4/modules/core/02-client/client" ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" ibckeeper "github.com/cosmos/ibc-go/v4/modules/core/keeper" @@ -161,22 +167,31 @@ func (m MockIBCTransferKeeper) GetPort(ctx sdk.Context) string { } var ModuleBasics = module.NewBasicManager( + authz.AppModuleBasic{}, auth.AppModuleBasic{}, + genutil.AppModuleBasic{}, bank.AppModuleBasic{}, capability.AppModuleBasic{}, staking.AppModuleBasic{}, mint.AppModuleBasic{}, distribution.AppModuleBasic{}, gov.NewAppModuleBasic( - paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.ProposalHandler, + paramsclient.ProposalHandler, + distrclient.ProposalHandler, + upgradeclient.ProposalHandler, + upgradeclient.CancelProposalHandler, + ibcclient.UpdateClientProposalHandler, + ibcclient.UpgradeProposalHandler, ), params.AppModuleBasic{}, crisis.AppModuleBasic{}, slashing.AppModuleBasic{}, - // ibc.AppModuleBasic{}, upgrade.AppModuleBasic{}, evidence.AppModuleBasic{}, - // transfer.AppModuleBasic{}, + transfer.AppModuleBasic{}, + vesting.AppModuleBasic{}, + feegrantmodule.AppModuleBasic{}, + registration.AppModuleBasic{}, ) @@ -681,6 +696,24 @@ func PrepareInitSignedTx(t *testing.T, keeper Keeper, ctx sdk.Context, creator s return ctx.WithTxBytes(txBytes) } +func PrepareSignedTx(t *testing.T, + keeper Keeper, + ctx sdk.Context, + sender sdk.AccAddress, + snederPrivkey crypto.PrivKey, + msg sdk.Msg, +) sdk.Context { + senderAccount, err := ante.GetSignerAcc(ctx, keeper.accountKeeper, sender) + require.NoError(t, err) + + newTx := NewTestTx(msg, senderAccount, snederPrivkey) + + txBytes, err := newTx.Marshal() + require.NoError(t, err) + + return ctx.WithTxBytes(txBytes) +} + func NewTestTx(msg sdk.Msg, creatorAcc authtypes.AccountI, privKey crypto.PrivKey) *tx.Tx { return NewTestTxMultiple([]sdk.Msg{msg}, []authtypes.AccountI{creatorAcc}, []crypto.PrivKey{privKey}) } From 386637119916c6f2f28d0fca1050c4cf077fc13e Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 10 May 2023 13:48:57 +0300 Subject: [PATCH 06/54] Fix null pointer access in go tests --- x/compute/internal/keeper/ibc_test.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index 1629cd089..3aa116dff 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -334,11 +334,8 @@ func ibcPacketReceiveHelper( DestinationPort: internalPacket.Dest.PortID, DestinationChannel: internalPacket.Dest.ChannelID, Data: internalPacket.Data, - TimeoutHeight: ibcclienttypes.Height{ - RevisionNumber: internalPacket.Timeout.Block.Revision, - RevisionHeight: internalPacket.Timeout.Block.Height, - }, - TimeoutTimestamp: internalPacket.Timeout.Timestamp, + TimeoutHeight: ibcclienttypes.Height{}, + TimeoutTimestamp: internalPacket.Timeout.Timestamp, }, ProofCommitment: []byte{}, ProofHeight: ibcclienttypes.Height{}, From 1552691d69a56f6830504d84fe634681a6b2c306 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 10 May 2023 13:49:12 +0300 Subject: [PATCH 07/54] Remove unused test helper function --- x/compute/internal/keeper/test_common.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/x/compute/internal/keeper/test_common.go b/x/compute/internal/keeper/test_common.go index 9fd45fa36..bf181d6b6 100644 --- a/x/compute/internal/keeper/test_common.go +++ b/x/compute/internal/keeper/test_common.go @@ -3,7 +3,6 @@ package keeper import ( "crypto/rand" "encoding/binary" - "encoding/json" "fmt" "os" "path/filepath" @@ -97,7 +96,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/upgrade" upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" - v1types "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types/v1" wasmtypes "github.com/scrtlabs/SecretNetwork/x/compute/internal/types" "github.com/scrtlabs/SecretNetwork/x/registration" ) @@ -613,18 +611,6 @@ func handleExecute(ctx sdk.Context, k Keeper, msg *wasmtypes.MsgExecuteContract) return res, nil } -func PrepareIBCOpenAck(t *testing.T, keeper Keeper, ctx sdk.Context, ibcOpenAck v1types.IBCOpenAck, ibcOpenConfirm v1types.IBCOpenConfirm) sdk.Context { - channelConnectMsg := v1types.IBCChannelConnectMsg{ - OpenAck: &ibcOpenAck, - OpenConfirm: &ibcOpenConfirm, - } - - txBytes, err := json.Marshal(channelConnectMsg) - require.NoError(t, err) - - return ctx.WithTxBytes(txBytes) -} - func PrepareExecSignedTxWithMultipleMsgs( t *testing.T, keeper Keeper, ctx sdk.Context, sender sdk.AccAddress, senderPrivKey crypto.PrivKey, secretMsgs [][]byte, contractAddress sdk.AccAddress, coins sdk.Coins, From 5265bb5ceb09fabac15ed98783c7b3958ffd2dd8 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 16 May 2023 12:15:43 +0300 Subject: [PATCH 08/54] Checkpoint --- .../src/contract_operations.rs | 2 ++ .../src/contract_validation.rs | 30 ++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index dcf772879..5430903e1 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -114,6 +114,7 @@ pub fn init( msg, true, true, + HandleType::HANDLE_TYPE_EXECUTE, // unused in init, but same behavior as execute )?; // let duration = start.elapsed(); // trace!("Time elapsed in verify_params: {:?}", duration); @@ -292,6 +293,7 @@ pub fn handle( msg, should_validate_sig_info, should_validate_input, + parsed_handle_type.clone(), )?; let mut validated_msg = decrypted_msg.clone(); diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 6a472f0d5..01778b519 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -365,6 +365,7 @@ pub fn verify_params( og_msg: &[u8], should_validate_sig_info: bool, should_validate_input: bool, + handle_type: HandleType, ) -> Result<(), EnclaveError> { if should_validate_sig_info { debug!("Verifying message signatures for: {:?}", sig_info); @@ -438,8 +439,14 @@ pub fn verify_params( let messages = get_messages(sig_info)?; // let start = Instant::now(); - let is_verified = - verify_message_params(&messages, sender, sent_funds, contract_address, msg); + let is_verified = verify_message_params( + &messages, + sender, + sent_funds, + contract_address, + msg, + handle_type, + ); // let duration = start.elapsed(); // trace!( // "verify_params: Time elapsed in verify_message_params: {:?}", @@ -633,7 +640,10 @@ fn get_verified_msg<'sd>( messages: &'sd [CosmWasmMsg], msg_sender: &CanonicalAddr, sent_msg: &SecretMessage, + handle_type: HandleType, ) -> Option<&'sd CosmWasmMsg> { + trace!("get_verified_msg: {:?}", messages); + messages.iter().find(|&m| match m { CosmWasmMsg::Execute { msg, sender, .. } | CosmWasmMsg::Instantiate { @@ -641,7 +651,18 @@ fn get_verified_msg<'sd>( sender, .. } => msg_sender == sender && &sent_msg.to_vec() == msg, - CosmWasmMsg::MsgRecvPacket { data, .. } => sent_msg.msg == *data, + CosmWasmMsg::MsgRecvPacket { data, .. } => match handle_type { + HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { + &sent_msg.msg == data // plaintext + || &sent_msg.to_vec() == data // encrypted + } + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { + // TODO: + // parase data as {wasm:{contract:..,msg:...}} JSON and make sure wasm.msg == send_msg (maybe use sorted JSON?) + false + } + _ => false, + }, CosmWasmMsg::Other => false, }) } @@ -877,13 +898,14 @@ fn verify_message_params( sent_funds: &[Coin], contract_address: &HumanAddr, sent_msg: &SecretMessage, + handle_type: HandleType, ) -> bool { debug!("Verifying sender..."); info!("Verifying message..."); // If msg is not found (is None) then it means message verification failed, // since it didn't find a matching signed message - let msg = get_verified_msg(messages, sender, sent_msg); + let msg = get_verified_msg(messages, sender, sent_msg, handle_type); if msg.is_none() { debug!("Message verification failed!"); trace!( From 6918429b43875bf52371e3d7a728fd106cfd14bc Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 22 May 2023 15:06:21 +0300 Subject: [PATCH 09/54] Validate HANDLE_TYPE_IBC_PACKET_RECEIVE :tada: --- .../src/contract_operations.rs | 2 +- .../src/contract_validation.rs | 90 ++++++++++++------- .../enclaves/shared/cosmos-types/src/types.rs | 60 ++++++++----- .../shared/cosmwasm-types/generic/src/lib.rs | 12 +++ .../cosmwasm-types/v0.10/src/encoding.rs | 2 +- .../shared/cosmwasm-types/v1.0/src/ibc.rs | 8 +- 6 files changed, 113 insertions(+), 61 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 5430903e1..94687ee9d 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -336,6 +336,7 @@ pub fn handle( // Execute: msg.sender was already verified HandleType::HANDLE_TYPE_EXECUTE => {} // Reply & IBC stuff: no msg.sender, set it to null just in case + // WASM Hooks: cannot verify sender, set it to null HandleType::HANDLE_TYPE_REPLY | HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN | HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT @@ -343,7 +344,6 @@ pub fn handle( | HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE | HandleType::HANDLE_TYPE_IBC_PACKET_ACK | HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT - // WASM Hooks: cannot verify sender, set it to null | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT => { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 01778b519..835555e97 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -1,4 +1,5 @@ -use cw_types_v1::ibc::IbcPacketReceiveMsg; +use cw_types_generic::IbcHooksIncomingTransferMsg; +use cw_types_v1::ibc::{IbcPacketReceiveMsg}; use cw_types_v1::results::REPLY_ENCRYPTION_MAGIC_BYTES; use log::*; @@ -8,7 +9,7 @@ use cw_types_generic::BaseEnv; use cw_types_v010::types::{CanonicalAddr, Coin, HumanAddr}; use enclave_cosmos_types::traits::CosmosAminoPubkey; use enclave_cosmos_types::types::{ - ContractCode, CosmWasmMsg, CosmosPubKey, FungibleTokenPacketData, HandleType, IbcHooksWasmMsg, + ContractCode, CosmosMsg, CosmosPubKey, FungibleTokenPacketData, HandleType, IbcHooksWasmMsg, SigInfo, SignDoc, StdSignDoc, }; use enclave_crypto::traits::VerifyingKey; @@ -524,7 +525,7 @@ fn get_signer(sign_info: &SigInfo, sender: &CanonicalAddr) -> Result Result, EnclaveError> { +fn get_messages(sign_info: &SigInfo) -> Result, EnclaveError> { use cosmos_proto::tx::signing::SignMode::*; match sign_info.sign_mode { SIGN_MODE_DIRECT => { @@ -539,7 +540,7 @@ fn get_messages(sign_info: &SigInfo) -> Result, EnclaveError> { warn!("failure to parse StdSignDoc: {:?}", err); EnclaveError::FailedTxVerification })?; - let messages: Result, _> = sign_doc + let messages: Result, _> = sign_doc .msgs .iter() .map(|x| x.clone().into_cosmwasm_msg()) @@ -575,7 +576,7 @@ fn get_messages(sign_info: &SigInfo) -> Result, EnclaveError> { ); EnclaveError::FailedTxVerification })?; - let messages: Result, _> = sign_doc + let messages: Result, _> = sign_doc .msgs .iter() .map(|x| x.clone().into_cosmwasm_msg()) @@ -637,41 +638,70 @@ fn verify_callback_sig_impl( /// Get the cosmwasm message that contains the encrypted message fn get_verified_msg<'sd>( - messages: &'sd [CosmWasmMsg], + messages: &'sd [CosmosMsg], msg_sender: &CanonicalAddr, sent_msg: &SecretMessage, handle_type: HandleType, -) -> Option<&'sd CosmWasmMsg> { +) -> Option<&'sd CosmosMsg> { trace!("get_verified_msg: {:?}", messages); messages.iter().find(|&m| match m { - CosmWasmMsg::Execute { msg, sender, .. } - | CosmWasmMsg::Instantiate { + CosmosMsg::Execute { msg, sender, .. } + | CosmosMsg::Instantiate { init_msg: msg, sender, .. } => msg_sender == sender && &sent_msg.to_vec() == msg, - CosmWasmMsg::MsgRecvPacket { data, .. } => match handle_type { + CosmosMsg::MsgRecvPacket { + sequence, + source_port, + source_channel, + destination_port, + destination_channel, + data, + } => match handle_type { HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { - &sent_msg.msg == data // plaintext - || &sent_msg.to_vec() == data // encrypted + let parsed = serde_json::from_slice::(&sent_msg.msg); + if parsed.is_err(){ + trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_RECEIVE: sent_msg.msg cannot be parsed as IbcPacketReceiveMsg: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), parsed.err()); + return false; + } + let parsed = parsed.unwrap(); + + parsed.packet.data.as_slice() == data.as_slice() + && parsed.packet.sequence == *sequence + && parsed.packet.src.port_id == *source_port + && parsed.packet.src.channel_id == *source_channel + && parsed.packet.dest.port_id == *destination_port + && parsed.packet.dest.channel_id == *destination_channel + } HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { - // TODO: - // parase data as {wasm:{contract:..,msg:...}} JSON and make sure wasm.msg == send_msg (maybe use sorted JSON?) - false + let parsed = serde_json::from_slice::(data); + if parsed.is_err(){ + trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: data cannot be parsed as IbcHooksIncomingTransferMsg: {:?} Error: {:?}", String::from_utf8_lossy(data), parsed.err()); + return false; + } + + let send_msg_value = serde_json::from_slice::(&sent_msg.msg); + if send_msg_value.is_err(){ + trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: sent_msg.msg cannot be parsed as serde_json::Value: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), send_msg_value.err()); + return false; + } + + parsed.unwrap().wasm.msg == send_msg_value.unwrap() } _ => false, }, - CosmWasmMsg::Other => false, + CosmosMsg::Other => false, }) } /// Check that the contract listed in the cosmwasm message matches the one in env -fn verify_contract(msg: &CosmWasmMsg, contract_address: &HumanAddr) -> bool { +fn verify_contract(msg: &CosmosMsg, contract_address: &HumanAddr) -> bool { // Contract address is relevant only to execute, since during sending an instantiate message the contract address is not yet known match msg { - CosmWasmMsg::Execute { contract, .. } => { + CosmosMsg::Execute { contract, .. } => { info!("Verifying contract address.."); let is_verified = contract_address == contract; if !is_verified { @@ -683,9 +713,9 @@ fn verify_contract(msg: &CosmWasmMsg, contract_address: &HumanAddr) -> bool { } is_verified } - CosmWasmMsg::Instantiate { .. } => true, - CosmWasmMsg::Other => false, - CosmWasmMsg::MsgRecvPacket { + CosmosMsg::Instantiate { .. } => true, + CosmosMsg::Other => false, + CosmosMsg::MsgRecvPacket { destination_port, data, .. @@ -774,15 +804,15 @@ fn verify_contract(msg: &CosmWasmMsg, contract_address: &HumanAddr) -> bool { } /// Check that the funds listed in the cosmwasm message matches the ones in env -fn verify_funds(msg: &CosmWasmMsg, sent_funds_msg: &[Coin]) -> bool { +fn verify_funds(msg: &CosmosMsg, sent_funds_msg: &[Coin]) -> bool { match msg { - CosmWasmMsg::Execute { sent_funds, .. } - | CosmWasmMsg::Instantiate { + CosmosMsg::Execute { sent_funds, .. } + | CosmosMsg::Instantiate { init_funds: sent_funds, .. } => sent_funds_msg == sent_funds, - CosmWasmMsg::Other => false, - CosmWasmMsg::MsgRecvPacket { + CosmosMsg::Other => false, + CosmosMsg::MsgRecvPacket { data, source_port, source_channel, @@ -893,15 +923,13 @@ fn verify_funds(msg: &CosmWasmMsg, sent_funds_msg: &[Coin]) -> bool { } fn verify_message_params( - messages: &[CosmWasmMsg], + messages: &[CosmosMsg], sender: &CanonicalAddr, sent_funds: &[Coin], contract_address: &HumanAddr, sent_msg: &SecretMessage, handle_type: HandleType, ) -> bool { - debug!("Verifying sender..."); - info!("Verifying message..."); // If msg is not found (is None) then it means message verification failed, // since it didn't find a matching signed message @@ -919,11 +947,11 @@ fn verify_message_params( let msg = msg.unwrap(); match msg { - CosmWasmMsg::MsgRecvPacket { .. } => { + CosmosMsg::MsgRecvPacket { .. } => { // No sender to verify. // Going to pass null sender to the contract if all other checks pass. } - CosmWasmMsg::Execute { .. } | CosmWasmMsg::Instantiate { .. } | CosmWasmMsg::Other => { + CosmosMsg::Execute { .. } | CosmosMsg::Instantiate { .. } | CosmosMsg::Other => { if msg.sender() != Some(&sender) { warn!( "message sender did not match cosmwasm message sender: {:?} {:?}", diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 462f6bd40..24898cc37 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -257,7 +257,7 @@ impl SignDoc { #[derive(Debug)] pub struct TxBody { - pub messages: Vec, + pub messages: Vec, // Leaving this here for discoverability. We can use this, but don't verify it today. #[allow(dead_code)] memo: (), @@ -279,7 +279,7 @@ impl TxBody { let messages = tx_body .messages .into_iter() - .map(|any| CosmWasmMsg::from_bytes(&any.value)) + .map(|any| CosmosMsg::from_bytes(&any.value)) .collect::, _>>()?; Ok(TxBody { @@ -323,7 +323,7 @@ pub fn deserialize_ignore_any<'de, D: serde::Deserializer<'de>, T: Default>( } impl StdCosmWasmMsg { - pub fn into_cosmwasm_msg(self) -> Result { + pub fn into_cosmwasm_msg(self) -> Result { match self { Self::Execute { sender, @@ -344,7 +344,7 @@ impl StdCosmWasmMsg { EnclaveError::FailedToDeserialize })?; let msg = msg.0; - Ok(CosmWasmMsg::Execute { + Ok(CosmosMsg::Execute { sender, contract, msg, @@ -372,7 +372,7 @@ impl StdCosmWasmMsg { EnclaveError::FailedToDeserialize })?; let init_msg = init_msg.0; - Ok(CosmWasmMsg::Instantiate { + Ok(CosmosMsg::Instantiate { sender, init_msg, init_funds, @@ -380,7 +380,7 @@ impl StdCosmWasmMsg { callback_sig, }) } - Self::Other => Ok(CosmWasmMsg::Other), + Self::Other => Ok(CosmosMsg::Other), } } } @@ -403,7 +403,7 @@ pub struct IbcHooksWasmMsg { } #[derive(Debug)] -pub enum CosmWasmMsg { +pub enum CosmosMsg { // CosmWasm: Execute { sender: CanonicalAddr, @@ -444,25 +444,21 @@ pub enum CosmWasmMsg { Other, } -impl CosmWasmMsg { +impl CosmosMsg { pub fn from_bytes(bytes: &[u8]) -> Result { + // Assaf: This function needs a refactor, as some protobufs are + // compatible, e.g. try_parse_execute succeeds in parsing MsgRecvPacket as + // MsgExecuteContract, so for now for each field of MsgExecuteContract we also need + // to add a sanity check Self::try_parse_execute(bytes) .or_else(|_| Self::try_parse_instantiate(bytes)) - // .or_else(|_| Self::try_parse_msg_channel_open_init(bytes)) - // .or_else(|_| Self::try_parse_msg_channel_open_try(bytes)) - // .or_else(|_| Self::try_parse_msg_channel_open_ack(bytes)) - // .or_else(|_| Self::try_parse_msg_channel_open_confirm(bytes)) - // .or_else(|_| Self::try_parse_msg_channel_close_init(bytes)) - // .or_else(|_| Self::try_parse_msg_channel_close_confirm(bytes)) - // .or_else(|_| Self::try_parse_msg_acknowledgement(bytes)) - // .or_else(|_| Self::try_parse_msg_timeout(bytes)) .or_else(|_| Self::try_parse_recv_packet(bytes)) .or_else(|_| { warn!( - "got an error while trying to deserialize cosmwasm message bytes from protobuf: {}", + "error while trying to deserialize message bytes protobuf: {}", Binary(bytes.into()) ); - Ok(CosmWasmMsg::Other) + Ok(CosmosMsg::Other) }) } @@ -506,7 +502,7 @@ impl CosmWasmMsg { match raw_msg.packet.into_option() { None => Err(EnclaveError::FailedToDeserialize), - Some(packet) => Ok(CosmWasmMsg::MsgRecvPacket { + Some(packet) => Ok(CosmosMsg::MsgRecvPacket { sequence: packet.sequence, source_port: packet.source_port, source_channel: packet.source_channel, @@ -529,11 +525,16 @@ impl CosmWasmMsg { raw_msg.sender ); + if raw_msg.sender.len() == 0 { + warn!("try_parse_instantiate: sender address to instantiate was empty"); + return Err(EnclaveError::FailedToDeserialize); + } + let init_funds = Self::parse_funds(raw_msg.init_funds)?; let callback_sig = Some(raw_msg.callback_sig); - Ok(CosmWasmMsg::Instantiate { + Ok(CosmosMsg::Instantiate { sender: CanonicalAddr(Binary(raw_msg.sender)), init_msg: raw_msg.init_msg, init_funds, @@ -553,12 +554,23 @@ impl CosmWasmMsg { raw_msg.sender.len(), raw_msg.sender ); + + if raw_msg.sender.len() == 0 { + warn!("try_parse_execute: sender address to execute was empty"); + return Err(EnclaveError::FailedToDeserialize); + } + trace!( "try_parse_execute contract: len={} val={:?}", raw_msg.contract.len(), raw_msg.contract ); + if raw_msg.contract.len() == 0 { + warn!("try_parse_execute: contract address to execute was empty"); + return Err(EnclaveError::FailedToDeserialize); + } + // humanize address let contract = HumanAddr::from_canonical(&CanonicalAddr(Binary(raw_msg.contract))) .map_err(|err| { @@ -573,7 +585,7 @@ impl CosmWasmMsg { let callback_sig = Some(raw_msg.callback_sig); - Ok(CosmWasmMsg::Execute { + Ok(CosmosMsg::Execute { sender: CanonicalAddr(Binary(raw_msg.sender)), contract, msg: raw_msg.msg, @@ -606,11 +618,11 @@ impl CosmWasmMsg { pub fn sender(&self) -> Option<&CanonicalAddr> { match self { - CosmWasmMsg::Execute { sender, .. } | CosmWasmMsg::Instantiate { sender, .. } => { + CosmosMsg::Execute { sender, .. } | CosmosMsg::Instantiate { sender, .. } => { Some(sender) } - CosmWasmMsg::MsgRecvPacket { .. } => None, - CosmWasmMsg::Other => None, + CosmosMsg::MsgRecvPacket { .. } => None, + CosmosMsg::Other => None, } } } diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs index c1249e525..8dd0f7630 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs @@ -10,6 +10,7 @@ use cw_types_v1::types::Env as V1Env; use cw_types_v1::types::MessageInfo as V1MessageInfo; use cw_types_v1::types::{self as v1types, Addr}; use enclave_ffi_types::EnclaveError; +use serde_json; pub const CONTRACT_KEY_LENGTH: usize = 64; @@ -249,3 +250,14 @@ mod tests { assert_eq!(2 + 2, 4); } } + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct IbcHooksIncomingTransferMsg { + pub wasm: IbcHooksIncomingTransferMsgWasm, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct IbcHooksIncomingTransferMsgWasm { + pub contract: String, + pub msg: serde_json::Value, +} diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/encoding.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/encoding.rs index 605892e15..899360fe8 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/encoding.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/encoding.rs @@ -11,7 +11,7 @@ use log::*; /// with serde. It also adds some helper methods to help encode inline. /// /// This is only needed as serde-json-{core,wasm} has a horrible encoding for Vec -#[derive(Clone, Default, Debug, PartialEq)] +#[derive(Clone, Default, Debug, PartialEq, Eq)] pub struct Binary(pub Vec); impl Binary { diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs index 6c620e915..2995e8db8 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs @@ -123,7 +123,7 @@ where pub events: Vec, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct IbcEndpoint { pub port_id: String, pub channel_id: String, @@ -173,7 +173,7 @@ pub enum IbcChannelCloseMsg { } /// The message that is passed into `ibc_packet_receive` -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct IbcPacketReceiveMsg { pub packet: IbcPacket, pub relayer: Addr, @@ -188,7 +188,7 @@ impl IbcPacketReceiveMsg { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct IbcPacket { /// The raw data sent from the other side in the packet pub data: Binary, @@ -230,7 +230,7 @@ impl IbcAcknowledgement { /// In IBC each package must set at least one type of timeout: /// the timestamp or the block height. Using this rather complex enum instead of /// two timeout fields we ensure that at least one timeout is set. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub struct IbcTimeout { // use private fields to enforce the use of constructors, which ensure that at least one is set From 2b7492e600da9a2664cbd721bc1da1d569bf95ea Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 May 2023 10:54:04 +0300 Subject: [PATCH 10/54] Fix validate HANDLE_TYPE_IBC_PACKET_RECEIVE when encrypted --- .../src/contract_validation.rs | 21 ++++++++++--------- .../enclaves/shared/cosmos-types/src/types.rs | 7 ++++++- .../shared/cosmwasm-types/generic/src/lib.rs | 11 ---------- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 835555e97..4babe7749 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -1,4 +1,3 @@ -use cw_types_generic::IbcHooksIncomingTransferMsg; use cw_types_v1::ibc::{IbcPacketReceiveMsg}; use cw_types_v1::results::REPLY_ENCRYPTION_MAGIC_BYTES; use log::*; @@ -9,8 +8,8 @@ use cw_types_generic::BaseEnv; use cw_types_v010::types::{CanonicalAddr, Coin, HumanAddr}; use enclave_cosmos_types::traits::CosmosAminoPubkey; use enclave_cosmos_types::types::{ - ContractCode, CosmosMsg, CosmosPubKey, FungibleTokenPacketData, HandleType, IbcHooksWasmMsg, - SigInfo, SignDoc, StdSignDoc, + ContractCode, CosmosMsg, CosmosPubKey, FungibleTokenPacketData, HandleType, IbcHooksIncomingTransferWasmMsg, + SigInfo, SignDoc, StdSignDoc, IbcHooksIncomingTransferMsg, }; use enclave_crypto::traits::VerifyingKey; use enclave_crypto::{sha_256, AESKey, Hmac, Kdf, HASH_SIZE, KEY_MANAGER}; @@ -661,12 +660,14 @@ fn get_verified_msg<'sd>( data, } => match handle_type { HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { - let parsed = serde_json::from_slice::(&sent_msg.msg); - if parsed.is_err(){ - trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_RECEIVE: sent_msg.msg cannot be parsed as IbcPacketReceiveMsg: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), parsed.err()); - return false; + let parsed_sent_msg = serde_json::from_slice::(&sent_msg.msg); + if parsed_sent_msg.is_err() { + trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_RECEIVE: sent_msg.msg cannot be parsed as IbcPacketReceiveMsg: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), parsed_sent_msg.err()); + + trace!("Checking if sent_msg & data are encrypted"); + return &sent_msg.to_vec() == data; } - let parsed = parsed.unwrap(); + let parsed = parsed_sent_msg.unwrap(); parsed.packet.data.as_slice() == data.as_slice() && parsed.packet.sequence == *sequence @@ -674,7 +675,7 @@ fn get_verified_msg<'sd>( && parsed.packet.src.channel_id == *source_channel && parsed.packet.dest.port_id == *destination_port && parsed.packet.dest.channel_id == *destination_channel - + // TODO check timeout too? sequence + destination_channel + data should be enough } HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { let parsed = serde_json::from_slice::(data); @@ -748,7 +749,7 @@ fn verify_contract(msg: &CosmosMsg, contract_address: &HumanAddr) -> bool { }; // Parse data.memo as IbcHooksWasmMsg JSON - let wasm_msg: IbcHooksWasmMsg = match serde_json::from_slice(memo.as_bytes()) { + let wasm_msg: IbcHooksIncomingTransferWasmMsg = match serde_json::from_slice(memo.as_bytes()) { Ok(wasm_msg) => wasm_msg, Err(err) => { trace!( diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 24898cc37..a9ca70e66 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -395,9 +395,14 @@ pub struct FungibleTokenPacketData { pub memo: Option, } +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcHooksIncomingTransferMsg { + pub wasm: IbcHooksIncomingTransferWasmMsg, +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub struct IbcHooksWasmMsg { +pub struct IbcHooksIncomingTransferWasmMsg { pub contract: HumanAddr, pub msg: serde_json::Value, } diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs index 8dd0f7630..c9298da85 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs @@ -250,14 +250,3 @@ mod tests { assert_eq!(2 + 2, 4); } } - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -pub struct IbcHooksIncomingTransferMsg { - pub wasm: IbcHooksIncomingTransferMsgWasm, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -pub struct IbcHooksIncomingTransferMsgWasm { - pub contract: String, - pub msg: serde_json::Value, -} From d550cae9c5c80834e2d9d792ea164bcff3fcc93a Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 May 2023 11:24:40 +0300 Subject: [PATCH 11/54] Fix tests for IBC ack & timeout --- x/compute/internal/keeper/ibc_test.go | 97 ++++++++++++++++++++------- 1 file changed, 74 insertions(+), 23 deletions(-) diff --git a/x/compute/internal/keeper/ibc_test.go b/x/compute/internal/keeper/ibc_test.go index 3aa116dff..5f2cc099b 100644 --- a/x/compute/internal/keeper/ibc_test.go +++ b/x/compute/internal/keeper/ibc_test.go @@ -56,7 +56,7 @@ func ibcChannelConnectHelper( OpenConfirm: nil, } - msg := ibcchanneltypes.MsgChannelOpenAck{ + sdkMsg := ibcchanneltypes.MsgChannelOpenAck{ PortId: channel.Endpoint.PortID, ChannelId: channel.Endpoint.ChannelID, CounterpartyChannelId: channel.CounterpartyEndpoint.ChannelID, @@ -66,7 +66,7 @@ func ibcChannelConnectHelper( Signer: relayer.String(), } - ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &msg) + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &sdkMsg) } else { ibcChannelConnectMsg = v1types.IBCChannelConnectMsg{ OpenAck: nil, @@ -75,7 +75,7 @@ func ibcChannelConnectHelper( }, } - msg := ibcchanneltypes.MsgChannelOpenConfirm{ + sdkMsg := ibcchanneltypes.MsgChannelOpenConfirm{ PortId: channel.Endpoint.PortID, ChannelId: channel.Endpoint.ChannelID, ProofAck: []byte{}, @@ -83,7 +83,7 @@ func ibcChannelConnectHelper( Signer: relayer.String(), } - ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &msg) + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &sdkMsg) } err := keeper.OnConnectChannel(ctx, contract, ibcChannelConnectMsg) @@ -132,7 +132,7 @@ func ibcChannelOpenHelper( OpenInit: nil, } - msg := ibcchanneltypes.MsgChannelOpenTry{ + sdkMsg := ibcchanneltypes.MsgChannelOpenTry{ PortId: channel.Endpoint.PortID, PreviousChannelId: "", Channel: ibcchanneltypes.Channel{ @@ -150,7 +150,7 @@ func ibcChannelOpenHelper( ProofHeight: ibcclienttypes.Height{}, Signer: relayer.String(), } - ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &msg) + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &sdkMsg) } else { ibcChannelOpenMsg = v1types.IBCChannelOpenMsg{ OpenTry: nil, @@ -159,7 +159,7 @@ func ibcChannelOpenHelper( }, } - msg := ibcchanneltypes.MsgChannelOpenInit{ + sdkMsg := ibcchanneltypes.MsgChannelOpenInit{ PortId: channel.Endpoint.PortID, Channel: ibcchanneltypes.Channel{ State: ibcchanneltypes.INIT, @@ -173,7 +173,7 @@ func ibcChannelOpenHelper( }, Signer: relayer.String(), } - ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &msg) + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &sdkMsg) } res, err := keeper.OnOpenChannel(ctx, contract, ibcChannelOpenMsg) @@ -218,14 +218,14 @@ func ibcChannelCloseHelper( CloseInit: nil, } - msg := ibcchanneltypes.MsgChannelCloseConfirm{ + sdkMsg := ibcchanneltypes.MsgChannelCloseConfirm{ PortId: channel.Endpoint.PortID, ChannelId: channel.Endpoint.ChannelID, ProofInit: []byte{}, ProofHeight: ibcclienttypes.Height{}, Signer: relayer.String(), } - ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &msg) + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &sdkMsg) } else { ibcChannelCloseMsg = v1types.IBCChannelCloseMsg{ CloseConfirm: nil, @@ -234,12 +234,12 @@ func ibcChannelCloseHelper( }, } - msg := ibcchanneltypes.MsgChannelCloseInit{ + sdkMsg := ibcchanneltypes.MsgChannelCloseInit{ PortId: channel.Endpoint.PortID, ChannelId: channel.Endpoint.ChannelID, Signer: relayer.String(), } - ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &msg) + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &sdkMsg) } err := keeper.OnCloseChannel(ctx, contract, ibcChannelCloseMsg) @@ -323,10 +323,10 @@ func ibcPacketReceiveHelper( ibcPacketReceiveMsg := v1types.IBCPacketReceiveMsg{ Packet: internalPacket, - Relayer: "relayer", + Relayer: relayer.String(), } - msg := ibcchanneltypes.MsgRecvPacket{ + sdkMsg := ibcchanneltypes.MsgRecvPacket{ Packet: ibcchanneltypes.Packet{ Sequence: internalPacket.Sequence, SourcePort: internalPacket.Src.PortID, @@ -342,7 +342,7 @@ func ibcPacketReceiveHelper( Signer: relayer.String(), } - ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &msg) + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &sdkMsg) res, err := keeper.OnRecvPacket(ctx, contractAddr, ibcPacketReceiveMsg) @@ -368,8 +368,15 @@ func ibcPacketReceiveHelper( } func ibcPacketAckHelper( - t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, gas uint64, originalPacket v1types.IBCPacket, ack []byte, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contractAddr sdk.AccAddress, + relayer sdk.AccAddress, + relayerPrivkey crypto.PrivKey, + gas uint64, + originalPacket v1types.IBCPacket, + ack []byte, ) (sdk.Context, []ContractEvent, cosmwasm.StdError) { // create new ctx with the same storage and a gas limit // this is to reset the event manager, so we won't get @@ -387,9 +394,28 @@ func ibcPacketAckHelper( Data: ack, }, OriginalPacket: originalPacket, - Relayer: "relayer", + Relayer: relayer.String(), + } + + sdkMsg := ibcchanneltypes.MsgAcknowledgement{ + Packet: ibcchanneltypes.Packet{ + Sequence: originalPacket.Sequence, + SourcePort: originalPacket.Src.PortID, + SourceChannel: originalPacket.Src.ChannelID, + DestinationPort: originalPacket.Dest.PortID, + DestinationChannel: originalPacket.Dest.ChannelID, + Data: originalPacket.Data, + TimeoutHeight: ibcclienttypes.Height{}, + TimeoutTimestamp: originalPacket.Timeout.Timestamp, + }, + Acknowledgement: ack, + ProofAcked: nil, + ProofHeight: ibcclienttypes.Height{}, + Signer: relayer.String(), } + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &sdkMsg) + err := keeper.OnAckPacket(ctx, contractAddr, ibcPacketAckMsg) require.NotZero(t, gasMeter.GetWasmCounter(), err) @@ -405,8 +431,14 @@ func ibcPacketAckHelper( } func ibcPacketTimeoutHelper( - t *testing.T, keeper Keeper, ctx sdk.Context, - contractAddr sdk.AccAddress, creatorPrivKey crypto.PrivKey, gas uint64, originalPacket v1types.IBCPacket, + t *testing.T, + keeper Keeper, + ctx sdk.Context, + contractAddr sdk.AccAddress, + relayer sdk.AccAddress, + relayerPrivkey crypto.PrivKey, + gas uint64, + originalPacket v1types.IBCPacket, ) (sdk.Context, []ContractEvent, cosmwasm.StdError) { // create new ctx with the same storage and a gas limit // this is to reset the event manager, so we won't get @@ -421,9 +453,28 @@ func ibcPacketTimeoutHelper( ibcPacketTimeoutMsg := v1types.IBCPacketTimeoutMsg{ Packet: originalPacket, - Relayer: "relayer", + Relayer: relayer.String(), } + sdkMsg := ibcchanneltypes.MsgTimeout{ + Packet: ibcchanneltypes.Packet{ + Sequence: originalPacket.Sequence, + SourcePort: originalPacket.Src.PortID, + SourceChannel: originalPacket.Src.ChannelID, + DestinationPort: originalPacket.Dest.PortID, + DestinationChannel: originalPacket.Dest.ChannelID, + Data: originalPacket.Data, + TimeoutHeight: ibcclienttypes.Height{}, + TimeoutTimestamp: originalPacket.Timeout.Timestamp, + }, + ProofUnreceived: nil, + ProofHeight: ibcclienttypes.Height{}, + NextSequenceRecv: 0, + Signer: relayer.String(), + } + + ctx = PrepareSignedTx(t, keeper, ctx, relayer, relayerPrivkey, &sdkMsg) + err := keeper.OnTimeoutPacket(ctx, contractAddr, ibcPacketTimeoutMsg) require.NotZero(t, gasMeter.GetWasmCounter(), err) @@ -1047,7 +1098,7 @@ func TestIBCPacketAck(t *testing.T) { ack := make([]byte, 8) binary.LittleEndian.PutUint64(ack, uint64(test.sequence)) - ctx, events, err := ibcPacketAckHelper(t, keeper, ctx, contractAddress, privkeyA, defaultGasForIbcTests, ibcPacket, ack) + ctx, events, err := ibcPacketAckHelper(t, keeper, ctx, contractAddress, walletA, privkeyA, defaultGasForIbcTests, ibcPacket, ack) if !test.isSuccess { require.Contains(t, fmt.Sprintf("%+v", err), "Intentional") @@ -1170,7 +1221,7 @@ func TestIBCPacketTimeout(t *testing.T) { []byte{}, ) - ctx, events, err := ibcPacketTimeoutHelper(t, keeper, ctx, contractAddress, privkeyA, defaultGasForIbcTests, ibcPacket) + ctx, events, err := ibcPacketTimeoutHelper(t, keeper, ctx, contractAddress, walletA, privkeyA, defaultGasForIbcTests, ibcPacket) if !test.isSuccess { require.Contains(t, fmt.Sprintf("%+v", err), "Intentional") From dee2dd0f064b4a9eee1d369c64983dbdc66d6727 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 May 2023 14:01:01 +0300 Subject: [PATCH 12/54] GetTxInfo: Fix for multisig after refactor --- x/compute/internal/keeper/keeper.go | 77 +++++++++++++++++++---------- 1 file changed, 52 insertions(+), 25 deletions(-) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index b04c43b5a..4c080b9fa 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -9,6 +9,7 @@ import ( "fmt" "path/filepath" "strconv" + "strings" "time" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" @@ -23,6 +24,7 @@ import ( codedctypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/x/auth/ante" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" @@ -186,29 +188,39 @@ func (k Keeper) importCode(ctx sdk.Context, codeID uint64, codeInfo types.CodeIn func (k Keeper) GetTxInfo(ctx sdk.Context, sender sdk.AccAddress) ([]byte, sdktxsigning.SignMode, []byte, []byte, []byte, error) { var rawTx sdktx.TxRaw - err := k.cdc.Unmarshal(ctx.TxBytes(), &rawTx) + var parsedTx sdktx.Tx + err := k.cdc.Unmarshal(ctx.TxBytes(), &parsedTx) if err != nil { - return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to decode raw transaction from bytes: %s", err.Error())) + if strings.Contains(err.Error(), "no concrete type registered for type URL /ibc") { + // We're here because the tx is an IBC tx, and the IBC module doesn't support Amino encoding. + // It fails decoding IBC messages with the error "no concrete type registered for type URL /ibc.core.channel.v1.MsgChannelOpenInit against interface *types.Msg". + // "concrete type" is used to refer to the mapping between the Go struct and the Amino type string (e.g. "cosmos-sdk/MsgSend") + // Therefore we'll manually rebuild the tx without parsing the body, as parsing it is unnecessary here anyway. + // + // NOTE: This does not support multisigned IBC txs (if that's even a thing). + + err := k.cdc.Unmarshal(ctx.TxBytes(), &rawTx) + if err != nil { + return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to decode raw transaction from bytes: %s", err.Error())) + } + + var txAuthInfo sdktx.AuthInfo + err = k.cdc.Unmarshal(rawTx.AuthInfoBytes, &txAuthInfo) + if err != nil { + return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to decode transaction auth info from bytes: %s", err.Error())) + } + + parsedTx = sdktx.Tx{ + Body: nil, + AuthInfo: &txAuthInfo, + Signatures: rawTx.Signatures, + } + } else { + return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to decode transaction from bytes: %s", err.Error())) + } } - var txAuthInfo sdktx.AuthInfo - err = k.cdc.Unmarshal(rawTx.AuthInfoBytes, &txAuthInfo) - if err != nil { - return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to decode transaction auth info from bytes: %s", err.Error())) - } - - // Assaf: - // We're not decoding Body as it is unnecessary in this context, - // and it fails decoding IBC messages with the error "no concrete type registered for type URL /ibc.core.channel.v1.MsgChannelOpenInit against interface *types.Msg". - // I think that's because the core IBC messages don't support Amino encoding, - // and a "concrete type" is used to refer to the mapping between the Go struct and the Amino type string (e.g. "cosmos-sdk/MsgSend") - // Therefore we'll ignore the Body here. - // Plus this probably saves CPU cycles to not decode the body. - tx := authtx.WrapTx(&sdktx.Tx{ - Body: nil, - AuthInfo: &txAuthInfo, - Signatures: rawTx.Signatures, - }).GetTx() + tx := authtx.WrapTx(&parsedTx).GetTx() pubKeys, err := tx.GetPubKeys() if err != nil { @@ -217,7 +229,6 @@ func (k Keeper) GetTxInfo(ctx sdk.Context, sender sdk.AccAddress) ([]byte, sdktx pkIndex := -1 if sender == nil { - // Assaf: // We are in a situation where the contract gets a null msg.sender, // however we still need to get the sign bytes for verification against the wasm input msg inside the enclave. // There can be multiple signers on the tx, for example one can be the msg.sender and the another can be the gas fee payer. Another example is if this tx also contains MsgMultiSend which supports multiple msg.senders thus requiring multiple signers. @@ -263,9 +274,25 @@ func (k Keeper) GetTxInfo(ctx sdk.Context, sender sdk.AccAddress) ([]byte, sdktx return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to retrieve account by address: %s", err.Error())) } - signBytes, err := authtx.DirectSignBytes(rawTx.BodyBytes, rawTx.AuthInfoBytes, ctx.ChainID(), signerAcc.GetAccountNumber()) - if err != nil { - return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to recreate sign bytes for the tx: %s", err.Error())) + var signBytes []byte + + if rawTx.BodyBytes != nil && rawTx.AuthInfoBytes != nil { + signBytes, err = authtx.DirectSignBytes(rawTx.BodyBytes, rawTx.AuthInfoBytes, ctx.ChainID(), signerAcc.GetAccountNumber()) + if err != nil { + return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to recreate sign bytes for the tx: %s", err.Error())) + } + } else { + signingData := authsigning.SignerData{ + ChainID: ctx.ChainID(), + AccountNumber: signerAcc.GetAccountNumber(), + Sequence: signerAcc.GetSequence() - 1, + } + txConfig := authtx.NewTxConfig(k.cdc.(*codec.ProtoCodec), authtx.DefaultSignModes) + modeHandler := txConfig.SignModeHandler() + signBytes, err = modeHandler.GetSignBytes(signMode, signingData, tx) + if err != nil { + return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, fmt.Sprintf("Unable to recreate sign bytes for the tx: %s", err.Error())) + } } modeInfoBytes, err := sdktxsigning.SignatureDataToProto(signatures[pkIndex].Data).Marshal() @@ -283,7 +310,7 @@ func (k Keeper) GetTxInfo(ctx sdk.Context, sender sdk.AccAddress) ([]byte, sdktx if err != nil { return nil, 0, nil, nil, nil, sdkerrors.Wrap(types.ErrSigFailed, "couldn't marshal public key") } - return signBytes, signMode, modeInfoBytes, pkBytes, rawTx.Signatures[pkIndex], nil + return signBytes, signMode, modeInfoBytes, pkBytes, parsedTx.Signatures[pkIndex], nil } func V010MsgToV1SubMsg(contractAddress string, msg v010wasmTypes.CosmosMsg) (v1wasmTypes.SubMsg, error) { From 3d16db3124a39dbd0650e79e6ee295b52a9a062f Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 May 2023 20:55:26 +0300 Subject: [PATCH 13/54] Remove print in TestLastMsgMarkerMultipleMsgsInATx --- x/compute/internal/keeper/secret_contracts_exec_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index 7b10d1c2f..9bb3e0418 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -2367,8 +2367,6 @@ func TestLastMsgMarkerMultipleMsgsInATx(t *testing.T) { results, err := execHelperMultipleMsgs(t, keeper, ctx, contractAddress, walletA, privKeyA, msgs, true, true, math.MaxUint64, 0) require.NotEqual(t, nil, err) - println("Error: ", err) - require.Equal(t, 1, len(results)) } From 9768e3e1460764fe8908c14fbfb5dbfff8f602d2 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 May 2023 23:14:21 +0300 Subject: [PATCH 14/54] Fix IBC hooks incoming transfer validation --- .../src/contract_validation.rs | 27 ++++++++---- .../shared/contract-engine/src/ibc_message.rs | 18 ++++++++ .../shared/contract-engine/src/message.rs | 11 +++-- .../keeper/secret_contracts_exec_test.go | 42 +++++++++++++++++-- 4 files changed, 82 insertions(+), 16 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 4babe7749..8a1926fbb 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -8,7 +8,7 @@ use cw_types_generic::BaseEnv; use cw_types_v010::types::{CanonicalAddr, Coin, HumanAddr}; use enclave_cosmos_types::traits::CosmosAminoPubkey; use enclave_cosmos_types::types::{ - ContractCode, CosmosMsg, CosmosPubKey, FungibleTokenPacketData, HandleType, IbcHooksIncomingTransferWasmMsg, + ContractCode, CosmosMsg, CosmosPubKey, FungibleTokenPacketData, HandleType, SigInfo, SignDoc, StdSignDoc, IbcHooksIncomingTransferMsg, }; use enclave_crypto::traits::VerifyingKey; @@ -678,11 +678,20 @@ fn get_verified_msg<'sd>( // TODO check timeout too? sequence + destination_channel + data should be enough } HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { - let parsed = serde_json::from_slice::(data); - if parsed.is_err(){ - trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: data cannot be parsed as IbcHooksIncomingTransferMsg: {:?} Error: {:?}", String::from_utf8_lossy(data), parsed.err()); + let fungible_token_packet_data = serde_json::from_slice::(data); + if fungible_token_packet_data.is_err(){ + trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: data cannot be parsed as FungibleTokenPacketData: {:?} Error: {:?}", String::from_utf8_lossy(data), fungible_token_packet_data.err()); return false; } + let fungible_token_packet_data= fungible_token_packet_data.unwrap(); + + + let ibc_hooks_incoming_transfer_msg = serde_json::from_slice::(fungible_token_packet_data.memo.clone().unwrap_or("".into()).as_bytes()); + if ibc_hooks_incoming_transfer_msg.is_err(){ + trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: fungible_token_packet_data.memo cannot be parsed as IbcHooksIncomingTransferMsg: {:?} Error: {:?}", fungible_token_packet_data.memo, ibc_hooks_incoming_transfer_msg.err()); + return false; + } + let ibc_hooks_incoming_transfer_msg = ibc_hooks_incoming_transfer_msg.unwrap(); let send_msg_value = serde_json::from_slice::(&sent_msg.msg); if send_msg_value.is_err(){ @@ -690,7 +699,7 @@ fn get_verified_msg<'sd>( return false; } - parsed.unwrap().wasm.msg == send_msg_value.unwrap() + ibc_hooks_incoming_transfer_msg.wasm.msg == send_msg_value.unwrap() } _ => false, }, @@ -749,7 +758,7 @@ fn verify_contract(msg: &CosmosMsg, contract_address: &HumanAddr) -> bool { }; // Parse data.memo as IbcHooksWasmMsg JSON - let wasm_msg: IbcHooksIncomingTransferWasmMsg = match serde_json::from_slice(memo.as_bytes()) { + let wasm_msg: IbcHooksIncomingTransferMsg = match serde_json::from_slice(memo.as_bytes()) { Ok(wasm_msg) => wasm_msg, Err(err) => { trace!( @@ -763,13 +772,13 @@ fn verify_contract(msg: &CosmosMsg, contract_address: &HumanAddr) -> bool { // In ibc-hooks contract_address == packet_data.memo.wasm.contract == packet_data.receiver let is_verified = *contract_address == packet_data.receiver - && *contract_address == wasm_msg.contract; + && *contract_address == wasm_msg.wasm.contract; if !is_verified { trace!( "Contract address sent to enclave {:?} is not the same as in ibc-hooks packet receiver={:?} memo={:?}", contract_address, packet_data.receiver, - wasm_msg.contract + wasm_msg.wasm.contract ); } is_verified @@ -991,7 +1000,7 @@ fn receiver_chain_is_source(source_port: &str, source_channel: &str, denom: &str /// GetDenomPrefix returns the receiving denomination prefix fn get_denom_prefix(port_id: &str, channel_id: &str) -> String { - format!("{}/{}", port_id, channel_id) + format!("{}/{}/", port_id, channel_id) } /// DenomTrace contains the base denomination for ICS20 fungible tokens and the diff --git a/cosmwasm/enclaves/shared/contract-engine/src/ibc_message.rs b/cosmwasm/enclaves/shared/contract-engine/src/ibc_message.rs index 215b57dbb..b85aa0f86 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/ibc_message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/ibc_message.rs @@ -85,3 +85,21 @@ pub fn parse_ibc_receive_message(message: &[u8]) -> Result Result { + Ok(ParsedMessage { + should_validate_sig_info: false, + should_validate_input: true, + was_msg_encrypted: false, + should_encrypt_output: false, + secret_msg: SecretMessage { + nonce: [0; 32], + user_public_key: [0; 32], + msg: message.into(), + }, + decrypted_msg: message.into(), + data_for_validation: None, + }) +} diff --git a/cosmwasm/enclaves/shared/contract-engine/src/message.rs b/cosmwasm/enclaves/shared/contract-engine/src/message.rs index 303182c75..dd24f2e1f 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/message.rs @@ -4,7 +4,10 @@ use enclave_cosmos_types::types::HandleType; use enclave_ffi_types::EnclaveError; use crate::execute_message::parse_execute_message; -use crate::ibc_message::{parse_ibc_receive_message, parse_plaintext_ibc_protocol_message}; +use crate::ibc_message::{ + parse_ibc_hooks_incoming_transfer_message, parse_ibc_receive_message, + parse_plaintext_ibc_protocol_message, +}; use crate::reply_message::parse_reply_message; use crate::types::ParsedMessage; @@ -31,9 +34,9 @@ pub fn parse_message( parse_plaintext_ibc_protocol_message(message) } - HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE - | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { - parse_ibc_receive_message(message) + HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => parse_ibc_receive_message(message), + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { + parse_ibc_hooks_incoming_transfer_message(message) } }; } diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index 9bb3e0418..041f92e72 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -25,6 +25,9 @@ import ( crypto "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" + ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + ibcclienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + ibcchanneltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" ) func setupChainTest(t *testing.T, wasmPath string, additionalCoinsInWallets sdk.Coins, amount uint64) (sdk.Context, Keeper, []uint64, []string, sdk.AccAddress, crypto.PrivKey, sdk.AccAddress, crypto.PrivKey) { @@ -2370,7 +2373,7 @@ func TestLastMsgMarkerMultipleMsgsInATx(t *testing.T) { require.Equal(t, 1, len(results)) } -func TestPlaintextInputWithIBCHooksFlag(t *testing.T) { +func TestIBCHooksIncomingTransfer(t *testing.T) { for _, testContract := range testContracts { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) @@ -2378,9 +2381,42 @@ func TestPlaintextInputWithIBCHooksFlag(t *testing.T) { _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) - _, err := keeper.Execute(ctx, contractAddress, walletA, []byte(`{"log_msg_sender":{}}`), sdk.NewCoins(), nil, cosmwasm.HandleTypeIbcWasmHooksIncomingTransfer) + // To send 1denom to the contract over IBC, we need to send FungibleTokenPacketData + // that specifies the denom after it was sent to the other chain. + data := ibctransfertypes.FungibleTokenPacketData{ + // Denom is the denom after it was sent to the other chain + // and now it is coming back to Secret, but it's specifed as a full path denom + // because FungibleTokenPacketData had crafted on the other chain + Denom: "transfer/channel-0/denom", // port_on_other_chain/channel_on_other_chain/base_denom + Amount: "1", + Sender: "ignored", + Receiver: contractAddress.String(), // must be the contract address, like in the memo + Memo: fmt.Sprintf(`{"wasm":{"contract":"%s","msg":{"log_msg_sender":{}}}}`, contractAddress.String()), + } + dataBytes, err := json.Marshal(data) + require.NoError(t, err) + + sdkMsg := ibcchanneltypes.MsgRecvPacket{ + Packet: ibcchanneltypes.Packet{ + Sequence: 0, + SourcePort: "transfer", // port on the other chain + SourceChannel: "channel-0", // channel on the other chain + DestinationPort: "transfer", // port on Secret + DestinationChannel: "channel-0", // channel on Secret + Data: dataBytes, + TimeoutHeight: ibcclienttypes.Height{}, + TimeoutTimestamp: 0, + }, + ProofCommitment: []byte{}, + ProofHeight: ibcclienttypes.Height{}, + Signer: walletA.String(), + } - require.Empty(t, err) + ctx = PrepareSignedTx(t, keeper, ctx, walletA, privKeyA, &sdkMsg) + + _, execErr := keeper.Execute(ctx, contractAddress, walletA, []byte(`{"log_msg_sender":{}}`), sdk.NewCoins(sdk.NewInt64Coin("denom", 1)), nil, cosmwasm.HandleTypeIbcWasmHooksIncomingTransfer) + + require.Empty(t, execErr) events := tryDecryptWasmEvents(ctx, nil) From 47be10cb87e40deb3c4fed86a6aef764c381cb67 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 May 2023 23:31:18 +0300 Subject: [PATCH 15/54] Fix IBC hooks incoming transfer validation for tokens that originated from other chains --- .../src/contract_validation.rs | 2 +- .../keeper/secret_contracts_exec_test.go | 125 ++++++++++-------- 2 files changed, 73 insertions(+), 54 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 8a1926fbb..139dc19d0 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -912,7 +912,7 @@ fn verify_funds(msg: &CosmosMsg, sent_funds_msg: &[Coin]) -> bool { }; // Check denom - if sent_funds_msg_coin.denom != denom { + if sent_funds_msg_coin.denom.to_lowercase() != denom.to_lowercase() { trace!( "Contract was called via ibc-hooks but sent_funds_msg_coin.denom != denom: {:?} != {:?}", sent_funds_msg_coin.denom, diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index 041f92e72..d3e824723 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -2374,64 +2374,83 @@ func TestLastMsgMarkerMultipleMsgsInATx(t *testing.T) { } func TestIBCHooksIncomingTransfer(t *testing.T) { - for _, testContract := range testContracts { - t.Run(testContract.CosmWasmVersion, func(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins()) - - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) - require.Empty(t, initErr) - - // To send 1denom to the contract over IBC, we need to send FungibleTokenPacketData - // that specifies the denom after it was sent to the other chain. - data := ibctransfertypes.FungibleTokenPacketData{ - // Denom is the denom after it was sent to the other chain - // and now it is coming back to Secret, but it's specifed as a full path denom - // because FungibleTokenPacketData had crafted on the other chain - Denom: "transfer/channel-0/denom", // port_on_other_chain/channel_on_other_chain/base_denom - Amount: "1", - Sender: "ignored", - Receiver: contractAddress.String(), // must be the contract address, like in the memo - Memo: fmt.Sprintf(`{"wasm":{"contract":"%s","msg":{"log_msg_sender":{}}}}`, contractAddress.String()), - } - dataBytes, err := json.Marshal(data) - require.NoError(t, err) - - sdkMsg := ibcchanneltypes.MsgRecvPacket{ - Packet: ibcchanneltypes.Packet{ - Sequence: 0, - SourcePort: "transfer", // port on the other chain - SourceChannel: "channel-0", // channel on the other chain - DestinationPort: "transfer", // port on Secret - DestinationChannel: "channel-0", // channel on Secret - Data: dataBytes, - TimeoutHeight: ibcclienttypes.Height{}, - TimeoutTimestamp: 0, - }, - ProofCommitment: []byte{}, - ProofHeight: ibcclienttypes.Height{}, - Signer: walletA.String(), - } + for _, test := range []struct { + testName string + remoteDenom string // port_on_other_chain/channel_on_other_chain/base_denom or base_denom + localDenom string // denom on Secret ("denom" or "ibc/...") + }{ + { + testName: "denom originated from Secret", + remoteDenom: "transfer/channel-0/denom", + localDenom: "denom", + }, + { + testName: "denom is base denom of the other chain", + remoteDenom: "uatom", + localDenom: "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2", + }, + } { + for _, testContract := range testContracts { + t.Run(test.testName, func(t *testing.T) { + t.Run(testContract.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins(sdk.NewInt64Coin(test.localDenom, 1))) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) + require.Empty(t, initErr) + + // To send 1denom to the contract over IBC, we need to send FungibleTokenPacketData + // that specifies the denom after it was sent to the other chain. + data := ibctransfertypes.FungibleTokenPacketData{ + // Denom is the denom after it was sent to the other chain + // and now it is coming back to Secret, but it's specifed as a full path denom + // because FungibleTokenPacketData had crafted on the other chain + Denom: test.remoteDenom, // + Amount: "1", + Sender: "ignored", + Receiver: contractAddress.String(), // must be the contract address, like in the memo + Memo: fmt.Sprintf(`{"wasm":{"contract":"%s","msg":{"log_msg_sender":{}}}}`, contractAddress.String()), + } + dataBytes, err := json.Marshal(data) + require.NoError(t, err) + + sdkMsg := ibcchanneltypes.MsgRecvPacket{ + Packet: ibcchanneltypes.Packet{ + Sequence: 0, + SourcePort: "transfer", // port on the other chain + SourceChannel: "channel-0", // channel on the other chain + DestinationPort: "transfer", // port on Secret + DestinationChannel: "channel-0", // channel on Secret + Data: dataBytes, + TimeoutHeight: ibcclienttypes.Height{}, + TimeoutTimestamp: 0, + }, + ProofCommitment: []byte{}, + ProofHeight: ibcclienttypes.Height{}, + Signer: walletA.String(), + } - ctx = PrepareSignedTx(t, keeper, ctx, walletA, privKeyA, &sdkMsg) + ctx = PrepareSignedTx(t, keeper, ctx, walletA, privKeyA, &sdkMsg) - _, execErr := keeper.Execute(ctx, contractAddress, walletA, []byte(`{"log_msg_sender":{}}`), sdk.NewCoins(sdk.NewInt64Coin("denom", 1)), nil, cosmwasm.HandleTypeIbcWasmHooksIncomingTransfer) + _, execErr := keeper.Execute(ctx, contractAddress, walletA, []byte(`{"log_msg_sender":{}}`), sdk.NewCoins(sdk.NewInt64Coin(test.localDenom, 1)), nil, cosmwasm.HandleTypeIbcWasmHooksIncomingTransfer) - require.Empty(t, execErr) + require.Empty(t, execErr) - events := tryDecryptWasmEvents(ctx, nil) + events := tryDecryptWasmEvents(ctx, nil) - requireEvents(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - { - Key: "msg.sender", - Value: "", + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + { + Key: "msg.sender", + Value: "", + }, + }, }, - }, - }, - events, - ) - }) + events, + ) + }) + }) + } } } From ceaaeda2a7a387e6f83bb1050de709231b5e75fc Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 May 2023 23:40:17 +0300 Subject: [PATCH 16/54] Test code comments --- .../keeper/secret_contracts_exec_test.go | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index d3e824723..44bba3b8c 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -2375,36 +2375,33 @@ func TestLastMsgMarkerMultipleMsgsInATx(t *testing.T) { func TestIBCHooksIncomingTransfer(t *testing.T) { for _, test := range []struct { - testName string - remoteDenom string // port_on_other_chain/channel_on_other_chain/base_denom or base_denom - localDenom string // denom on Secret ("denom" or "ibc/...") + name string + // remoteDenom: "port_on_other_chain/channel_on_other_chain/base_denom" (e.g. transfer/channel-0/uscrt) or base_denom (e.g. uatom) + remoteDenom string + // localDenom: denom on Secret ("denom" or "ibc/...") + localDenom string }{ { - testName: "denom originated from Secret", + name: "denom originated from Secret", remoteDenom: "transfer/channel-0/denom", localDenom: "denom", }, { - testName: "denom is base denom of the other chain", + name: "denom is base denom of the other chain", remoteDenom: "uatom", localDenom: "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2", }, } { for _, testContract := range testContracts { - t.Run(test.testName, func(t *testing.T) { + t.Run(test.name, func(t *testing.T) { t.Run(testContract.CosmWasmVersion, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath, sdk.NewCoins(sdk.NewInt64Coin(test.localDenom, 1))) _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, testContract.IsCosmWasmV1, defaultGasForTests) require.Empty(t, initErr) - // To send 1denom to the contract over IBC, we need to send FungibleTokenPacketData - // that specifies the denom after it was sent to the other chain. data := ibctransfertypes.FungibleTokenPacketData{ - // Denom is the denom after it was sent to the other chain - // and now it is coming back to Secret, but it's specifed as a full path denom - // because FungibleTokenPacketData had crafted on the other chain - Denom: test.remoteDenom, // + Denom: test.remoteDenom, Amount: "1", Sender: "ignored", Receiver: contractAddress.String(), // must be the contract address, like in the memo From f78bf48db9b0a073b0885398ba66cbc482ab7e88 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 May 2023 23:44:35 +0300 Subject: [PATCH 17/54] Code comments for parse_ibc_hooks_incoming_transfer_message --- .../shared/contract-engine/src/ibc_message.rs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/ibc_message.rs b/cosmwasm/enclaves/shared/contract-engine/src/ibc_message.rs index b85aa0f86..f867ec079 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/ibc_message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/ibc_message.rs @@ -7,18 +7,16 @@ use log::{trace, warn}; pub fn parse_plaintext_ibc_protocol_message( plaintext_message: &[u8], ) -> Result { - let scrt_msg = SecretMessage { - nonce: [0; 32], - user_public_key: [0; 32], - msg: plaintext_message.into(), - }; - Ok(ParsedMessage { should_validate_sig_info: false, should_validate_input: false, was_msg_encrypted: false, should_encrypt_output: false, - secret_msg: scrt_msg, + secret_msg: SecretMessage { + nonce: [0; 32], + user_public_key: [0; 32], + msg: plaintext_message.into(), + }, decrypted_msg: plaintext_message.into(), data_for_validation: None, }) @@ -86,8 +84,10 @@ pub fn parse_ibc_receive_message(message: &[u8]) -> Result Result { Ok(ParsedMessage { should_validate_sig_info: false, @@ -97,9 +97,9 @@ pub fn parse_ibc_hooks_incoming_transfer_message( secret_msg: SecretMessage { nonce: [0; 32], user_public_key: [0; 32], - msg: message.into(), + msg: plaintext_message.into(), }, - decrypted_msg: message.into(), + decrypted_msg: plaintext_message.into(), data_for_validation: None, }) } From 8d854e1bf6524eb3fd122e59be802a90b6138e33 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 23 May 2023 23:57:56 +0300 Subject: [PATCH 18/54] Code comments for ParsedMessage::data_for_validation --- cosmwasm/enclaves/shared/contract-engine/src/types.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/types.rs b/cosmwasm/enclaves/shared/contract-engine/src/types.rs index 616f31792..4b333e81a 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/types.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/types.rs @@ -21,6 +21,7 @@ pub struct ParsedMessage { pub should_encrypt_output: bool, pub secret_msg: SecretMessage, pub decrypted_msg: Vec, + /// data_for_validation is only used when the input is an output of a reply pub data_for_validation: Option>, } From 81113fdc2f1b95dae404c439a8940df011658136 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 May 2023 00:09:09 +0300 Subject: [PATCH 19/54] Make clippy happy --- .../src/contract_validation.rs | 31 +++++++++---------- .../enclaves/shared/cosmos-types/src/types.rs | 6 ++-- .../shared/cosmwasm-types/generic/src/lib.rs | 1 - 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 139dc19d0..329fd2ccc 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -355,14 +355,14 @@ pub fn validate_basic_msg( } /// Verify all the parameters sent to the enclave match up, and were signed by the right account. -#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] pub fn verify_params( sig_info: &SigInfo, sent_funds: &[Coin], sender: &CanonicalAddr, contract_address: &HumanAddr, msg: &SecretMessage, - og_msg: &[u8], + _og_msg: &[u8], should_validate_sig_info: bool, should_validate_input: bool, handle_type: HandleType, @@ -460,7 +460,7 @@ pub fn verify_params( } info!("Parameters verified successfully"); - return Ok(()); + Ok(()) } fn get_signer(sign_info: &SigInfo, sender: &CanonicalAddr) -> Result { @@ -686,7 +686,7 @@ fn get_verified_msg<'sd>( let fungible_token_packet_data= fungible_token_packet_data.unwrap(); - let ibc_hooks_incoming_transfer_msg = serde_json::from_slice::(fungible_token_packet_data.memo.clone().unwrap_or("".into()).as_bytes()); + let ibc_hooks_incoming_transfer_msg = serde_json::from_slice::(fungible_token_packet_data.memo.clone().unwrap_or_else(|| "".to_string()).as_bytes()); if ibc_hooks_incoming_transfer_msg.is_err(){ trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: fungible_token_packet_data.memo cannot be parsed as IbcHooksIncomingTransferMsg: {:?} Error: {:?}", fungible_token_packet_data.memo, ibc_hooks_incoming_transfer_msg.err()); return false; @@ -873,12 +873,12 @@ fn verify_funds(msg: &CosmosMsg, sent_funds_msg: &[Coin]) -> bool { // It needs to be converted to the local denom. // Logic source: https://github.com/scrtlabs/SecretNetwork/blob/96b0ba7d6/x/ibc-hooks/wasm_hook.go#L483-L513 let denom: String = if receiver_chain_is_source( - &source_port, - &source_channel, + source_port, + source_channel, &packet_data.denom, ) { // remove prefix added by sender chain - let voucher_prefix = get_denom_prefix(&source_port, &source_channel); + let voucher_prefix = get_denom_prefix(source_port, source_channel); let unprefixed_denom: String = match packet_data .denom @@ -898,17 +898,15 @@ fn verify_funds(msg: &CosmosMsg, sent_funds_msg: &[Coin]) -> bool { // The denomination used to send the coins is either the native denom or the hash of the path // if the denomination is not native. let denom_trace = parse_denom_trace(&unprefixed_denom); - if denom_trace.path != "" { + if !denom_trace.path.is_empty() { denom_trace.ibc_denom() } else { unprefixed_denom } } else { - let prefixed_denom = get_denom_prefix(&destination_port, &destination_channel) + let prefixed_denom = get_denom_prefix(destination_port, destination_channel) + &packet_data.denom; - let denom = parse_denom_trace(&prefixed_denom).ibc_denom(); - - denom + parse_denom_trace(&prefixed_denom).ibc_denom() }; // Check denom @@ -924,9 +922,8 @@ fn verify_funds(msg: &CosmosMsg, sent_funds_msg: &[Coin]) -> bool { true } else { // Packet is for an IBC enabled contract - // No funds should be sent - sent_funds_msg.len() == 0 + sent_funds_msg.is_empty() } } } @@ -962,7 +959,7 @@ fn verify_message_params( // Going to pass null sender to the contract if all other checks pass. } CosmosMsg::Execute { .. } | CosmosMsg::Instantiate { .. } | CosmosMsg::Other => { - if msg.sender() != Some(&sender) { + if msg.sender() != Some(sender) { warn!( "message sender did not match cosmwasm message sender: {:?} {:?}", sender, msg @@ -1071,8 +1068,8 @@ fn parse_denom_trace(raw_denom: &str) -> DenomTrace { let (path, base_denom) = extract_path_and_base_from_full_denom(&denom_split); DenomTrace { - path: path.to_string(), - base_denom: base_denom.to_string(), + path, + base_denom, } } diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index a9ca70e66..f0387fee0 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -530,7 +530,7 @@ impl CosmosMsg { raw_msg.sender ); - if raw_msg.sender.len() == 0 { + if raw_msg.sender.is_empty() { warn!("try_parse_instantiate: sender address to instantiate was empty"); return Err(EnclaveError::FailedToDeserialize); } @@ -560,7 +560,7 @@ impl CosmosMsg { raw_msg.sender ); - if raw_msg.sender.len() == 0 { + if raw_msg.sender.is_empty() { warn!("try_parse_execute: sender address to execute was empty"); return Err(EnclaveError::FailedToDeserialize); } @@ -571,7 +571,7 @@ impl CosmosMsg { raw_msg.contract ); - if raw_msg.contract.len() == 0 { + if raw_msg.contract.is_empty() { warn!("try_parse_execute: contract address to execute was empty"); return Err(EnclaveError::FailedToDeserialize); } diff --git a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs index c9298da85..c1249e525 100644 --- a/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs +++ b/cosmwasm/enclaves/shared/cosmwasm-types/generic/src/lib.rs @@ -10,7 +10,6 @@ use cw_types_v1::types::Env as V1Env; use cw_types_v1::types::MessageInfo as V1MessageInfo; use cw_types_v1::types::{self as v1types, Addr}; use enclave_ffi_types::EnclaveError; -use serde_json; pub const CONTRACT_KEY_LENGTH: usize = 64; From cb1bd385dd4ed6f92580f1a62baff20ab2ec0c98 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 May 2023 00:48:16 +0300 Subject: [PATCH 20/54] golangci-lint run ./... --- app/app.go | 5 +- app/legacy/v170/migrate.go | 2 +- app/modules.go | 2 +- app/upgrades/v1.5/upgrade.go | 2 +- app/upgrades/v1.6/upgrade.go | 2 +- app/upgrades/v1.7/upgrade.go | 3 +- app/upgrades/v1.8/upgrade.go | 2 +- cmd/secretd/init.go | 4 +- cmd/secretd/root.go | 7 +- go-cosmwasm/api/callbacks.go | 10 +-- go-cosmwasm/lib.go | 2 - go-cosmwasm/types/v1/ibc.go | 4 +- x/compute/ibc.go | 3 +- x/compute/internal/keeper/ante.go | 1 + x/compute/internal/keeper/handler_plugin.go | 14 ++-- x/compute/internal/keeper/ibc.go | 4 +- x/compute/internal/keeper/keeper.go | 21 +++-- x/compute/internal/keeper/legacy_querier.go | 2 +- x/compute/internal/keeper/msg_dispatcher.go | 15 ++-- x/compute/internal/keeper/relay.go | 4 +- x/compute/internal/keeper/wasm_snapshotter.go | 2 +- x/compute/module.go | 18 ++-- x/ibc-hooks/client/cli/query.go | 2 +- x/ibc-hooks/sdkmodule.go | 20 ++--- x/mauth/ibc_module.go | 82 +++++++++---------- x/mauth/module.go | 14 ++-- x/mauth/types/codec.go | 2 +- x/mauth/types/msgs.go | 12 +-- x/mauth/types/query.go | 2 +- x/registration/alias.go | 2 +- x/registration/client/rest/tx.go | 2 +- .../internal/keeper/mock/enclave.go | 4 +- x/registration/internal/types/genesis.go | 2 +- x/registration/internal/types/reg_keys.go | 4 +- x/registration/internal/types/types.go | 12 +-- x/registration/module.go | 16 ++-- .../remote_attestation/remote_attestation.go | 2 +- 37 files changed, 153 insertions(+), 154 deletions(-) diff --git a/app/app.go b/app/app.go index d4f04b5d1..395455ed5 100644 --- a/app/app.go +++ b/app/app.go @@ -2,13 +2,14 @@ package app import ( "fmt" - ibcfeetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" "io" "net/http" "os" "path/filepath" + ibcfeetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" + packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" diff --git a/app/legacy/v170/migrate.go b/app/legacy/v170/migrate.go index ec9036cad..a61d60c80 100644 --- a/app/legacy/v170/migrate.go +++ b/app/legacy/v170/migrate.go @@ -9,7 +9,7 @@ import ( v170registration "github.com/scrtlabs/SecretNetwork/x/registration/legacy/v170" ) -func Migrate(appState types.AppMap, clientCtx client.Context) types.AppMap { +func Migrate(appState types.AppMap, _ client.Context) types.AppMap { legacyAminoCodec := codec.NewLegacyAmino() if appState[v120registration.ModuleName] != nil { diff --git a/app/modules.go b/app/modules.go index 14ebc10b4..30fa79c6d 100644 --- a/app/modules.go +++ b/app/modules.go @@ -48,7 +48,7 @@ var ModuleAccountPermissions = map[string][]string{ compute.ModuleName: {authtypes.Burner}, } -func AppModules( +func AppModules( //nolint:all app *SecretNetworkApp, encodingConfig EncodingConfig, skipGenesisInvariants bool, diff --git a/app/upgrades/v1.5/upgrade.go b/app/upgrades/v1.5/upgrade.go index 8c8f31567..76b08cdcb 100644 --- a/app/upgrades/v1.5/upgrade.go +++ b/app/upgrades/v1.5/upgrade.go @@ -17,7 +17,7 @@ var Upgrade = upgrades.Upgrade{ StoreUpgrades: store.StoreUpgrades{}, } -func createUpgradeHandler(mm *module.Manager, keepers *keepers.SecretAppKeepers, configurator module.Configurator, +func createUpgradeHandler(mm *module.Manager, keepers *keepers.SecretAppKeepers, configurator module.Configurator, //nolint:all ) upgradetypes.UpgradeHandler { return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { ctx.Logger().Info(` _ _ _____ _____ _____ _____ ______ `) diff --git a/app/upgrades/v1.6/upgrade.go b/app/upgrades/v1.6/upgrade.go index f940b93f7..514b2f290 100644 --- a/app/upgrades/v1.6/upgrade.go +++ b/app/upgrades/v1.6/upgrade.go @@ -17,7 +17,7 @@ var Upgrade = upgrades.Upgrade{ StoreUpgrades: store.StoreUpgrades{}, } -func createUpgradeHandler(mm *module.Manager, keepers *keepers.SecretAppKeepers, configurator module.Configurator, +func createUpgradeHandler(mm *module.Manager, keepers *keepers.SecretAppKeepers, configurator module.Configurator, //nolint:all ) upgradetypes.UpgradeHandler { return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { ctx.Logger().Info(` _ _ _____ _____ _____ _____ ______ `) diff --git a/app/upgrades/v1.7/upgrade.go b/app/upgrades/v1.7/upgrade.go index 3f60de896..c39d49510 100644 --- a/app/upgrades/v1.7/upgrade.go +++ b/app/upgrades/v1.7/upgrade.go @@ -5,10 +5,11 @@ import ( "encoding/hex" "encoding/json" "fmt" - icacontrollertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" "os" "path/filepath" + icacontrollertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" + store "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" diff --git a/app/upgrades/v1.8/upgrade.go b/app/upgrades/v1.8/upgrade.go index ac422182b..2453975d8 100644 --- a/app/upgrades/v1.8/upgrade.go +++ b/app/upgrades/v1.8/upgrade.go @@ -19,7 +19,7 @@ var Upgrade = upgrades.Upgrade{ StoreUpgrades: store.StoreUpgrades{}, } -func createUpgradeHandler(mm *module.Manager, keepers *keepers.SecretAppKeepers, configurator module.Configurator, +func createUpgradeHandler(mm *module.Manager, keepers *keepers.SecretAppKeepers, configurator module.Configurator, //nolint:all ) upgradetypes.UpgradeHandler { return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { ctx.Logger().Info(` _ _ _____ _____ _____ _____ ______ `) diff --git a/cmd/secretd/init.go b/cmd/secretd/init.go index 67991aa03..0e0cbd1b7 100644 --- a/cmd/secretd/init.go +++ b/cmd/secretd/init.go @@ -107,8 +107,8 @@ func InitCmd(mbm module.BasicManager, defaultNodeHome string) *cobra.Command { // Get bip39 mnemonic var mnemonic string - recover, _ := cmd.Flags().GetBool(FlagRecover) - if recover { + isRecover, _ := cmd.Flags().GetBool(FlagRecover) + if isRecover { inBuf := bufio.NewReader(cmd.InOrStdin()) value, err := input.GetString("Enter your bip39 mnemonic", inBuf) if err != nil { diff --git a/cmd/secretd/root.go b/cmd/secretd/root.go index 53a0bc7d1..7d769ec6c 100644 --- a/cmd/secretd/root.go +++ b/cmd/secretd/root.go @@ -348,11 +348,8 @@ func updateTmParamsAndInit(mbm module.BasicManager, defaultNodeHome string) *cob serverconfig.WriteConfigFile(appConfigFilePath, appConf) - if err := originalFunc(cmd, args); err != nil { - return err - } - - return nil + err := originalFunc(cmd, args) + return err } cmd.RunE = wrappedFunc diff --git a/go-cosmwasm/api/callbacks.go b/go-cosmwasm/api/callbacks.go index 4ce92d011..15ccba9ef 100644 --- a/go-cosmwasm/api/callbacks.go +++ b/go-cosmwasm/api/callbacks.go @@ -158,7 +158,7 @@ func buildIterator(dbCounter uint64, it dbm.Iterator) C.iterator_t { } //export cGet -func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, key C.Buffer, val *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { +func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, key C.Buffer, val *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { //nolint:all defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil || val == nil { // we received an invalid pointer @@ -187,7 +187,7 @@ func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, key C.Buffer, val } //export cSet -func cSet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key C.Buffer, val C.Buffer, errOut *C.Buffer) (ret C.GoResult) { +func cSet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key C.Buffer, val C.Buffer, errOut *C.Buffer) (ret C.GoResult) { //nolint:all defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil { // we received an invalid pointer @@ -208,7 +208,7 @@ func cSet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key C.Buffe } //export cDelete -func cDelete(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key C.Buffer, errOut *C.Buffer) (ret C.GoResult) { +func cDelete(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key C.Buffer, errOut *C.Buffer) (ret C.GoResult) { //nolint:all defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil { // we received an invalid pointer @@ -228,7 +228,7 @@ func cDelete(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key C.Bu } //export cScan -func cScan(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, start C.Buffer, end C.Buffer, order i32, out *C.GoIter, errOut *C.Buffer) (ret C.GoResult) { +func cScan(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, start C.Buffer, end C.Buffer, order i32, out *C.GoIter, errOut *C.Buffer) (ret C.GoResult) { //nolint:all defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil || out == nil { // we received an invalid pointer @@ -266,7 +266,7 @@ func cScan(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, start C.Bu } //export cNext -func cNext(ref C.iterator_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key *C.Buffer, val *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { +func cNext(ref C.iterator_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key *C.Buffer, val *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { //nolint:all // typical usage of iterator // for ; itr.Valid(); itr.Next() { // k, v := itr.Key(); itr.Value() diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index 9f14c0f0d..26165f145 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/scrtlabs/SecretNetwork/go-cosmwasm/api" types "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types" v010types "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types/v010" @@ -140,7 +139,6 @@ func (w *Wasmer) Instantiate( gasMeter GasMeter, gasLimit uint64, sigInfo types.VerificationInfo, - contractAddress sdk.AccAddress, ) (interface{}, []byte, uint64, error) { paramBin, err := json.Marshal(env) if err != nil { diff --git a/go-cosmwasm/types/v1/ibc.go b/go-cosmwasm/types/v1/ibc.go index aa594c53e..de6758928 100644 --- a/go-cosmwasm/types/v1/ibc.go +++ b/go-cosmwasm/types/v1/ibc.go @@ -168,9 +168,9 @@ const ( func IBCOrderToEnum(o IBCOrder) ibcchanneltypes.Order { if o == Unordered { return ibcchanneltypes.UNORDERED - } else { - return ibcchanneltypes.ORDERED } + + return ibcchanneltypes.ORDERED } // IBCTimeoutBlock Height is a monotonically increasing data type diff --git a/x/compute/ibc.go b/x/compute/ibc.go index 4b5fa9a81..efd09c759 100644 --- a/x/compute/ibc.go +++ b/x/compute/ibc.go @@ -178,7 +178,8 @@ func (i IBCHandler) OnChanOpenConfirm(ctx sdk.Context, portID, channelID string) } msg := v1types.IBCChannelConnectMsg{ OpenConfirm: &v1types.IBCOpenConfirm{ - Channel: toWasmVMChannel(portID, channelID, channelInfo, appVersion)}, + Channel: toWasmVMChannel(portID, channelID, channelInfo, appVersion), + }, } return i.keeper.OnConnectChannel(ctx, contractAddr, msg) } diff --git a/x/compute/internal/keeper/ante.go b/x/compute/internal/keeper/ante.go index 629c9a06b..40e684ab0 100644 --- a/x/compute/internal/keeper/ante.go +++ b/x/compute/internal/keeper/ante.go @@ -2,6 +2,7 @@ package keeper import ( "encoding/binary" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/scrtlabs/SecretNetwork/x/compute/internal/types" ) diff --git a/x/compute/internal/keeper/handler_plugin.go b/x/compute/internal/keeper/handler_plugin.go index 2242d470f..52cd69332 100644 --- a/x/compute/internal/keeper/handler_plugin.go +++ b/x/compute/internal/keeper/handler_plugin.go @@ -93,9 +93,9 @@ func NewMessageHandler( // order to find the right one to process given message. If a handler cannot // process given message (returns ErrUnknownMsg), its result is ignored and the // next handler is executed. -func (m MessageHandlerChain) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg v1wasmTypes.CosmosMsg, ogMessageVersion wasmTypes.CosmosMsgVersion) ([]sdk.Event, [][]byte, error) { +func (m MessageHandlerChain) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg v1wasmTypes.CosmosMsg) ([]sdk.Event, [][]byte, error) { for _, h := range m.handlers { - events, data, err := h.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg, ogMessageVersion) + events, data, err := h.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg) switch { case err == nil: return events, data, nil @@ -109,7 +109,7 @@ func (m MessageHandlerChain) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAd } // DispatchMsg publishes a raw IBC packet onto the channel. -func (h IBCRawPacketHandler) DispatchMsg(ctx sdk.Context, _ sdk.AccAddress, contractIBCPortID string, msg v1wasmTypes.CosmosMsg, ogMessageVersion wasmTypes.CosmosMsgVersion) (events []sdk.Event, data [][]byte, err error) { +func (h IBCRawPacketHandler) DispatchMsg(ctx sdk.Context, _ sdk.AccAddress, contractIBCPortID string, msg v1wasmTypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { if msg.IBC == nil || msg.IBC.SendPacket == nil { return nil, nil, types.ErrUnknownMsg } @@ -353,7 +353,7 @@ func EncodeBankMsg(sender sdk.AccAddress, msg *v1wasmTypes.BankMsg) ([]sdk.Msg, return []sdk.Msg{&sdkMsg}, nil } -func NoCustomMsg(sender sdk.AccAddress, msg json.RawMessage) ([]sdk.Msg, error) { +func NoCustomMsg(_ sdk.AccAddress, _ json.RawMessage) ([]sdk.Msg, error) { return nil, sdkerrors.Wrap(types.ErrInvalidMsg, "Custom variant not supported") } @@ -466,12 +466,12 @@ func EncodeStakingMsg(sender sdk.AccAddress, msg *v1wasmTypes.StakingMsg) ([]sdk func EncodeStargateMsg(unpacker codectypes.AnyUnpacker) StargateEncoder { return func(sender sdk.AccAddress, msg *v1wasmTypes.StargateMsg) ([]sdk.Msg, error) { - any := codectypes.Any{ + anyObj := codectypes.Any{ TypeUrl: msg.TypeURL, Value: msg.Value, } var sdkMsg sdk.Msg - if err := unpacker.UnpackAny(&any, &sdkMsg); err != nil { + if err := unpacker.UnpackAny(&anyObj, &sdkMsg); err != nil { return nil, sdkerrors.Wrap(types.ErrInvalidMsg, fmt.Sprintf("Cannot unpack proto message with type URL: %s", msg.TypeURL)) } if err := codectypes.UnpackInterfaces(sdkMsg, unpacker); err != nil { @@ -524,7 +524,7 @@ func EncodeWasmMsg(sender sdk.AccAddress, msg *v1wasmTypes.WasmMsg) ([]sdk.Msg, } } -func (h SDKMessageHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg v1wasmTypes.CosmosMsg, ogMessageVersion wasmTypes.CosmosMsgVersion) ([]sdk.Event, [][]byte, error) { +func (h SDKMessageHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg v1wasmTypes.CosmosMsg) ([]sdk.Event, [][]byte, error) { sdkMsgs, err := h.encoders.Encode(ctx, contractAddr, contractIBCPortID, msg) if err != nil { return nil, nil, err diff --git a/x/compute/internal/keeper/ibc.go b/x/compute/internal/keeper/ibc.go index 9fb950ff3..571f6c885 100644 --- a/x/compute/internal/keeper/ibc.go +++ b/x/compute/internal/keeper/ibc.go @@ -15,8 +15,8 @@ import ( // returns a string name of the port or error if we cannot bind it. // this will fail if call twice. func (k Keeper) bindIbcPort(ctx sdk.Context, portID string) error { - cap := k.portKeeper.BindPort(ctx, portID) - return k.ClaimCapability(ctx, cap, host.PortPath(portID)) + capability := k.portKeeper.BindPort(ctx, portID) + return k.ClaimCapability(ctx, capability, host.PortPath(portID)) } // ensureIbcPort is like registerIbcPort, but it checks if we already hold the port diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 4c080b9fa..22e142ae3 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -456,7 +456,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre // instantiate wasm contract gas := gasForContract(ctx) - response, key, gasUsed, err := k.wasmer.Instantiate(codeInfo.CodeHash, env, initMsg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo, contractAddress) + response, key, gasUsed, err := k.wasmer.Instantiate(codeInfo.CodeHash, env, initMsg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, verificationInfo) consumeGas(ctx, gasUsed) if err != nil { @@ -490,7 +490,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre return nil, nil, sdkerrors.Wrap(err, "couldn't convert v0.10 messages to v1 messages") } - data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, subMessages, res.Log, []v1wasmTypes.Event{}, res.Data, initMsg, verificationInfo, wasmTypes.CosmosMsgVersionV010) + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, subMessages, res.Log, []v1wasmTypes.Event{}, res.Data, initMsg, verificationInfo) if err != nil { return nil, nil, sdkerrors.Wrap(err, "dispatch") } @@ -527,7 +527,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator sdk.AccAddre store.Set(types.GetContractLabelPrefix(label), contractAddress) - data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, initMsg, verificationInfo, wasmTypes.CosmosMsgVersionV1) + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, initMsg, verificationInfo) if err != nil { return nil, nil, sdkerrors.Wrap(err, "dispatch") } @@ -615,7 +615,7 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller return nil, sdkerrors.Wrap(err, "couldn't convert v0.10 messages to v1 messages") } - data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, subMessages, res.Log, []v1wasmTypes.Event{}, res.Data, msg, verificationInfo, wasmTypes.CosmosMsgVersionV010) + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, subMessages, res.Log, []v1wasmTypes.Event{}, res.Data, msg, verificationInfo) if err != nil { return nil, sdkerrors.Wrap(err, "dispatch") } @@ -629,7 +629,7 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()), )) - data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, msg, verificationInfo, wasmTypes.CosmosMsgVersionV1) + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, msg, verificationInfo) if err != nil { return nil, sdkerrors.Wrap(err, "dispatch") } @@ -916,7 +916,6 @@ func (k *Keeper) handleContractResponse( // sigInfo of the initial message that triggered the original contract call // This is used mainly in replies in order to decrypt their data. ogSigInfo wasmTypes.VerificationInfo, - ogCosmosMessageVersion wasmTypes.CosmosMsgVersion, ) ([]byte, error) { events := types.ContractLogsToSdkEvents(logs, contractAddr) @@ -933,7 +932,7 @@ func (k *Keeper) handleContractResponse( } responseHandler := NewContractResponseHandler(NewMessageDispatcher(k.messenger, k)) - return responseHandler.Handle(ctx, contractAddr, ibcPort, msgs, data, ogTx, ogSigInfo, ogCosmosMessageVersion) + return responseHandler.Handle(ctx, contractAddr, ibcPort, msgs, data, ogTx, ogSigInfo) } func gasForContract(ctx sdk.Context) uint64 { @@ -1049,7 +1048,7 @@ func gasMeter(ctx sdk.Context) MultipiedGasMeter { } type MsgDispatcher interface { - DispatchSubmessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []v1wasmTypes.SubMsg, ogTx []byte, ogSigInfo wasmTypes.VerificationInfo, ogCosmosMessageVersion wasmTypes.CosmosMsgVersion) ([]byte, error) + DispatchSubmessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []v1wasmTypes.SubMsg, ogTx []byte, ogSigInfo wasmTypes.VerificationInfo) ([]byte, error) } // ContractResponseHandler default implementation that first dispatches submessage then normal messages. @@ -1064,9 +1063,9 @@ func NewContractResponseHandler(md MsgDispatcher) *ContractResponseHandler { } // Handle processes the data returned by a contract invocation. -func (h ContractResponseHandler) Handle(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, messages []v1wasmTypes.SubMsg, origRspData []byte, ogTx []byte, ogSigInfo wasmTypes.VerificationInfo, ogCosmosMessageVersion wasmTypes.CosmosMsgVersion) ([]byte, error) { +func (h ContractResponseHandler) Handle(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, messages []v1wasmTypes.SubMsg, origRspData []byte, ogTx []byte, ogSigInfo wasmTypes.VerificationInfo) ([]byte, error) { result := origRspData - switch rsp, err := h.md.DispatchSubmessages(ctx, contractAddr, ibcPort, messages, ogTx, ogSigInfo, ogCosmosMessageVersion); { + switch rsp, err := h.md.DispatchSubmessages(ctx, contractAddr, ibcPort, messages, ogTx, ogSigInfo); { case err != nil: return nil, sdkerrors.Wrap(err, "submessages") case rsp != nil: @@ -1126,7 +1125,7 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply v1w sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()), )) - data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, ogTx, ogSigInfo, wasmTypes.CosmosMsgVersionV1) + data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Events, res.Data, ogTx, ogSigInfo) if err != nil { return nil, sdkerrors.Wrap(types.ErrReplyFailed, err.Error()) } diff --git a/x/compute/internal/keeper/legacy_querier.go b/x/compute/internal/keeper/legacy_querier.go index 4abafab0e..2a4e78abb 100644 --- a/x/compute/internal/keeper/legacy_querier.go +++ b/x/compute/internal/keeper/legacy_querier.go @@ -122,7 +122,7 @@ func NewLegacyQuerier(keeper Keeper) sdk.Querier { } } -func queryContractState(ctx sdk.Context, bech, queryMethod string, data []byte, keeper Keeper) (json.RawMessage, error) { +func queryContractState(ctx sdk.Context, bech, queryMethod string, data []byte, keeper Keeper) (json.RawMessage, error) { //nolint:all contractAddr, err := sdk.AccAddressFromBech32(bech) if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, bech) diff --git a/x/compute/internal/keeper/msg_dispatcher.go b/x/compute/internal/keeper/msg_dispatcher.go index 121778259..718fd17bd 100644 --- a/x/compute/internal/keeper/msg_dispatcher.go +++ b/x/compute/internal/keeper/msg_dispatcher.go @@ -4,11 +4,12 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/cosmos/cosmos-sdk/baseapp" "os" "sort" "strings" + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" wasmTypes "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types" @@ -22,7 +23,7 @@ import ( type Messenger interface { // DispatchMsg encodes the wasmVM message and dispatches it. - DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg v1wasmTypes.CosmosMsg, ogMessageVersion wasmTypes.CosmosMsgVersion) (events []sdk.Event, data [][]byte, err error) + DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg v1wasmTypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) } // Replyer is a subset of keeper that can handle replies to submessages @@ -76,7 +77,7 @@ func sdkEventsToWasmVMEvents(events []sdk.Event) []v1wasmTypes.Event { } // dispatchMsgWithGasLimit sends a message with gas limit applied -func (d MessageDispatcher) dispatchMsgWithGasLimit(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msg v1wasmTypes.CosmosMsg, gasLimit uint64, ogCosmosMessageVersion wasmTypes.CosmosMsgVersion) (events []sdk.Event, data [][]byte, err error) { +func (d MessageDispatcher) dispatchMsgWithGasLimit(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msg v1wasmTypes.CosmosMsg, gasLimit uint64) (events []sdk.Event, data [][]byte, err error) { limitedMeter := sdk.NewGasMeter(gasLimit) subCtx := ctx.WithGasMeter(limitedMeter) @@ -93,7 +94,7 @@ func (d MessageDispatcher) dispatchMsgWithGasLimit(ctx sdk.Context, contractAddr err = sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "SubMsg hit gas limit") } }() - events, data, err = d.messenger.DispatchMsg(subCtx, contractAddr, ibcPort, msg, ogCosmosMessageVersion) + events, data, err = d.messenger.DispatchMsg(subCtx, contractAddr, ibcPort, msg) // make sure we charge the parent what was spent spent := subCtx.GasMeter().GasConsumed() @@ -185,7 +186,7 @@ func redactError(err error) (bool, error) { // DispatchSubmessages builds a sandbox to execute these messages and returns the execution result to the contract // that dispatched them, both on success as well as failure -func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []v1wasmTypes.SubMsg, ogTx []byte, ogSigInfo wasmTypes.VerificationInfo, ogCosmosMessageVersion wasmTypes.CosmosMsgVersion) ([]byte, error) { +func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []v1wasmTypes.SubMsg, ogTx []byte, ogSigInfo wasmTypes.VerificationInfo) ([]byte, error) { var rsp []byte for _, msg := range msgs { @@ -220,9 +221,9 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk var events []sdk.Event var data [][]byte if limitGas { - events, data, err = d.dispatchMsgWithGasLimit(subCtx, contractAddr, ibcPort, msg.Msg, *msg.GasLimit, ogCosmosMessageVersion) + events, data, err = d.dispatchMsgWithGasLimit(subCtx, contractAddr, ibcPort, msg.Msg, *msg.GasLimit) } else { - events, data, err = d.messenger.DispatchMsg(subCtx, contractAddr, ibcPort, msg.Msg, ogCosmosMessageVersion) + events, data, err = d.messenger.DispatchMsg(subCtx, contractAddr, ibcPort, msg.Msg) } // if it succeeds, commit state changes from submessage, and pass on events to Event Manager diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index b42b87b9e..253d382a2 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -221,7 +221,7 @@ func (k Keeper) OnRecvPacket( } // note submessage reply results can overwrite the `Acknowledgement` data - return k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, resp.Messages, resp.Attributes, resp.Events, resp.Acknowledgement, ogTx, verificationInfo, wasmTypes.CosmosMsgVersionV1) + return k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, resp.Messages, resp.Attributes, resp.Events, resp.Acknowledgement, ogTx, verificationInfo) } // should never get here as it's already checked in @@ -297,6 +297,6 @@ func (k Keeper) OnTimeoutPacket( func (k Keeper) handleIBCBasicContractResponse(ctx sdk.Context, addr sdk.AccAddress, ibcPortID string, inputMsg []byte, res *v1types.IBCBasicResponse) error { verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) - _, err := k.handleContractResponse(ctx, addr, ibcPortID, res.Messages, res.Attributes, res.Events, nil, inputMsg, verificationInfo, wasmTypes.CosmosMsgVersionV1) + _, err := k.handleContractResponse(ctx, addr, ibcPortID, res.Messages, res.Attributes, res.Events, nil, inputMsg, verificationInfo) return err } diff --git a/x/compute/internal/keeper/wasm_snapshotter.go b/x/compute/internal/keeper/wasm_snapshotter.go index 801740b41..663bd7e6e 100644 --- a/x/compute/internal/keeper/wasm_snapshotter.go +++ b/x/compute/internal/keeper/wasm_snapshotter.go @@ -126,7 +126,7 @@ func (ws *WasmSnapshotter) Snapshot(height uint64, protoWriter protoio.Writer) e } func (ws *WasmSnapshotter) Restore( - height uint64, format uint32, protoReader protoio.Reader, + height uint64, format uint32, protoReader protoio.Reader, //nolint:all ) (snapshottypes.SnapshotItem, error) { if format != 1 { return snapshottypes.SnapshotItem{}, snapshottypes.ErrUnknownFormat diff --git a/x/compute/module.go b/x/compute/module.go index b3b135ef3..1fefbd8b2 100644 --- a/x/compute/module.go +++ b/x/compute/module.go @@ -57,7 +57,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { } // ValidateGenesis performs genesis state validation for the compute module. -func (AppModuleBasic) ValidateGenesis(marshaler codec.JSONCodec, config client.TxEncodingConfig, message json.RawMessage) error { +func (AppModuleBasic) ValidateGenesis(marshaler codec.JSONCodec, _ client.TxEncodingConfig, message json.RawMessage) error { var data GenesisState err := marshaler.UnmarshalJSON(message, &data) if err != nil { @@ -118,12 +118,12 @@ func (am AppModule) RegisterServices(configurator module.Configurator) { // } } -func (am AppModule) LegacyQuerierHandler(amino *codec.LegacyAmino) sdk.Querier { +func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { return keeper.NewLegacyQuerier(am.keeper) } // RegisterInvariants registers the compute module invariants. -func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} // Route returns the message routing key for the compute module. func (am AppModule) Route() sdk.Route { @@ -181,7 +181,7 @@ func (am AppModule) BeginBlock(ctx sdk.Context, beginBlock abci.RequestBeginBloc } if beginBlock.Header.EncryptedRandom != nil { - randomAndProof := append(beginBlock.Header.EncryptedRandom.Random, beginBlock.Header.EncryptedRandom.Proof...) + randomAndProof := append(beginBlock.Header.EncryptedRandom.Random, beginBlock.Header.EncryptedRandom.Proof...) //nolint:all random, err := api.SubmitBlockSignatures(header, commit, data, randomAndProof) if err != nil { panic(err) @@ -205,24 +205,24 @@ func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.Validato // AppModuleSimulation functions // GenerateGenesisState creates a randomized GenState of the bank module. -func (AppModule) GenerateGenesisState(simState *module.SimulationState) { +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { //nolint:all } // ProposalContents doesn't return any content functions for governance proposals. -func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent { +func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent { //nolint:all return nil } // RandomizedParams creates randomized bank param changes for the simulator. -func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { +func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { //nolint:all return nil } // RegisterStoreDecoder registers a decoder for supply module's types -func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { +func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { //nolint:all } // WeightedOperations returns the all the gov module operations with their respective weights. -func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { +func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { //nolint:all return nil } diff --git a/x/ibc-hooks/client/cli/query.go b/x/ibc-hooks/client/cli/query.go index c3afa9571..4d3a9503e 100644 --- a/x/ibc-hooks/client/cli/query.go +++ b/x/ibc-hooks/client/cli/query.go @@ -13,7 +13,7 @@ import ( "github.com/scrtlabs/SecretNetwork/x/ibc-hooks/types" ) -func indexRunCmd(cmd *cobra.Command, args []string) error { +func indexRunCmd(cmd *cobra.Command, args []string) error { //nolint:all usageTemplate := `Usage:{{if .HasAvailableSubCommands}} {{.CommandPath}} [command]{{end}} diff --git a/x/ibc-hooks/sdkmodule.go b/x/ibc-hooks/sdkmodule.go index 13320cce6..a69528a17 100644 --- a/x/ibc-hooks/sdkmodule.go +++ b/x/ibc-hooks/sdkmodule.go @@ -38,28 +38,28 @@ func (AppModuleBasic) Name() string { } // RegisterLegacyAminoCodec registers the ibc-hooks module's types on the given LegacyAmino codec. -func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} +func (AppModuleBasic) RegisterLegacyAminoCodec(_ *codec.LegacyAmino) {} // RegisterInterfaces registers the module's interface types. func (b AppModuleBasic) RegisterInterfaces(_ cdctypes.InterfaceRegistry) {} // DefaultGenesis returns default genesis state as raw bytes for the // module. -func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { +func (AppModuleBasic) DefaultGenesis(_ codec.JSONCodec) json.RawMessage { emptyString := "{}" return []byte(emptyString) } // ValidateGenesis performs genesis state validation for the ibc-hooks module. -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { +func (AppModuleBasic) ValidateGenesis(_ codec.JSONCodec, _ client.TxEncodingConfig, _ json.RawMessage) error { return nil } // RegisterRESTRoutes registers the REST routes for the ibc-hooks module. -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) {} +func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) {} //nolint:all // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the ibc-hooks module. -func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {} +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {} //nolint:all // GetTxCmd returns no root tx command for the ibc-hooks module. func (AppModuleBasic) GetTxCmd() *cobra.Command { return nil } @@ -103,7 +103,7 @@ func (AppModule) QuerierRoute() string { } // LegacyQuerierHandler returns the x/ibc-hooks module's sdk.Querier. -func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { +func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { return func(sdk.Context, []string, abci.RequestQuery) ([]byte, error) { return nil, fmt.Errorf("legacy querier not supported for the x/%s module", types.ModuleName) } @@ -111,21 +111,21 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd // RegisterServices registers a gRPC query service to respond to the // module-specific gRPC queries. -func (am AppModule) RegisterServices(cfg module.Configurator) { +func (am AppModule) RegisterServices(cfg module.Configurator) { //nolint:all } // InitGenesis performs genesis initialization for the ibc-hooks module. It returns // no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { +func (am AppModule) InitGenesis(_ sdk.Context, _ codec.JSONCodec, _ json.RawMessage) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } -func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { +func (am AppModule) ExportGenesis(_ sdk.Context, _ codec.JSONCodec) json.RawMessage { return json.RawMessage([]byte("{}")) } // BeginBlock returns the begin blocker for the ibc-hooks module. -func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { +func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) { } // EndBlock returns the end blocker for the ibc-hooks module. It returns no validator diff --git a/x/mauth/ibc_module.go b/x/mauth/ibc_module.go index 3312ff2b4..084f7d188 100644 --- a/x/mauth/ibc_module.go +++ b/x/mauth/ibc_module.go @@ -29,12 +29,12 @@ func NewIBCModule(k keeper.Keeper) IBCModule { // OnChanOpenInit implements the IBCModule interface func (im IBCModule) OnChanOpenInit( ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, + order channeltypes.Order, //nolint:all + connectionHops []string, //nolint:all portID string, channelID string, chanCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, + counterparty channeltypes.Counterparty, //nolint:all version string, ) (string, error) { err := im.keeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)) @@ -47,52 +47,52 @@ func (im IBCModule) OnChanOpenInit( // OnChanOpenTry implements the IBCModule interface func (im IBCModule) OnChanOpenTry( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID, - channelID string, - chanCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - counterpartyVersion string, + ctx sdk.Context, //nolint:all + order channeltypes.Order, //nolint:all + connectionHops []string, //nolint:all + portID, //nolint:all + channelID string, //nolint:all + chanCap *capabilitytypes.Capability, //nolint:all + counterparty channeltypes.Counterparty, //nolint:all + counterpartyVersion string, //nolint:all ) (version string, err error) { return "", nil } // OnChanOpenAck implements the IBCModule interface func (im IBCModule) OnChanOpenAck( - ctx sdk.Context, - portID, - channelID string, - counterpartychannelID string, - counterpartyVersion string, + ctx sdk.Context, //nolint:all + portID, //nolint:all + channelID string, //nolint:all + counterpartychannelID string, //nolint:all + counterpartyVersion string, //nolint:all ) error { return nil } // OnChanOpenConfirm implements the IBCModule interface func (im IBCModule) OnChanOpenConfirm( - ctx sdk.Context, - portID, - channelID string, + ctx sdk.Context, //nolint:all + portID, //nolint:all + channelID string, //nolint:all ) error { return nil } // OnChanCloseInit implements the IBCModule interface func (im IBCModule) OnChanCloseInit( - ctx sdk.Context, - portID, - channelID string, + ctx sdk.Context, //nolint:all + portID, //nolint:all + channelID string, //nolint:all ) error { return nil } // OnChanCloseConfirm implements the IBCModule interface func (im IBCModule) OnChanCloseConfirm( - ctx sdk.Context, - portID, - channelID string, + ctx sdk.Context, //nolint:all + portID, //nolint:all + channelID string, //nolint:all ) error { return nil } @@ -101,40 +101,40 @@ func (im IBCModule) OnChanCloseConfirm( // is returned if the packet data is successfully decoded and the receive application // logic returns without error. func (im IBCModule) OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, + ctx sdk.Context, //nolint:all + packet channeltypes.Packet, //nolint:all + relayer sdk.AccAddress, //nolint:all ) ibcexported.Acknowledgement { return channeltypes.NewErrorAcknowledgement(sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "cannot receive packet via interchain accounts authentication module")) } // OnAcknowledgementPacket implements the IBCModule interface func (im IBCModule) OnAcknowledgementPacket( - ctx sdk.Context, - packet channeltypes.Packet, - acknowledgement []byte, - relayer sdk.AccAddress, + ctx sdk.Context, //nolint:all + packet channeltypes.Packet, //nolint:all + acknowledgement []byte, //nolint:all + relayer sdk.AccAddress, //nolint:all ) error { return nil } // OnTimeoutPacket implements the IBCModule interface. func (im IBCModule) OnTimeoutPacket( - ctx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, + ctx sdk.Context, //nolint:all + packet channeltypes.Packet, //nolint:all + relayer sdk.AccAddress, //nolint:all ) error { return nil } // NegotiateAppVersion implements the IBCModule interface func (im IBCModule) NegotiateAppVersion( - ctx sdk.Context, - order channeltypes.Order, - connectionID string, - portID string, - counterparty channeltypes.Counterparty, - proposedVersion string, + ctx sdk.Context, //nolint:all + order channeltypes.Order, //nolint:all + connectionID string, //nolint:all + portID string, //nolint:all + counterparty channeltypes.Counterparty, //nolint:all + proposedVersion string, //nolint:all ) (string, error) { return "", nil } diff --git a/x/mauth/module.go b/x/mauth/module.go index e5149b9e4..d511c1b8d 100644 --- a/x/mauth/module.go +++ b/x/mauth/module.go @@ -52,21 +52,21 @@ func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { } // DefaultGenesis returns the capability module's default genesis state. -func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { //nolint:all return nil } // ValidateGenesis performs genesis state validation for the capability module. -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { //nolint:all return nil } // RegisterRESTRoutes registers the capability module's REST service handlers. -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { +func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { //nolint:all } // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. -func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { //nolint:all } // GetTxCmd returns the capability module's root tx command. @@ -110,7 +110,7 @@ func (AppModule) QuerierRoute() string { } // LegacyQuerierHandler returns the capability module's Querier. -func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { +func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { //nolint:all return nil } @@ -126,12 +126,12 @@ func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} // InitGenesis performs the capability module's genesis initialization It returns // no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { //nolint:all return []abci.ValidatorUpdate{} } // ExportGenesis returns the capability module's exported genesis state as raw JSON bytes. -func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { +func (am AppModule) ExportGenesis(_ sdk.Context, _ codec.JSONCodec) json.RawMessage { return nil } diff --git a/x/mauth/types/codec.go b/x/mauth/types/codec.go index a9f157807..1e9737c07 100644 --- a/x/mauth/types/codec.go +++ b/x/mauth/types/codec.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/msgservice" ) -func RegisterCodec(cdc *codec.LegacyAmino) { +func RegisterCodec(_ *codec.LegacyAmino) { // cdc.RegisterConcrete(MsgRegister{}, "intertx/MsgRegister", nil) // cdc.RegisterConcrete(MsgSend{}, "intertx/MsgSend", nil) } diff --git a/x/mauth/types/msgs.go b/x/mauth/types/msgs.go index 1eaaa96b1..1a119f4c9 100644 --- a/x/mauth/types/msgs.go +++ b/x/mauth/types/msgs.go @@ -18,7 +18,7 @@ var ( ) // NewMsgRegisterAccount creates a new MsgRegisterAccount instance -func NewMsgRegisterAccount(owner, connectionID, counterpartyConnectionID string) *MsgRegisterAccount { +func NewMsgRegisterAccount(owner, connectionID, counterpartyConnectionID string) *MsgRegisterAccount { //nolint:all return &MsgRegisterAccount{ Owner: owner, ConnectionId: connectionID, @@ -45,8 +45,8 @@ func (msg MsgRegisterAccount) GetSigners() []sdk.AccAddress { } // NewMsgSend creates a new MsgSend instance -func NewMsgSubmitTx(owner sdk.AccAddress, sdkMsg sdk.Msg, connectionID, counterpartyConnectionID string) (*MsgSubmitTx, error) { - any, err := PackTxMsgAny(sdkMsg) +func NewMsgSubmitTx(owner sdk.AccAddress, sdkMsg sdk.Msg, connectionID, counterpartyConnectionID string) (*MsgSubmitTx, error) { //nolint:all + anyObj, err := PackTxMsgAny(sdkMsg) if err != nil { return nil, err } @@ -54,7 +54,7 @@ func NewMsgSubmitTx(owner sdk.AccAddress, sdkMsg sdk.Msg, connectionID, counterp return &MsgSubmitTx{ Owner: owner, ConnectionId: connectionID, - Msg: any, + Msg: anyObj, }, nil } @@ -65,12 +65,12 @@ func PackTxMsgAny(sdkMsg sdk.Msg) (*codectypes.Any, error) { return nil, fmt.Errorf("can't proto marshal %T", sdkMsg) } - any, err := codectypes.NewAnyWithValue(msg) + anyObj, err := codectypes.NewAnyWithValue(msg) if err != nil { return nil, err } - return any, nil + return anyObj, nil } // UnpackInterfaces implements codectypes.UnpackInterfacesMessage diff --git a/x/mauth/types/query.go b/x/mauth/types/query.go index ba5ec15ff..e6eaa2814 100644 --- a/x/mauth/types/query.go +++ b/x/mauth/types/query.go @@ -1,7 +1,7 @@ package types // NewQueryInterchainAccountRequest creates and returns a new QueryInterchainAccountFromAddressRequest -func NewQueryInterchainAccountRequest(owner, connectionID, counterpartyConnectionID string) *QueryInterchainAccountFromAddressRequest { +func NewQueryInterchainAccountRequest(owner, connectionID, counterpartyConnectionID string) *QueryInterchainAccountFromAddressRequest { //nolint:all return &QueryInterchainAccountFromAddressRequest{ Owner: owner, ConnectionId: connectionID, diff --git a/x/registration/alias.go b/x/registration/alias.go index db24a7d54..2c4b2f95e 100644 --- a/x/registration/alias.go +++ b/x/registration/alias.go @@ -66,5 +66,5 @@ type ( EnclaveApi = enclave.Api MasterKey = types.MasterKey Key = types.Key - RegistrationNodeInfo = types.RegistrationNodeInfo + RegistrationNodeInfo = types.RegistrationNodeInfo //nolint:all ) diff --git a/x/registration/client/rest/tx.go b/x/registration/client/rest/tx.go index 9a0863bdb..3919553fb 100644 --- a/x/registration/client/rest/tx.go +++ b/x/registration/client/rest/tx.go @@ -5,7 +5,7 @@ import ( "github.com/gorilla/mux" ) -func registerTxRoutes(cliCtx client.Context, r *mux.Router) { +func registerTxRoutes(cliCtx client.Context, r *mux.Router) { //nolint:all // r.HandleFunc("/wasm/code", storeCodeHandlerFn(cliCtx)).Methods("POST") // r.HandleFunc("/wasm/code/{codeId}", instantiateContractHandlerFn(cliCtx)).Methods("POST") // r.HandleFunc("/wasm/contract/{contractAddr}", executeContractHandlerFn(cliCtx)).Methods("POST") diff --git a/x/registration/internal/keeper/mock/enclave.go b/x/registration/internal/keeper/mock/enclave.go index 0f2bb976a..882aa6b6f 100644 --- a/x/registration/internal/keeper/mock/enclave.go +++ b/x/registration/internal/keeper/mock/enclave.go @@ -4,10 +4,10 @@ package mock type MockEnclaveApi struct{} //nolint:revive -func (MockEnclaveApi) LoadSeed(masterCert []byte, seed []byte, apiKey []byte) (bool, error) { +func (MockEnclaveApi) LoadSeed(masterCert []byte, seed []byte, apiKey []byte) (bool, error) { //nolint:all return true, nil } -func (MockEnclaveApi) GetEncryptedSeed(masterCert []byte) ([]byte, error) { +func (MockEnclaveApi) GetEncryptedSeed(masterCert []byte) ([]byte, error) { //nolint:all return []byte(""), nil } diff --git a/x/registration/internal/types/genesis.go b/x/registration/internal/types/genesis.go index 6877bdaa1..6c6da8d26 100644 --- a/x/registration/internal/types/genesis.go +++ b/x/registration/internal/types/genesis.go @@ -2,7 +2,7 @@ package types // ValidateGenesis performs basic validation of supply genesis data returning an // error for any failed validation criteria. -func ValidateGenesis(data GenesisState) error { +func ValidateGenesis(data GenesisState) error { //nolint:all // todo: do we want to use this, or just fail if they don't exist? // if data.IoMasterCertificate == nil { diff --git a/x/registration/internal/types/reg_keys.go b/x/registration/internal/types/reg_keys.go index 90f9c7762..bd9e883bc 100644 --- a/x/registration/internal/types/reg_keys.go +++ b/x/registration/internal/types/reg_keys.go @@ -3,7 +3,7 @@ package types func GetApiKey() ([]byte, error) { - apiKeyFile, err := Asset("api_key.txt") //nolint:all + apiKeyFile, err := Asset("api_key.txt") if err != nil { return nil, err } @@ -12,7 +12,7 @@ func GetApiKey() ([]byte, error) { } func GetSpid() ([]byte, error) { - apiKeyFile, err := Asset("spid.txt") //nolint:all + apiKeyFile, err := Asset("spid.txt") if err != nil { return nil, err } diff --git a/x/registration/internal/types/types.go b/x/registration/internal/types/types.go index 17025917d..fdb2dd6d4 100644 --- a/x/registration/internal/types/types.go +++ b/x/registration/internal/types/types.go @@ -13,16 +13,16 @@ const ( MasterNodeKeyId = "NodeExchMasterKey" MasterIoKeyId = "IoExchMasterKey" SecretNodeSeedLegacyConfig = "seed.json" - SecretNodeSeedNewConfig = "new_seed.json" + SecretNodeSeedNewConfig = "new_seed.json" //nolint:gosec SecretNodeCfgFolder = ".node" ) const ( - NodeExchMasterKeyPath = "node-master-key.txt" - IoExchMasterKeyPath = "io-master-key.txt" - LegacyIoMasterCertificate = "MIINUzCCDPqgAwIBAgIBATAKBggqhkjOPQQDAjAUMRIwEAYDVQQDDAlTZWNyZXRURUUwHhcNMjAwOTE1MTQzNjIxWhcNMjAxMjE0MTQzNjIxWjAqMSgwJgYDVQQDDB9TZWNyZXQgTmV0d29yayBOb2RlIENlcnRpZmljYXRlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAElRADUNxVdzSyHH0QdaPUB8rA6DWxtHcxhLVNl7KmClDb6nAiYPh6opfEW2TOVBe66RWhtI+CswywuK37nOY3lqOCDCUwggwhMIIMHQYJYIZIAYb4QgENBIIMDnsicmVwb3J0IjoiZXlKcFpDSTZJakU0TmpjNU1UQTROREl5TkRjek1qRTBORFl5TURBeE56QTBOek0wTnpRNU9ERTFOek0xSWl3aWRHbHRaWE4wWVcxd0lqb2lNakF5TUMwd09TMHhOVlF4TkRvek5qb3lNUzQzTXpJME56TWlMQ0oyWlhKemFXOXVJam8wTENKaFpIWnBjMjl5ZVZWU1RDSTZJbWgwZEhCek9pOHZjMlZqZFhKcGRIa3RZMlZ1ZEdWeUxtbHVkR1ZzTG1OdmJTSXNJbUZrZG1semIzSjVTVVJ6SWpwYklrbE9WRVZNTFZOQkxUQXdNek0wSWwwc0ltbHpka1Z1WTJ4aGRtVlJkVzkwWlZOMFlYUjFjeUk2SWxOWFgwaEJVa1JGVGtsT1IxOU9SVVZFUlVRaUxDSnBjM1pGYm1Oc1lYWmxVWFZ2ZEdWQ2IyUjVJam9pUVdkQlFVRk5XVXhCUVVGTVFVRnZRVUZCUVVGQlVEaDBjWE5WVGpnemFHbEdlWFpKUzJVMFVuaFliVmd6ZHpodGNrbHZVbW96YUVwb1RXNVJZazVHZEVSM09FUkNaaXRCUW1kQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQ1VVRkJRVUZCUVVGQlFVaEJRVUZCUVVGQlFVRkNjVGMzVTNoUkswdE1Sek01TXk5R09UWnlXa3hwUWpScmJFZDRiM0JJVDFBeGRqQjFjbVZCV1RsNlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUTBWWVVFNUpSbEJTVm14alkyY3JRamt3WlZVeE5GZFVSa2xVTUZGR01YVlZSR0oyYVVoRkx6Z3ZjR2RCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVSXpPVlZ6ZUdkeU9EWmhkVUZIVW1WcFdVRlFWemRhUzNvNFQyUnVkWFJyYTJ0dloxZFhTbGxYWWtkUlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCSW4wPSIsInNpZ25hdHVyZSI6InBydjJIdkhoc3RtK2tHWmpHaGh4R0QvWkZRcFhvWFJiRlIyZXlsWG54THhBS05Eb3FCSlc4WWU4RTJ5T1FMeHlYdnJsSzFtd0t5ekh6UGcxOHJvOWhlak9xYStiT3RCa1dBenNsMGNRL0xJWU5kQVhxR0xNZmFVUjBKSS9QUU9pbkRheVBDQ3A2U0F1WWc0eWJZMTM3RkVtNVFtUG5QVFQzMVEwTXE3N1daNUV2NHdvTDkvbjcwaWJoSDNsVXVFUXo5MTNVend1S0lLaExUc0pWMHBrNE5WSGdOT1lVa0tPT1hjTmZEem55NW5hRG5VMldxZ0xSOUllU29aUG1RTU5zMTdqV2dMbVAvLzVHckpqWHZMSFhSeER6WFhubUVjK04rL1BXZVBOWGdlL2FOM3RMTWNuemJlR0ZHNHM3bnlKaG9jOTdUMGNMZU1wcG9xalVvQTI1Zz09Iiwic2lnbmluZ19jZXJ0IjoiTUlJRW9UQ0NBd21nQXdJQkFnSUpBTkVIZGwweW83Q1dNQTBHQ1NxR1NJYjNEUUVCQ3dVQU1INHhDekFKQmdOVkJBWVRBbFZUTVFzd0NRWURWUVFJREFKRFFURVVNQklHQTFVRUJ3d0xVMkZ1ZEdFZ1EyeGhjbUV4R2pBWUJnTlZCQW9NRVVsdWRHVnNJRU52Y25CdmNtRjBhVzl1TVRBd0xnWURWUVFERENkSmJuUmxiQ0JUUjFnZ1FYUjBaWE4wWVhScGIyNGdVbVZ3YjNKMElGTnBaMjVwYm1jZ1EwRXdIaGNOTVRZeE1USXlNRGt6TmpVNFdoY05Nall4TVRJd01Ea3pOalU0V2pCN01Rc3dDUVlEVlFRR0V3SlZVekVMTUFrR0ExVUVDQXdDUTBFeEZEQVNCZ05WQkFjTUMxTmhiblJoSUVOc1lYSmhNUm93R0FZRFZRUUtEQkZKYm5SbGJDQkRiM0p3YjNKaGRHbHZiakV0TUNzR0ExVUVBd3drU1c1MFpXd2dVMGRZSUVGMGRHVnpkR0YwYVc5dUlGSmxjRzl5ZENCVGFXZHVhVzVuTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFxWG90NE9adXBoUjhudWRGckFGaWFHeHhrZ21hL0VzL0JBK3RiZUNUVVIxMDZBTDFFTmNXQTRGWDNLK0U5QkJMMC83WDVyajVuSWdYL1IvMXViaGtLV3c5Z2ZxUEczS2VBdElkY3YvdVRPMXlYdjUwdnFhUHZFMUNSQ2h2emRTL1pFQnFRNW9WdkxUUFozVkVpY1FqbHl0S2dOOWNMbnhid3R1dkxVSzdleVJQZkpXL2tzZGRPelA4VkJCbmlvbFluUkNEMmpyTVJaOG5CTTJaV1l3blhud1llT0FIVitXOXRPaEFJbXdSd0tGLzk1eUFzVndkMjFyeUhNSkJjR0g3MHFMYWdaN1R0eXQrK3FPLzYrS0FYSnVLd1pxalJsRXRTRXo4Z1pRZUZmVllnY3dTZm85Nm9TTUF6VnI3VjBMNkhTRExSbnBiNnh4bWJQZHFOb2w0dFFJREFRQUJvNEdrTUlHaE1COEdBMVVkSXdRWU1CYUFGSGhEZTNhbWZyelFyMzVDTitzMWZEdUhBVkU4TUE0R0ExVWREd0VCL3dRRUF3SUd3REFNQmdOVkhSTUJBZjhFQWpBQU1HQUdBMVVkSHdSWk1GY3dWYUJUb0ZHR1QyaDBkSEE2THk5MGNuVnpkR1ZrYzJWeWRtbGpaWE11YVc1MFpXd3VZMjl0TDJOdmJuUmxiblF2UTFKTUwxTkhXQzlCZEhSbGMzUmhkR2x2YmxKbGNHOXlkRk5wWjI1cGJtZERRUzVqY213d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dHQkFHY0l0aHRjSzlJVlJ6NHJScStaS0UrN2s1MC9PeFVzbVc4YWF2T3pLYjBpQ3gwN1lROXJ6aTVuVTczdE1FMnlHUkx6aFNWaUZzL0xwRmE5bHBRTDZKTDFhUXdtRFI3NFR4WUdCQUlpNWY0STVUSm9DQ0VxUkh6OTFrcEc2VXZ5bjJ0TG1uSWRKYlBFNHZZdldMcnRYWGZGQlNTUEQ0QWZuNyszL1hVZ2dBbGM3b0NUaXpPZmJidE9GbFlBNGc1S2NZZ1MxSjJaQWVNUXFiVWRac2VaQ2NhWlpabjY1dGRxZWU4VVhabER2eDArTmRPMExSKzVwRnkranVNMHdXYnU1OU12emNtVFhianNpN0hZNnpkNTNZcTVLMjQ0ZndGSFJROGVPQjBJV0IrNFBmTTdGZUFBcFp2bGZxbEtPbExjWkwydXlWbXpSa3lSNXlXNzJ1bzltZWhYNDRDaVBKMmZzZTlZNmVRdGNmRWhNUGttSFhJMDFzTitLd1BicEEzOSt4T3NTdGpoUDlOMVkxYTJ0UUFWbyt5VmdMZ1YySHdzNzNGYzBvM3dDNzhxUEVBK3YyYVJzL0JlM1pGRGdEeWdoYy8xZmdVKzdDK1A2a2JxZDRwb3liNklXOEtDSmJ4Zk1KdmtvcmROT2dPVVV4bmRQSEVpL3RiL1U3dUxqTE9nUEE9PSJ9MAoGCCqGSM49BAMCA0cAMEQCIHlYJXyIuuFdy9KCek8GhX5Jm5s50rgImpPg8pEzJ7NiAiAR5GAtTP8kyqxGEHK5/vnuLqX/2YCYhr1e6qyaSBcuAA==" - SeedPath = "seed.txt" - SeedConfigVersion = 2 + NodeExchMasterKeyPath = "node-master-key.txt" + IoExchMasterKeyPath = "io-master-key.txt" + LegacyIoMasterCertificate = "MIINUzCCDPqgAwIBAgIBATAKBggqhkjOPQQDAjAUMRIwEAYDVQQDDAlTZWNyZXRURUUwHhcNMjAwOTE1MTQzNjIxWhcNMjAxMjE0MTQzNjIxWjAqMSgwJgYDVQQDDB9TZWNyZXQgTmV0d29yayBOb2RlIENlcnRpZmljYXRlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAElRADUNxVdzSyHH0QdaPUB8rA6DWxtHcxhLVNl7KmClDb6nAiYPh6opfEW2TOVBe66RWhtI+CswywuK37nOY3lqOCDCUwggwhMIIMHQYJYIZIAYb4QgENBIIMDnsicmVwb3J0IjoiZXlKcFpDSTZJakU0TmpjNU1UQTROREl5TkRjek1qRTBORFl5TURBeE56QTBOek0wTnpRNU9ERTFOek0xSWl3aWRHbHRaWE4wWVcxd0lqb2lNakF5TUMwd09TMHhOVlF4TkRvek5qb3lNUzQzTXpJME56TWlMQ0oyWlhKemFXOXVJam8wTENKaFpIWnBjMjl5ZVZWU1RDSTZJbWgwZEhCek9pOHZjMlZqZFhKcGRIa3RZMlZ1ZEdWeUxtbHVkR1ZzTG1OdmJTSXNJbUZrZG1semIzSjVTVVJ6SWpwYklrbE9WRVZNTFZOQkxUQXdNek0wSWwwc0ltbHpka1Z1WTJ4aGRtVlJkVzkwWlZOMFlYUjFjeUk2SWxOWFgwaEJVa1JGVGtsT1IxOU9SVVZFUlVRaUxDSnBjM1pGYm1Oc1lYWmxVWFZ2ZEdWQ2IyUjVJam9pUVdkQlFVRk5XVXhCUVVGTVFVRnZRVUZCUVVGQlVEaDBjWE5WVGpnemFHbEdlWFpKUzJVMFVuaFliVmd6ZHpodGNrbHZVbW96YUVwb1RXNVJZazVHZEVSM09FUkNaaXRCUW1kQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQ1VVRkJRVUZCUVVGQlFVaEJRVUZCUVVGQlFVRkNjVGMzVTNoUkswdE1Sek01TXk5R09UWnlXa3hwUWpScmJFZDRiM0JJVDFBeGRqQjFjbVZCV1RsNlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUTBWWVVFNUpSbEJTVm14alkyY3JRamt3WlZVeE5GZFVSa2xVTUZGR01YVlZSR0oyYVVoRkx6Z3ZjR2RCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVSXpPVlZ6ZUdkeU9EWmhkVUZIVW1WcFdVRlFWemRhUzNvNFQyUnVkWFJyYTJ0dloxZFhTbGxYWWtkUlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCSW4wPSIsInNpZ25hdHVyZSI6InBydjJIdkhoc3RtK2tHWmpHaGh4R0QvWkZRcFhvWFJiRlIyZXlsWG54THhBS05Eb3FCSlc4WWU4RTJ5T1FMeHlYdnJsSzFtd0t5ekh6UGcxOHJvOWhlak9xYStiT3RCa1dBenNsMGNRL0xJWU5kQVhxR0xNZmFVUjBKSS9QUU9pbkRheVBDQ3A2U0F1WWc0eWJZMTM3RkVtNVFtUG5QVFQzMVEwTXE3N1daNUV2NHdvTDkvbjcwaWJoSDNsVXVFUXo5MTNVend1S0lLaExUc0pWMHBrNE5WSGdOT1lVa0tPT1hjTmZEem55NW5hRG5VMldxZ0xSOUllU29aUG1RTU5zMTdqV2dMbVAvLzVHckpqWHZMSFhSeER6WFhubUVjK04rL1BXZVBOWGdlL2FOM3RMTWNuemJlR0ZHNHM3bnlKaG9jOTdUMGNMZU1wcG9xalVvQTI1Zz09Iiwic2lnbmluZ19jZXJ0IjoiTUlJRW9UQ0NBd21nQXdJQkFnSUpBTkVIZGwweW83Q1dNQTBHQ1NxR1NJYjNEUUVCQ3dVQU1INHhDekFKQmdOVkJBWVRBbFZUTVFzd0NRWURWUVFJREFKRFFURVVNQklHQTFVRUJ3d0xVMkZ1ZEdFZ1EyeGhjbUV4R2pBWUJnTlZCQW9NRVVsdWRHVnNJRU52Y25CdmNtRjBhVzl1TVRBd0xnWURWUVFERENkSmJuUmxiQ0JUUjFnZ1FYUjBaWE4wWVhScGIyNGdVbVZ3YjNKMElGTnBaMjVwYm1jZ1EwRXdIaGNOTVRZeE1USXlNRGt6TmpVNFdoY05Nall4TVRJd01Ea3pOalU0V2pCN01Rc3dDUVlEVlFRR0V3SlZVekVMTUFrR0ExVUVDQXdDUTBFeEZEQVNCZ05WQkFjTUMxTmhiblJoSUVOc1lYSmhNUm93R0FZRFZRUUtEQkZKYm5SbGJDQkRiM0p3YjNKaGRHbHZiakV0TUNzR0ExVUVBd3drU1c1MFpXd2dVMGRZSUVGMGRHVnpkR0YwYVc5dUlGSmxjRzl5ZENCVGFXZHVhVzVuTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFxWG90NE9adXBoUjhudWRGckFGaWFHeHhrZ21hL0VzL0JBK3RiZUNUVVIxMDZBTDFFTmNXQTRGWDNLK0U5QkJMMC83WDVyajVuSWdYL1IvMXViaGtLV3c5Z2ZxUEczS2VBdElkY3YvdVRPMXlYdjUwdnFhUHZFMUNSQ2h2emRTL1pFQnFRNW9WdkxUUFozVkVpY1FqbHl0S2dOOWNMbnhid3R1dkxVSzdleVJQZkpXL2tzZGRPelA4VkJCbmlvbFluUkNEMmpyTVJaOG5CTTJaV1l3blhud1llT0FIVitXOXRPaEFJbXdSd0tGLzk1eUFzVndkMjFyeUhNSkJjR0g3MHFMYWdaN1R0eXQrK3FPLzYrS0FYSnVLd1pxalJsRXRTRXo4Z1pRZUZmVllnY3dTZm85Nm9TTUF6VnI3VjBMNkhTRExSbnBiNnh4bWJQZHFOb2w0dFFJREFRQUJvNEdrTUlHaE1COEdBMVVkSXdRWU1CYUFGSGhEZTNhbWZyelFyMzVDTitzMWZEdUhBVkU4TUE0R0ExVWREd0VCL3dRRUF3SUd3REFNQmdOVkhSTUJBZjhFQWpBQU1HQUdBMVVkSHdSWk1GY3dWYUJUb0ZHR1QyaDBkSEE2THk5MGNuVnpkR1ZrYzJWeWRtbGpaWE11YVc1MFpXd3VZMjl0TDJOdmJuUmxiblF2UTFKTUwxTkhXQzlCZEhSbGMzUmhkR2x2YmxKbGNHOXlkRk5wWjI1cGJtZERRUzVqY213d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dHQkFHY0l0aHRjSzlJVlJ6NHJScStaS0UrN2s1MC9PeFVzbVc4YWF2T3pLYjBpQ3gwN1lROXJ6aTVuVTczdE1FMnlHUkx6aFNWaUZzL0xwRmE5bHBRTDZKTDFhUXdtRFI3NFR4WUdCQUlpNWY0STVUSm9DQ0VxUkh6OTFrcEc2VXZ5bjJ0TG1uSWRKYlBFNHZZdldMcnRYWGZGQlNTUEQ0QWZuNyszL1hVZ2dBbGM3b0NUaXpPZmJidE9GbFlBNGc1S2NZZ1MxSjJaQWVNUXFiVWRac2VaQ2NhWlpabjY1dGRxZWU4VVhabER2eDArTmRPMExSKzVwRnkranVNMHdXYnU1OU12emNtVFhianNpN0hZNnpkNTNZcTVLMjQ0ZndGSFJROGVPQjBJV0IrNFBmTTdGZUFBcFp2bGZxbEtPbExjWkwydXlWbXpSa3lSNXlXNzJ1bzltZWhYNDRDaVBKMmZzZTlZNmVRdGNmRWhNUGttSFhJMDFzTitLd1BicEEzOSt4T3NTdGpoUDlOMVkxYTJ0UUFWbyt5VmdMZ1YySHdzNzNGYzBvM3dDNzhxUEVBK3YyYVJzL0JlM1pGRGdEeWdoYy8xZmdVKzdDK1A2a2JxZDRwb3liNklXOEtDSmJ4Zk1KdmtvcmROT2dPVVV4bmRQSEVpL3RiL1U3dUxqTE9nUEE9PSJ9MAoGCCqGSM49BAMCA0cAMEQCIHlYJXyIuuFdy9KCek8GhX5Jm5s50rgImpPg8pEzJ7NiAiAR5GAtTP8kyqxGEHK5/vnuLqX/2YCYhr1e6qyaSBcuAA==" + SeedPath = "seed.txt" + SeedConfigVersion = 2 ) const AttestationCertPath = "attestation_cert.der" diff --git a/x/registration/module.go b/x/registration/module.go index 094258000..eb64e06ea 100644 --- a/x/registration/module.go +++ b/x/registration/module.go @@ -58,7 +58,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { } // ValidateGenesis performs genesis state validation for the compute module. -func (AppModuleBasic) ValidateGenesis(marshaler codec.JSONCodec, config client.TxEncodingConfig, message json.RawMessage) error { +func (AppModuleBasic) ValidateGenesis(marshaler codec.JSONCodec, config client.TxEncodingConfig, message json.RawMessage) error { //nolint:all var data GenesisState err := marshaler.UnmarshalJSON(message, &data) if err != nil { @@ -107,12 +107,12 @@ func (am AppModule) RegisterServices(configurator module.Configurator) { types.RegisterQueryServer(configurator.QueryServer(), NewQuerier(am.keeper)) } -func (am AppModule) LegacyQuerierHandler(amino *codec.LegacyAmino) sdk.Querier { +func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { return keeper.NewLegacyQuerier(am.keeper) } // RegisterInvariants registers the compute module invariants. -func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} // Route returns the message routing key for the compute module. func (am AppModule) Route() sdk.Route { @@ -154,24 +154,24 @@ func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.Validato // AppModuleSimulation functions // GenerateGenesisState creates a randomized GenState of the bank module. -func (AppModule) GenerateGenesisState(simState *module.SimulationState) { +func (AppModule) GenerateGenesisState(_ *module.SimulationState) { } // ProposalContents doesn't return any content functions for governance proposals. -func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent { +func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { return nil } // RandomizedParams creates randomized bank param changes for the simulator. -func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { +func (AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { return nil } // RegisterStoreDecoder registers a decoder for supply module's types -func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { +func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { } // WeightedOperations returns the all the gov module operations with their respective weights. -func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { +func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { //nolint:all return nil } diff --git a/x/registration/remote_attestation/remote_attestation.go b/x/registration/remote_attestation/remote_attestation.go index 3a8b9120d..786bfc2c0 100644 --- a/x/registration/remote_attestation/remote_attestation.go +++ b/x/registration/remote_attestation/remote_attestation.go @@ -195,7 +195,7 @@ func verifyAttReport(attnReportRaw []byte, pubK []byte) ([]byte, error) { } // 1. Check timestamp is within 24H - if qr.Timestamp != "" { + if qr.Timestamp != "" { //nolint:all // timeFixed := qr.Timestamp + "+0000" // timeFixed := qr.Timestamp + "Z" // ts, _ := time.Parse(time.RFC3339, timeFixed) From a6b09d3a1a2b4f865fad51de0089014488371277 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 May 2023 00:53:24 +0300 Subject: [PATCH 21/54] Fix CI linting issue? --- x/registration/internal/keeper/mock/enclave.go | 4 ++-- x/registration/internal/types/reg_keys.go | 4 ++-- x/registration/remote_attestation/remote_attestation.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x/registration/internal/keeper/mock/enclave.go b/x/registration/internal/keeper/mock/enclave.go index 882aa6b6f..0f2bb976a 100644 --- a/x/registration/internal/keeper/mock/enclave.go +++ b/x/registration/internal/keeper/mock/enclave.go @@ -4,10 +4,10 @@ package mock type MockEnclaveApi struct{} //nolint:revive -func (MockEnclaveApi) LoadSeed(masterCert []byte, seed []byte, apiKey []byte) (bool, error) { //nolint:all +func (MockEnclaveApi) LoadSeed(masterCert []byte, seed []byte, apiKey []byte) (bool, error) { return true, nil } -func (MockEnclaveApi) GetEncryptedSeed(masterCert []byte) ([]byte, error) { //nolint:all +func (MockEnclaveApi) GetEncryptedSeed(masterCert []byte) ([]byte, error) { return []byte(""), nil } diff --git a/x/registration/internal/types/reg_keys.go b/x/registration/internal/types/reg_keys.go index bd9e883bc..90f9c7762 100644 --- a/x/registration/internal/types/reg_keys.go +++ b/x/registration/internal/types/reg_keys.go @@ -3,7 +3,7 @@ package types func GetApiKey() ([]byte, error) { - apiKeyFile, err := Asset("api_key.txt") + apiKeyFile, err := Asset("api_key.txt") //nolint:all if err != nil { return nil, err } @@ -12,7 +12,7 @@ func GetApiKey() ([]byte, error) { } func GetSpid() ([]byte, error) { - apiKeyFile, err := Asset("spid.txt") + apiKeyFile, err := Asset("spid.txt") //nolint:all if err != nil { return nil, err } diff --git a/x/registration/remote_attestation/remote_attestation.go b/x/registration/remote_attestation/remote_attestation.go index 786bfc2c0..3a8b9120d 100644 --- a/x/registration/remote_attestation/remote_attestation.go +++ b/x/registration/remote_attestation/remote_attestation.go @@ -195,7 +195,7 @@ func verifyAttReport(attnReportRaw []byte, pubK []byte) ([]byte, error) { } // 1. Check timestamp is within 24H - if qr.Timestamp != "" { //nolint:all + if qr.Timestamp != "" { // timeFixed := qr.Timestamp + "+0000" // timeFixed := qr.Timestamp + "Z" // ts, _ := time.Parse(time.RFC3339, timeFixed) From 1ad45dddd61e9d0b2558dab8ac3588103b106c70 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 May 2023 00:56:59 +0300 Subject: [PATCH 22/54] Fix CI linting issue? --- app/modules.go | 2 +- x/mauth/ibc_module.go | 82 +++++++++++++++++++++--------------------- x/mauth/module.go | 12 +++---- x/mauth/types/msgs.go | 4 +-- x/mauth/types/query.go | 2 +- 5 files changed, 51 insertions(+), 51 deletions(-) diff --git a/app/modules.go b/app/modules.go index 30fa79c6d..14ebc10b4 100644 --- a/app/modules.go +++ b/app/modules.go @@ -48,7 +48,7 @@ var ModuleAccountPermissions = map[string][]string{ compute.ModuleName: {authtypes.Burner}, } -func AppModules( //nolint:all +func AppModules( app *SecretNetworkApp, encodingConfig EncodingConfig, skipGenesisInvariants bool, diff --git a/x/mauth/ibc_module.go b/x/mauth/ibc_module.go index 084f7d188..3312ff2b4 100644 --- a/x/mauth/ibc_module.go +++ b/x/mauth/ibc_module.go @@ -29,12 +29,12 @@ func NewIBCModule(k keeper.Keeper) IBCModule { // OnChanOpenInit implements the IBCModule interface func (im IBCModule) OnChanOpenInit( ctx sdk.Context, - order channeltypes.Order, //nolint:all - connectionHops []string, //nolint:all + order channeltypes.Order, + connectionHops []string, portID string, channelID string, chanCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, //nolint:all + counterparty channeltypes.Counterparty, version string, ) (string, error) { err := im.keeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)) @@ -47,52 +47,52 @@ func (im IBCModule) OnChanOpenInit( // OnChanOpenTry implements the IBCModule interface func (im IBCModule) OnChanOpenTry( - ctx sdk.Context, //nolint:all - order channeltypes.Order, //nolint:all - connectionHops []string, //nolint:all - portID, //nolint:all - channelID string, //nolint:all - chanCap *capabilitytypes.Capability, //nolint:all - counterparty channeltypes.Counterparty, //nolint:all - counterpartyVersion string, //nolint:all + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, + channelID string, + chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + counterpartyVersion string, ) (version string, err error) { return "", nil } // OnChanOpenAck implements the IBCModule interface func (im IBCModule) OnChanOpenAck( - ctx sdk.Context, //nolint:all - portID, //nolint:all - channelID string, //nolint:all - counterpartychannelID string, //nolint:all - counterpartyVersion string, //nolint:all + ctx sdk.Context, + portID, + channelID string, + counterpartychannelID string, + counterpartyVersion string, ) error { return nil } // OnChanOpenConfirm implements the IBCModule interface func (im IBCModule) OnChanOpenConfirm( - ctx sdk.Context, //nolint:all - portID, //nolint:all - channelID string, //nolint:all + ctx sdk.Context, + portID, + channelID string, ) error { return nil } // OnChanCloseInit implements the IBCModule interface func (im IBCModule) OnChanCloseInit( - ctx sdk.Context, //nolint:all - portID, //nolint:all - channelID string, //nolint:all + ctx sdk.Context, + portID, + channelID string, ) error { return nil } // OnChanCloseConfirm implements the IBCModule interface func (im IBCModule) OnChanCloseConfirm( - ctx sdk.Context, //nolint:all - portID, //nolint:all - channelID string, //nolint:all + ctx sdk.Context, + portID, + channelID string, ) error { return nil } @@ -101,40 +101,40 @@ func (im IBCModule) OnChanCloseConfirm( // is returned if the packet data is successfully decoded and the receive application // logic returns without error. func (im IBCModule) OnRecvPacket( - ctx sdk.Context, //nolint:all - packet channeltypes.Packet, //nolint:all - relayer sdk.AccAddress, //nolint:all + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, ) ibcexported.Acknowledgement { return channeltypes.NewErrorAcknowledgement(sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "cannot receive packet via interchain accounts authentication module")) } // OnAcknowledgementPacket implements the IBCModule interface func (im IBCModule) OnAcknowledgementPacket( - ctx sdk.Context, //nolint:all - packet channeltypes.Packet, //nolint:all - acknowledgement []byte, //nolint:all - relayer sdk.AccAddress, //nolint:all + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, ) error { return nil } // OnTimeoutPacket implements the IBCModule interface. func (im IBCModule) OnTimeoutPacket( - ctx sdk.Context, //nolint:all - packet channeltypes.Packet, //nolint:all - relayer sdk.AccAddress, //nolint:all + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, ) error { return nil } // NegotiateAppVersion implements the IBCModule interface func (im IBCModule) NegotiateAppVersion( - ctx sdk.Context, //nolint:all - order channeltypes.Order, //nolint:all - connectionID string, //nolint:all - portID string, //nolint:all - counterparty channeltypes.Counterparty, //nolint:all - proposedVersion string, //nolint:all + ctx sdk.Context, + order channeltypes.Order, + connectionID string, + portID string, + counterparty channeltypes.Counterparty, + proposedVersion string, ) (string, error) { return "", nil } diff --git a/x/mauth/module.go b/x/mauth/module.go index d511c1b8d..49c45ce82 100644 --- a/x/mauth/module.go +++ b/x/mauth/module.go @@ -52,21 +52,21 @@ func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { } // DefaultGenesis returns the capability module's default genesis state. -func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { //nolint:all +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { return nil } // ValidateGenesis performs genesis state validation for the capability module. -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { //nolint:all +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { return nil } // RegisterRESTRoutes registers the capability module's REST service handlers. -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { //nolint:all +func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { } // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. -func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { //nolint:all +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { } // GetTxCmd returns the capability module's root tx command. @@ -110,7 +110,7 @@ func (AppModule) QuerierRoute() string { } // LegacyQuerierHandler returns the capability module's Querier. -func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { //nolint:all +func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { return nil } @@ -126,7 +126,7 @@ func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} // InitGenesis performs the capability module's genesis initialization It returns // no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { //nolint:all +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } diff --git a/x/mauth/types/msgs.go b/x/mauth/types/msgs.go index 1a119f4c9..5a6b56804 100644 --- a/x/mauth/types/msgs.go +++ b/x/mauth/types/msgs.go @@ -18,7 +18,7 @@ var ( ) // NewMsgRegisterAccount creates a new MsgRegisterAccount instance -func NewMsgRegisterAccount(owner, connectionID, counterpartyConnectionID string) *MsgRegisterAccount { //nolint:all +func NewMsgRegisterAccount(owner, connectionID, counterpartyConnectionID string) *MsgRegisterAccount { return &MsgRegisterAccount{ Owner: owner, ConnectionId: connectionID, @@ -45,7 +45,7 @@ func (msg MsgRegisterAccount) GetSigners() []sdk.AccAddress { } // NewMsgSend creates a new MsgSend instance -func NewMsgSubmitTx(owner sdk.AccAddress, sdkMsg sdk.Msg, connectionID, counterpartyConnectionID string) (*MsgSubmitTx, error) { //nolint:all +func NewMsgSubmitTx(owner sdk.AccAddress, sdkMsg sdk.Msg, connectionID, counterpartyConnectionID string) (*MsgSubmitTx, error) { anyObj, err := PackTxMsgAny(sdkMsg) if err != nil { return nil, err diff --git a/x/mauth/types/query.go b/x/mauth/types/query.go index e6eaa2814..ba5ec15ff 100644 --- a/x/mauth/types/query.go +++ b/x/mauth/types/query.go @@ -1,7 +1,7 @@ package types // NewQueryInterchainAccountRequest creates and returns a new QueryInterchainAccountFromAddressRequest -func NewQueryInterchainAccountRequest(owner, connectionID, counterpartyConnectionID string) *QueryInterchainAccountFromAddressRequest { //nolint:all +func NewQueryInterchainAccountRequest(owner, connectionID, counterpartyConnectionID string) *QueryInterchainAccountFromAddressRequest { return &QueryInterchainAccountFromAddressRequest{ Owner: owner, ConnectionId: connectionID, From 86a0cb9cb5acff84d6fc95467f0987db7cbfa565 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 May 2023 01:00:21 +0300 Subject: [PATCH 23/54] Fix CI linting issue? --- app/upgrades/v1.5/upgrade.go | 2 +- app/upgrades/v1.6/upgrade.go | 2 +- go-cosmwasm/api/callbacks.go | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/upgrades/v1.5/upgrade.go b/app/upgrades/v1.5/upgrade.go index 76b08cdcb..2781f2c72 100644 --- a/app/upgrades/v1.5/upgrade.go +++ b/app/upgrades/v1.5/upgrade.go @@ -17,7 +17,7 @@ var Upgrade = upgrades.Upgrade{ StoreUpgrades: store.StoreUpgrades{}, } -func createUpgradeHandler(mm *module.Manager, keepers *keepers.SecretAppKeepers, configurator module.Configurator, //nolint:all +func createUpgradeHandler(mm *module.Manager, _ *keepers.SecretAppKeepers, configurator module.Configurator, ) upgradetypes.UpgradeHandler { return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { ctx.Logger().Info(` _ _ _____ _____ _____ _____ ______ `) diff --git a/app/upgrades/v1.6/upgrade.go b/app/upgrades/v1.6/upgrade.go index 514b2f290..66c7cf072 100644 --- a/app/upgrades/v1.6/upgrade.go +++ b/app/upgrades/v1.6/upgrade.go @@ -17,7 +17,7 @@ var Upgrade = upgrades.Upgrade{ StoreUpgrades: store.StoreUpgrades{}, } -func createUpgradeHandler(mm *module.Manager, keepers *keepers.SecretAppKeepers, configurator module.Configurator, //nolint:all +func createUpgradeHandler(mm *module.Manager, _ *keepers.SecretAppKeepers, configurator module.Configurator, ) upgradetypes.UpgradeHandler { return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { ctx.Logger().Info(` _ _ _____ _____ _____ _____ ______ `) diff --git a/go-cosmwasm/api/callbacks.go b/go-cosmwasm/api/callbacks.go index 15ccba9ef..4ce92d011 100644 --- a/go-cosmwasm/api/callbacks.go +++ b/go-cosmwasm/api/callbacks.go @@ -158,7 +158,7 @@ func buildIterator(dbCounter uint64, it dbm.Iterator) C.iterator_t { } //export cGet -func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, key C.Buffer, val *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { //nolint:all +func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, key C.Buffer, val *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil || val == nil { // we received an invalid pointer @@ -187,7 +187,7 @@ func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, key C.Buffer, val } //export cSet -func cSet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key C.Buffer, val C.Buffer, errOut *C.Buffer) (ret C.GoResult) { //nolint:all +func cSet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key C.Buffer, val C.Buffer, errOut *C.Buffer) (ret C.GoResult) { defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil { // we received an invalid pointer @@ -208,7 +208,7 @@ func cSet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key C.Buffe } //export cDelete -func cDelete(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key C.Buffer, errOut *C.Buffer) (ret C.GoResult) { //nolint:all +func cDelete(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key C.Buffer, errOut *C.Buffer) (ret C.GoResult) { defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil { // we received an invalid pointer @@ -228,7 +228,7 @@ func cDelete(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key C.Bu } //export cScan -func cScan(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, start C.Buffer, end C.Buffer, order i32, out *C.GoIter, errOut *C.Buffer) (ret C.GoResult) { //nolint:all +func cScan(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, start C.Buffer, end C.Buffer, order i32, out *C.GoIter, errOut *C.Buffer) (ret C.GoResult) { defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil || out == nil { // we received an invalid pointer @@ -266,7 +266,7 @@ func cScan(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, start C.Bu } //export cNext -func cNext(ref C.iterator_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key *C.Buffer, val *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { //nolint:all +func cNext(ref C.iterator_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key *C.Buffer, val *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { // typical usage of iterator // for ; itr.Valid(); itr.Next() { // k, v := itr.Key(); itr.Value() From 2eb58f766df9a981c76b0330ac6c2b5e743c537b Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 May 2023 01:05:31 +0300 Subject: [PATCH 24/54] Fix CI linting issue? --- x/ibc-hooks/client/cli/query.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/ibc-hooks/client/cli/query.go b/x/ibc-hooks/client/cli/query.go index 4d3a9503e..d5fc520d0 100644 --- a/x/ibc-hooks/client/cli/query.go +++ b/x/ibc-hooks/client/cli/query.go @@ -13,7 +13,7 @@ import ( "github.com/scrtlabs/SecretNetwork/x/ibc-hooks/types" ) -func indexRunCmd(cmd *cobra.Command, args []string) error { //nolint:all +func indexRunCmd(cmd *cobra.Command, _ []string) error { usageTemplate := `Usage:{{if .HasAvailableSubCommands}} {{.CommandPath}} [command]{{end}} From f7658676a6950b12809471ea26ff18cf0bf6e822 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 May 2023 08:09:58 +0300 Subject: [PATCH 25/54] CI: Point to the right secretjs branch --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ef7f7a6a0..bedfeffc5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -341,7 +341,7 @@ jobs: make kill-localsecret # next step needs the localsecret ports - name: Run secret.js tests run: | - git clone --depth 1 --branch ibc-go-v4 https://github.com/scrtlabs/secret.js + git clone --depth 1 --branch ibc-hooks https://github.com/scrtlabs/secret.js cd secret.js # Use the docker images that we built just a few steps above perl -i -pe 's/localsecret:.+?"/localsecret:v0.0.0"/' ./test/docker-compose.yml From 538ed0fc4c9e9289f05cdc1f59360d0d645cc410 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 May 2023 13:33:19 +0300 Subject: [PATCH 26/54] Fix SGX apt repo pubkey error --- deployment/dockerfiles/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deployment/dockerfiles/Dockerfile b/deployment/dockerfiles/Dockerfile index a67f89794..1d9900255 100644 --- a/deployment/dockerfiles/Dockerfile +++ b/deployment/dockerfiles/Dockerfile @@ -157,7 +157,8 @@ RUN . /opt/sgxsdk/environment && env && VERSION=${VERSION} FEATURES=${FEATURES} FROM $SCRT_RELEASE_BASE_IMAGE as release-image # wasmi-sgx-test script requirements -RUN apt-get update && \ +RUN add-apt-repository -r "deb https://download.01.org/intel-sgx/sgx_repo/ubuntu focal main" && \ + apt-get update && \ apt-get install -y --no-install-recommends \ #### Base utilities #### jq \ From ff00508a14b781751e6b3842145f1eb627d8a405 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 May 2023 13:53:51 +0300 Subject: [PATCH 27/54] revert clippy weird unused var suggestion --- .../enclaves/shared/contract-engine/src/contract_validation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 329fd2ccc..8b1c24a4d 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -362,7 +362,7 @@ pub fn verify_params( sender: &CanonicalAddr, contract_address: &HumanAddr, msg: &SecretMessage, - _og_msg: &[u8], + og_msg: &[u8], should_validate_sig_info: bool, should_validate_input: bool, handle_type: HandleType, From f43f3a3a37c04436d3b7c6cb32e945bbc7afc07e Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 24 May 2023 13:57:52 +0300 Subject: [PATCH 28/54] revert clippy weird unused var suggestion --- .../enclaves/shared/contract-engine/src/contract_operations.rs | 2 ++ .../enclaves/shared/contract-engine/src/contract_validation.rs | 1 + 2 files changed, 3 insertions(+) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 94687ee9d..1d58d86ab 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -111,6 +111,7 @@ pub fn init( &canonical_sender_address, contract_address, &secret_msg, + #[cfg(feature = "light-client-validation")] msg, true, true, @@ -290,6 +291,7 @@ pub fn handle( &canonical_sender_address, contract_address, &secret_msg, + #[cfg(feature = "light-client-validation")] msg, should_validate_sig_info, should_validate_input, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 8b1c24a4d..23db61b55 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -362,6 +362,7 @@ pub fn verify_params( sender: &CanonicalAddr, contract_address: &HumanAddr, msg: &SecretMessage, + #[cfg(feature = "light-client-validation")] og_msg: &[u8], should_validate_sig_info: bool, should_validate_input: bool, From 6870c71332306fb08fa895a3721b469b92636a68 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Fri, 26 May 2023 01:06:21 +0300 Subject: [PATCH 29/54] Docker magic? --- deployment/dockerfiles/Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deployment/dockerfiles/Dockerfile b/deployment/dockerfiles/Dockerfile index 1d9900255..a91285976 100644 --- a/deployment/dockerfiles/Dockerfile +++ b/deployment/dockerfiles/Dockerfile @@ -82,6 +82,9 @@ RUN git clone --branch main https://github.com/scrtlabs/tm-secret-enclave.git WORKDIR tm-secret-enclave +RUN git fetch +RUN git checkout tags/v1.9.2 + RUN git submodule init RUN git submodule update --remote From 2bdf20f8bf693cb4d6f29a0b4f7863b4a2b1672d Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Fri, 26 May 2023 01:06:25 +0300 Subject: [PATCH 30/54] IBC hooks outgoing transfer ack validation :tada: --- .../test-compute-contract/src/contract.rs | 31 +- .../test-compute-contract/src/msg.rs | 26 +- .../src/contract_validation.rs | 216 +++++++++++--- .../shared/contract-engine/src/ibc_message.rs | 4 +- .../shared/contract-engine/src/message.rs | 12 +- .../enclaves/shared/cosmos-types/src/types.rs | 276 +++++++++++++----- .../keeper/secret_contracts_exec_test.go | 55 ++++ 7 files changed, 503 insertions(+), 117 deletions(-) diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract/src/contract.rs b/cosmwasm/contracts/v1/compute-tests/test-compute-contract/src/contract.rs index 0a9527b17..91b791e8c 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract/src/contract.rs +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract/src/contract.rs @@ -10,7 +10,9 @@ use cosmwasm_std::{ use cosmwasm_storage::PrefixedStorage; use secp256k1::Secp256k1; -use crate::msg::{ExecuteMsg, ExternalMessages, InstantiateMsg, QueryMsg, QueryRes}; +use crate::msg::{ + ExecuteMsg, ExternalMessages, IBCLifecycleComplete, InstantiateMsg, QueryMsg, QueryRes, +}; use crate::state::{count, count_read, expiration, expiration_read}; #[entry_point] @@ -1293,6 +1295,33 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S }) .set_data(details[0].data.as_bytes())) } + ExecuteMsg::IBCLifecycleComplete(IBCLifecycleComplete::IBCAck { + channel, + sequence, + ack, + success, + }) => Ok(Response::default().add_attributes(vec![ + ("ibc_lifecycle_complete.ibc_ack.channel", channel), + ( + "ibc_lifecycle_complete.ibc_ack.sequence", + sequence.to_string(), + ), + ("ibc_lifecycle_complete.ibc_ack.ack", ack), + ( + "ibc_lifecycle_complete.ibc_ack.success", + success.to_string(), + ), + ])), + ExecuteMsg::IBCLifecycleComplete(IBCLifecycleComplete::IBCTimeout { + channel, + sequence, + }) => Ok(Response::default().add_attributes(vec![ + ("ibc_lifecycle_complete.ibc_timeout.channel", channel), + ( + "ibc_lifecycle_complete.ibc_timeout.sequence", + sequence.to_string(), + ), + ])), } } diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract/src/msg.rs b/cosmwasm/contracts/v1/compute-tests/test-compute-contract/src/msg.rs index 41ffb1647..2e2a9e33c 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract/src/msg.rs +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract/src/msg.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{Binary, Coin}; +use cosmwasm_std::{Binary, Coin, Uint64}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -421,6 +421,30 @@ pub enum ExecuteMsg { ExecuteMultipleContracts { details: Vec, }, + #[serde(rename = "ibc_lifecycle_complete")] + IBCLifecycleComplete(IBCLifecycleComplete), +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub enum IBCLifecycleComplete { + #[serde(rename = "ibc_ack")] + IBCAck { + /// The source channel (secret side) of the IBC packet + channel: String, + /// The sequence number that the packet was sent with + sequence: u64, + /// String encoded version of the ack as seen by OnAcknowledgementPacket(..) + ack: String, + /// Weather an ack is a success of failure according to the transfer spec + success: bool, + }, + #[serde(rename = "ibc_timeout")] + IBCTimeout { + /// The source channel (secret side) of the IBC packet + channel: String, + /// The sequence number that the packet was sent with + sequence: u64, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 23db61b55..91dc3cbf7 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -8,8 +8,8 @@ use cw_types_generic::BaseEnv; use cw_types_v010::types::{CanonicalAddr, Coin, HumanAddr}; use enclave_cosmos_types::traits::CosmosAminoPubkey; use enclave_cosmos_types::types::{ - ContractCode, CosmosMsg, CosmosPubKey, FungibleTokenPacketData, HandleType, - SigInfo, SignDoc, StdSignDoc, IbcHooksIncomingTransferMsg, + ContractCode, CosmosSdkMsg, CosmosPubKey, FungibleTokenPacketData, HandleType, + SigInfo, SignDoc, StdSignDoc, IbcHooksIncomingTransferMsg, Packet, IbcHooksOutgoingTransferMemo, IBCLifecycleComplete, is_transfer_ack_error, IBCPacketAckMsg, IBCLifecycleCompleteOptions, }; use enclave_crypto::traits::VerifyingKey; use enclave_crypto::{sha_256, AESKey, Hmac, Kdf, HASH_SIZE, KEY_MANAGER}; @@ -393,7 +393,7 @@ pub fn verify_params( ); //let start = Instant::now(); - let sender_public_key = get_signer(sig_info, sender)?; + let sender_public_key = get_signer(sig_info, sender, handle_type)?; // let duration = start.elapsed(); // trace!( // "verify_params: Time elapsed in get_signer_and_messages: {:?}", @@ -437,7 +437,7 @@ pub fn verify_params( } if should_validate_input { - let messages = get_messages(sig_info)?; + let messages = get_messages(sig_info, handle_type)?; // let start = Instant::now(); let is_verified = verify_message_params( @@ -464,11 +464,11 @@ pub fn verify_params( Ok(()) } -fn get_signer(sign_info: &SigInfo, sender: &CanonicalAddr) -> Result { +fn get_signer(sign_info: &SigInfo, sender: &CanonicalAddr, handle_type: HandleType) -> Result { use cosmos_proto::tx::signing::SignMode::*; match sign_info.sign_mode { SIGN_MODE_DIRECT => { - let sign_doc = SignDoc::from_bytes(sign_info.sign_bytes.as_slice())?; + let sign_doc = SignDoc::from_bytes(sign_info.sign_bytes.as_slice(), handle_type)?; trace!("sign doc: {:?}", sign_doc); // This verifies that signatures and sign bytes are self consistent @@ -525,11 +525,11 @@ fn get_signer(sign_info: &SigInfo, sender: &CanonicalAddr) -> Result Result, EnclaveError> { +fn get_messages(sign_info: &SigInfo, handle_type: HandleType) -> Result, EnclaveError> { use cosmos_proto::tx::signing::SignMode::*; match sign_info.sign_mode { SIGN_MODE_DIRECT => { - let sign_doc = SignDoc::from_bytes(sign_info.sign_bytes.as_slice())?; + let sign_doc = SignDoc::from_bytes(sign_info.sign_bytes.as_slice(), handle_type)?; trace!("sign doc: {:?}", sign_doc); Ok(sign_doc.body.messages) @@ -540,7 +540,7 @@ fn get_messages(sign_info: &SigInfo) -> Result, EnclaveError> { warn!("failure to parse StdSignDoc: {:?}", err); EnclaveError::FailedTxVerification })?; - let messages: Result, _> = sign_doc + let messages: Result, _> = sign_doc .msgs .iter() .map(|x| x.clone().into_cosmwasm_msg()) @@ -576,7 +576,7 @@ fn get_messages(sign_info: &SigInfo) -> Result, EnclaveError> { ); EnclaveError::FailedTxVerification })?; - let messages: Result, _> = sign_doc + let messages: Result, _> = sign_doc .msgs .iter() .map(|x| x.clone().into_cosmwasm_msg()) @@ -638,27 +638,29 @@ fn verify_callback_sig_impl( /// Get the cosmwasm message that contains the encrypted message fn get_verified_msg<'sd>( - messages: &'sd [CosmosMsg], + messages: &'sd [CosmosSdkMsg], msg_sender: &CanonicalAddr, sent_msg: &SecretMessage, handle_type: HandleType, -) -> Option<&'sd CosmosMsg> { +) -> Option<&'sd CosmosSdkMsg> { trace!("get_verified_msg: {:?}", messages); messages.iter().find(|&m| match m { - CosmosMsg::Execute { msg, sender, .. } - | CosmosMsg::Instantiate { + CosmosSdkMsg::MsgExecuteContract { msg, sender, .. } + | CosmosSdkMsg::MsgInstantiateContract { init_msg: msg, sender, .. } => msg_sender == sender && &sent_msg.to_vec() == msg, - CosmosMsg::MsgRecvPacket { + CosmosSdkMsg::MsgRecvPacket { + packet: Packet { sequence, source_port, source_channel, destination_port, destination_channel, data, + }, .. } => match handle_type { HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { let parsed_sent_msg = serde_json::from_slice::(&sent_msg.msg); @@ -694,25 +696,70 @@ fn get_verified_msg<'sd>( } let ibc_hooks_incoming_transfer_msg = ibc_hooks_incoming_transfer_msg.unwrap(); - let send_msg_value = serde_json::from_slice::(&sent_msg.msg); - if send_msg_value.is_err(){ - trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: sent_msg.msg cannot be parsed as serde_json::Value: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), send_msg_value.err()); + let sent_msg_value = serde_json::from_slice::(&sent_msg.msg); + if sent_msg_value.is_err(){ + trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: sent_msg.msg cannot be parsed as serde_json::Value: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), sent_msg_value.err()); return false; } - ibc_hooks_incoming_transfer_msg.wasm.msg == send_msg_value.unwrap() + ibc_hooks_incoming_transfer_msg.wasm.msg == sent_msg_value.unwrap() } _ => false, }, - CosmosMsg::Other => false, + CosmosSdkMsg::Other => false, + CosmosSdkMsg::MsgAcknowledgement { packet, acknowledgement, signer,.. } => { + match handle_type { + HandleType::HANDLE_TYPE_IBC_PACKET_ACK => { + let ibc_packet_ack_msg = serde_json::from_slice::(&sent_msg.msg); + if ibc_packet_ack_msg.is_err(){ + trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_ACK: sent_msg.msg cannot be parsed as IBCPacketAckMsg: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), ibc_packet_ack_msg.err()); + return false; + } + let ibc_packet_ack_msg= ibc_packet_ack_msg.unwrap(); + + ibc_packet_ack_msg.original_packet.src.channel_id == packet.source_channel && + ibc_packet_ack_msg.original_packet.src.port_id == packet.source_port && + ibc_packet_ack_msg.original_packet.dest.channel_id == packet.destination_channel && + ibc_packet_ack_msg.original_packet.dest.port_id == packet.destination_port && + ibc_packet_ack_msg.original_packet.sequence == packet.sequence && + ibc_packet_ack_msg.original_packet.data == packet.data && + ibc_packet_ack_msg.relayer == *signer && + ibc_packet_ack_msg.acknowledgement.data == *acknowledgement + }, + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK => { + trace!("ASSAF 1"); + let ibc_lifecycle_complete = serde_json::from_slice::(&sent_msg.msg); + if ibc_lifecycle_complete.is_err(){ + trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK: sent_msg.msg cannot be parsed as IBCLifecycleComplete: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), ibc_lifecycle_complete.err()); + return false; + } + let ibc_lifecycle_complete= ibc_lifecycle_complete.unwrap(); + + trace!("ASSAF 2 {:?}", ibc_lifecycle_complete); + + + match ibc_lifecycle_complete { + IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCAck { channel, sequence, ack, success }) => + channel == packet.source_channel + && sequence == packet.sequence + && ack == String::from_utf8_lossy( acknowledgement) + && success == !is_transfer_ack_error(acknowledgement) + , + IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCTimeout { .. }) => false, + } + }, + _ => false, + + } + }, }) } /// Check that the contract listed in the cosmwasm message matches the one in env -fn verify_contract(msg: &CosmosMsg, contract_address: &HumanAddr) -> bool { +fn verify_contract(msg: &CosmosSdkMsg, contract_address: &HumanAddr) -> bool { // Contract address is relevant only to execute, since during sending an instantiate message the contract address is not yet known match msg { - CosmosMsg::Execute { contract, .. } => { + CosmosSdkMsg::MsgExecuteContract { contract, .. } => { info!("Verifying contract address.."); let is_verified = contract_address == contract; if !is_verified { @@ -724,11 +771,11 @@ fn verify_contract(msg: &CosmosMsg, contract_address: &HumanAddr) -> bool { } is_verified } - CosmosMsg::Instantiate { .. } => true, - CosmosMsg::Other => false, - CosmosMsg::MsgRecvPacket { - destination_port, - data, + CosmosSdkMsg::MsgInstantiateContract { .. } => true, + CosmosSdkMsg::Other => false, + CosmosSdkMsg::MsgRecvPacket { + packet:Packet{ destination_port, + data,..}, .. } => { if destination_port == "transfer" { @@ -793,7 +840,7 @@ fn verify_contract(msg: &CosmosMsg, contract_address: &HumanAddr) -> bool { Some(contract_address) => contract_address, None => { trace!( - "Contract was called via MsgRecvPacket but destination_port doesn't start with \"wasm.\": {:?}", + "IBC-enabled Contract was called via MsgRecvPacket but destination_port doesn't start with \"wasm.\": {:?}", destination_port, ); return false; @@ -803,33 +850,122 @@ fn verify_contract(msg: &CosmosMsg, contract_address: &HumanAddr) -> bool { let is_verified = *contract_address == HumanAddr::from(contract_address_from_port); if !is_verified { trace!( - "Contract address sent to enclave {:?} is not the same as extracted from MsgRecvPacket but destination_port: {:?}", + "IBC-enabled Contract address sent to enclave {:?} is not the same as extracted from MsgRecvPacket but destination_port: {:?}", + contract_address, + contract_address_from_port, + ); + } + is_verified + } + }, + CosmosSdkMsg::MsgAcknowledgement{ + packet:Packet{ + source_port, + data,.. }, + .. + } => { + if source_port == "transfer" { +// Packet was sent from a contract via the transfer port. +// We're getting the ack here because the memo field contained `{"ibc_callback": "secret1contractAddr"}`, +// and ibc-hooks routes the ack into `secret1contractAddr`. + +// Parse data as FungibleTokenPacketData JSON +let packet_data: FungibleTokenPacketData = match serde_json::from_slice( + data.as_slice(), +) { + Ok(packet_data) => packet_data, + Err(err) => { + trace!( + "Contract was called via ibc-hooks ack callback but packet_data cannot be parsed as FungibleTokenPacketData: {:?} Error: {:?}", + String::from_utf8_lossy(data.as_slice()), + err, + ); + return false; + } +}; + +// memo must be set in ibc-hooks +let memo = match packet_data.memo { + Some(memo) => memo, + None => { + trace!("Contract was called via ibc-hooks ack callback but packet_data.memo is empty"); + return false; + } +}; + +// Parse data.memo as `{"ibc_callback": "secret1contractAddr"}` JSON +let ibc_hooks_outgoing_memo: IbcHooksOutgoingTransferMemo = match serde_json::from_slice(memo.as_bytes()) { + Ok(wasm_msg) => wasm_msg, + Err(err) => { + trace!( + "Contract was called via ibc-hooks but packet_data.memo cannot be parsed as IbcHooksWasmMsg: {:?} Error: {:?}", + memo, + err, + ); + return false; + } +}; + +let is_verified = *contract_address == ibc_hooks_outgoing_memo.ibc_callback && *contract_address == packet_data.sender; +if !is_verified { + trace!( + "Contract address sent to enclave {:?} is not the same as in ibc-hooks outgoing transfer callback address packet {:?}", + contract_address, + ibc_hooks_outgoing_memo.ibc_callback + ); +} +is_verified + } else { + // Packet was sent from an IBC enabled contract + // source_port is of the form "wasm.{contract_address}" + + // Extract contract_address from source_port + // This also checks that source_port starts with "wasm." + let contract_address_from_port = match source_port.strip_prefix("wasm.") { + Some(contract_address) => contract_address, + None => { + trace!( + "IBC-enabled Contract was called via MsgAcknowledgement but source_port doesn't start with \"wasm.\": {:?}", + source_port, + ); + return false; + } + }; + + let is_verified = *contract_address == HumanAddr::from(contract_address_from_port); + if !is_verified { + trace!( + "Contract address sent to enclave {:?} is not the same as extracted from MsgAcknowledgement but source_port: {:?}", contract_address, contract_address_from_port, ); } is_verified } + } } } /// Check that the funds listed in the cosmwasm message matches the ones in env -fn verify_funds(msg: &CosmosMsg, sent_funds_msg: &[Coin]) -> bool { +fn verify_funds(msg: &CosmosSdkMsg, sent_funds_msg: &[Coin]) -> bool { match msg { - CosmosMsg::Execute { sent_funds, .. } - | CosmosMsg::Instantiate { + CosmosSdkMsg::MsgExecuteContract { sent_funds, .. } + | CosmosSdkMsg::MsgInstantiateContract { init_funds: sent_funds, .. } => sent_funds_msg == sent_funds, - CosmosMsg::Other => false, - CosmosMsg::MsgRecvPacket { + CosmosSdkMsg::Other => false, + CosmosSdkMsg::MsgRecvPacket { + packet: Packet { data, source_port, source_channel, destination_port, destination_channel, .. + }, + .. } => { if destination_port == "transfer" { // Packet was routed here through ibc-hooks @@ -927,11 +1063,16 @@ fn verify_funds(msg: &CosmosMsg, sent_funds_msg: &[Coin]) -> bool { sent_funds_msg.is_empty() } } + CosmosSdkMsg::MsgAcknowledgement { .. } => { + + // No funds should be sent with a MsgAcknowledgement + sent_funds_msg.is_empty() + }, } } fn verify_message_params( - messages: &[CosmosMsg], + messages: &[CosmosSdkMsg], sender: &CanonicalAddr, sent_funds: &[Coin], contract_address: &HumanAddr, @@ -955,11 +1096,12 @@ fn verify_message_params( let msg = msg.unwrap(); match msg { - CosmosMsg::MsgRecvPacket { .. } => { + CosmosSdkMsg::MsgRecvPacket{..} | + CosmosSdkMsg::MsgAcknowledgement{..} => { // No sender to verify. // Going to pass null sender to the contract if all other checks pass. } - CosmosMsg::Execute { .. } | CosmosMsg::Instantiate { .. } | CosmosMsg::Other => { + CosmosSdkMsg::MsgExecuteContract { .. } | CosmosSdkMsg::MsgInstantiateContract { .. } | CosmosSdkMsg::Other => { if msg.sender() != Some(sender) { warn!( "message sender did not match cosmwasm message sender: {:?} {:?}", diff --git a/cosmwasm/enclaves/shared/contract-engine/src/ibc_message.rs b/cosmwasm/enclaves/shared/contract-engine/src/ibc_message.rs index f867ec079..1d5e7612c 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/ibc_message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/ibc_message.rs @@ -84,9 +84,9 @@ pub fn parse_ibc_receive_message(message: &[u8]) -> Result Result { Ok(ParsedMessage { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/message.rs b/cosmwasm/enclaves/shared/contract-engine/src/message.rs index dd24f2e1f..156b8b1b6 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/message.rs @@ -5,8 +5,8 @@ use enclave_ffi_types::EnclaveError; use crate::execute_message::parse_execute_message; use crate::ibc_message::{ - parse_ibc_hooks_incoming_transfer_message, parse_ibc_receive_message, - parse_plaintext_ibc_protocol_message, + parse_ibc_receive_message, parse_plaintext_ibc_protocol_message, + parse_plaintext_ibc_validated_message, }; use crate::reply_message::parse_reply_message; use crate::types::ParsedMessage; @@ -22,9 +22,7 @@ pub fn parse_message( HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN | HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT | HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE - | HandleType::HANDLE_TYPE_IBC_PACKET_ACK | HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT - | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT => { trace!( "parsing {} msg (Should always be plaintext): {:?}", @@ -35,8 +33,10 @@ pub fn parse_message( parse_plaintext_ibc_protocol_message(message) } HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => parse_ibc_receive_message(message), - HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { - parse_ibc_hooks_incoming_transfer_message(message) + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER + | HandleType::HANDLE_TYPE_IBC_PACKET_ACK + | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK => { + parse_plaintext_ibc_validated_message(message) } }; } diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index f0387fee0..23001afd0 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -149,7 +149,7 @@ pub enum SignModeDef { } #[allow(non_camel_case_types)] -#[derive(Deserialize, Clone, Debug, PartialEq)] +#[derive(Deserialize, Clone, Debug, PartialEq, Copy)] pub enum HandleType { HANDLE_TYPE_EXECUTE = 0, HANDLE_TYPE_REPLY = 1, @@ -233,7 +233,7 @@ pub struct SignDoc { } impl SignDoc { - pub fn from_bytes(bytes: &[u8]) -> Result { + pub fn from_bytes(bytes: &[u8], handle_type: HandleType) -> Result { let raw_sign_doc = proto::tx::tx::SignDoc::parse_from_bytes(bytes).map_err(|err| { warn!( "got an error while trying to deserialize sign doc bytes from protobuf: {}: {}", @@ -243,7 +243,7 @@ impl SignDoc { EnclaveError::FailedToDeserialize })?; - let body = TxBody::from_bytes(&raw_sign_doc.body_bytes)?; + let body = TxBody::from_bytes(&raw_sign_doc.body_bytes, handle_type)?; let auth_info = AuthInfo::from_bytes(&raw_sign_doc.auth_info_bytes)?; Ok(Self { @@ -257,7 +257,7 @@ impl SignDoc { #[derive(Debug)] pub struct TxBody { - pub messages: Vec, + pub messages: Vec, // Leaving this here for discoverability. We can use this, but don't verify it today. #[allow(dead_code)] memo: (), @@ -266,7 +266,7 @@ pub struct TxBody { } impl TxBody { - pub fn from_bytes(bytes: &[u8]) -> Result { + pub fn from_bytes(bytes: &[u8], handle_type: HandleType) -> Result { let tx_body = proto::tx::tx::TxBody::parse_from_bytes(bytes).map_err(|err| { warn!( "got an error while trying to deserialize cosmos message body bytes from protobuf: {}: {}", @@ -279,7 +279,7 @@ impl TxBody { let messages = tx_body .messages .into_iter() - .map(|any| CosmosMsg::from_bytes(&any.value)) + .map(|any| CosmosSdkMsg::from_bytes(&any.value, handle_type)) .collect::, _>>()?; Ok(TxBody { @@ -323,7 +323,7 @@ pub fn deserialize_ignore_any<'de, D: serde::Deserializer<'de>, T: Default>( } impl StdCosmWasmMsg { - pub fn into_cosmwasm_msg(self) -> Result { + pub fn into_cosmwasm_msg(self) -> Result { match self { Self::Execute { sender, @@ -344,7 +344,7 @@ impl StdCosmWasmMsg { EnclaveError::FailedToDeserialize })?; let msg = msg.0; - Ok(CosmosMsg::Execute { + Ok(CosmosSdkMsg::MsgExecuteContract { sender, contract, msg, @@ -372,7 +372,7 @@ impl StdCosmWasmMsg { EnclaveError::FailedToDeserialize })?; let init_msg = init_msg.0; - Ok(CosmosMsg::Instantiate { + Ok(CosmosSdkMsg::MsgInstantiateContract { sender, init_msg, init_funds, @@ -380,7 +380,7 @@ impl StdCosmWasmMsg { callback_sig, }) } - Self::Other => Ok(CosmosMsg::Other), + Self::Other => Ok(CosmosSdkMsg::Other), } } } @@ -407,17 +407,125 @@ pub struct IbcHooksIncomingTransferWasmMsg { pub msg: serde_json::Value, } -#[derive(Debug)] -pub enum CosmosMsg { +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct IbcHooksOutgoingTransferMemo { + pub ibc_callback: HumanAddr, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct Height { + pub revision_number: u64, + pub revision_height: u64, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum IBCLifecycleComplete { + #[serde(rename = "ibc_lifecycle_complete")] + IBCLifecycleComplete(IBCLifecycleCompleteOptions), +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum IBCLifecycleCompleteOptions { + #[serde(rename = "ibc_ack")] + IBCAck { + /// The source channel (Secret side) of the IBC packet + channel: String, + /// The sequence number that the packet was sent with + sequence: u64, + /// String encoded version of the ack as seen by OnAcknowledgementPacket(..) + ack: String, + /// Weather an ack is a success of failure according to the transfer spec + success: bool, + }, + #[serde(rename = "ibc_timeout")] + IBCTimeout { + /// The source channel (secret side) of the IBC packet + channel: String, + /// The sequence number that the packet was sent with + sequence: u64, + }, +} + +pub fn is_transfer_ack_error(acknowledgement: &[u8]) -> bool { + if let Ok(ack_err) = serde_json::from_slice::(acknowledgement) { + if !ack_err.error.is_empty() { + return true; + } + } + false +} + +#[derive(Deserialize)] +pub struct AcknowledgementError { + #[serde(rename = "error")] + pub error: String, +} + +#[derive(Debug, Deserialize)] +pub struct IBCPacketAckMsg { + pub acknowledgement: IBCAcknowledgement, + pub original_packet: IBCPacket, + pub relayer: String, +} + +#[derive(Debug, Deserialize)] +pub struct IBCAcknowledgement { + pub data: Vec, +} + +#[derive(Debug, Deserialize)] +pub struct IBCPacket { + pub data: Vec, + pub src: IBCEndpoint, + pub dest: IBCEndpoint, + pub sequence: u64, + pub timeout: IBCTimeout, +} + +#[derive(Debug, Deserialize)] +pub struct IBCEndpoint { + pub port_id: String, + pub channel_id: String, +} + +#[derive(Debug, Deserialize)] +pub struct IBCTimeout { + pub block: Option, + pub timestamp: Option, +} + +#[derive(Debug, Deserialize)] +pub struct IBCTimeoutBlock { + pub revision: u64, + pub height: u64, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct Packet { + pub sequence: u64, + pub source_port: String, + pub source_channel: String, + /// if the packet is sent into an IBC-enabled contract, `destination_port` will be `"wasm.{contract_address}"` + /// if the packet is rounted here via ibc-hooks, `destination_port` will be `"transfer"` + pub destination_port: String, + pub destination_channel: String, + /// if the packet is sent into an IBC-enabled contract, this will be raw bytes + /// if the packet is rounted here via ibc-hooks, this will be a JSON string of the type `FungibleTokenPacketData` (https://github.com/cosmos/ibc-go/blob/v4.3.0/modules/apps/transfer/types/packet.pb.go#L25-L39) + pub data: Vec, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum CosmosSdkMsg { // CosmWasm: - Execute { + MsgExecuteContract { sender: CanonicalAddr, contract: HumanAddr, msg: Vec, sent_funds: Vec, callback_sig: Option>, }, - Instantiate { + MsgInstantiateContract { sender: CanonicalAddr, init_msg: Vec, init_funds: Vec, @@ -431,40 +539,51 @@ pub enum CosmosMsg { // MsgChannelOpenConfirm {}, // TODO // MsgChannelCloseInit {}, // TODO // MsgChannelCloseConfirm {}, // TODO - // MsgAcknowledgement {}, // TODO + MsgAcknowledgement { + packet: Packet, + acknowledgement: Vec, + proof_acked: Vec, + proof_height: Option, + signer: String, + }, // MsgTimeout {}, // TODO MsgRecvPacket { - sequence: u64, - source_port: String, - source_channel: String, - /// if the packet is sent into an IBC-enabled contract, `destination_port` will be `"wasm.{contract_address}"` - /// if the packet is rounted here via ibc-hooks, `destination_port` will be `"transfer"` - destination_port: String, - destination_channel: String, - /// if the packet is sent into an IBC-enabled contract, this will be raw bytes - /// if the packet is rounted here via ibc-hooks, this will be a JSON string of the type `FungibleTokenPacketData` (https://github.com/cosmos/ibc-go/blob/v4.3.0/modules/apps/transfer/types/packet.pb.go#L25-L39) - data: Vec, + packet: Packet, + proof_commitment: Vec, + proof_height: Option, + signer: String, }, // All else: Other, } -impl CosmosMsg { - pub fn from_bytes(bytes: &[u8]) -> Result { +impl CosmosSdkMsg { + pub fn from_bytes(bytes: &[u8], handle_type: HandleType) -> Result { // Assaf: This function needs a refactor, as some protobufs are // compatible, e.g. try_parse_execute succeeds in parsing MsgRecvPacket as // MsgExecuteContract, so for now for each field of MsgExecuteContract we also need // to add a sanity check - Self::try_parse_execute(bytes) - .or_else(|_| Self::try_parse_instantiate(bytes)) - .or_else(|_| Self::try_parse_recv_packet(bytes)) - .or_else(|_| { - warn!( - "error while trying to deserialize message bytes protobuf: {}", - Binary(bytes.into()) - ); - Ok(CosmosMsg::Other) - }) + match handle_type { + HandleType::HANDLE_TYPE_EXECUTE => { + Self::try_parse_execute(bytes).or_else(|_| Self::try_parse_instantiate(bytes)) + } + HandleType::HANDLE_TYPE_REPLY => Ok(CosmosSdkMsg::Other), + HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN => Ok(CosmosSdkMsg::Other), + HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT => Ok(CosmosSdkMsg::Other), + HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => Ok(CosmosSdkMsg::Other), + HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => Self::try_parse_ibc_recv_packet(bytes), + HandleType::HANDLE_TYPE_IBC_PACKET_ACK => Self::try_parse_ibc_ack(bytes), + HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => Ok(CosmosSdkMsg::Other), + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { + Self::try_parse_ibc_recv_packet(bytes) + } + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK => { + Self::try_parse_ibc_ack(bytes) + } + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT => { + Ok(CosmosSdkMsg::Other) + } + } } // fn try_parse_msg_channel_open_init(bytes: &[u8]) -> Result { @@ -491,15 +610,39 @@ impl CosmosMsg { // todo!() // } - // fn try_parse_msg_acknowledgement(bytes: &[u8]) -> Result { - // todo!() - // } + fn try_parse_ibc_ack(bytes: &[u8]) -> Result { + use proto::ibc::tx::MsgAcknowledgement; + + let raw_msg = MsgAcknowledgement::parse_from_bytes(bytes) + .map_err(|_| EnclaveError::FailedToDeserialize)?; + + match raw_msg.packet.clone().into_option() { + None => Err(EnclaveError::FailedToDeserialize), + Some(packet) => Ok(CosmosSdkMsg::MsgAcknowledgement { + packet: Packet { + sequence: packet.sequence, + source_port: packet.source_port, + source_channel: packet.source_channel, + destination_port: packet.destination_port, + destination_channel: packet.destination_channel, + data: packet.data, + }, + acknowledgement: raw_msg.acknowledgement, + proof_acked: raw_msg.proof_acked, + proof_height: raw_msg.proof_height.into_option().map(|height| Height { + revision_number: height.revision_number, + revision_height: height.revision_height, + }), + signer: raw_msg.signer, + }), + } + } // fn try_parse_msg_timeout(bytes: &[u8]) -> Result { // todo!() // } - fn try_parse_recv_packet(bytes: &[u8]) -> Result { + fn try_parse_ibc_recv_packet(bytes: &[u8]) -> Result { use proto::ibc::tx::MsgRecvPacket; let raw_msg = MsgRecvPacket::parse_from_bytes(bytes) @@ -507,13 +650,21 @@ impl CosmosMsg { match raw_msg.packet.into_option() { None => Err(EnclaveError::FailedToDeserialize), - Some(packet) => Ok(CosmosMsg::MsgRecvPacket { - sequence: packet.sequence, - source_port: packet.source_port, - source_channel: packet.source_channel, - destination_port: packet.destination_port, - destination_channel: packet.destination_channel, - data: packet.data, + Some(packet) => Ok(CosmosSdkMsg::MsgRecvPacket { + packet: Packet { + sequence: packet.sequence, + source_port: packet.source_port, + source_channel: packet.source_channel, + destination_port: packet.destination_port, + destination_channel: packet.destination_channel, + data: packet.data, + }, + proof_commitment: raw_msg.proof_commitment, + proof_height: raw_msg.proof_height.into_option().map(|height| Height { + revision_number: height.revision_number, + revision_height: height.revision_height, + }), + signer: raw_msg.signer, }), } } @@ -530,16 +681,11 @@ impl CosmosMsg { raw_msg.sender ); - if raw_msg.sender.is_empty() { - warn!("try_parse_instantiate: sender address to instantiate was empty"); - return Err(EnclaveError::FailedToDeserialize); - } - let init_funds = Self::parse_funds(raw_msg.init_funds)?; let callback_sig = Some(raw_msg.callback_sig); - Ok(CosmosMsg::Instantiate { + Ok(CosmosSdkMsg::MsgInstantiateContract { sender: CanonicalAddr(Binary(raw_msg.sender)), init_msg: raw_msg.init_msg, init_funds, @@ -560,22 +706,12 @@ impl CosmosMsg { raw_msg.sender ); - if raw_msg.sender.is_empty() { - warn!("try_parse_execute: sender address to execute was empty"); - return Err(EnclaveError::FailedToDeserialize); - } - trace!( "try_parse_execute contract: len={} val={:?}", raw_msg.contract.len(), raw_msg.contract ); - if raw_msg.contract.is_empty() { - warn!("try_parse_execute: contract address to execute was empty"); - return Err(EnclaveError::FailedToDeserialize); - } - // humanize address let contract = HumanAddr::from_canonical(&CanonicalAddr(Binary(raw_msg.contract))) .map_err(|err| { @@ -590,7 +726,7 @@ impl CosmosMsg { let callback_sig = Some(raw_msg.callback_sig); - Ok(CosmosMsg::Execute { + Ok(CosmosSdkMsg::MsgExecuteContract { sender: CanonicalAddr(Binary(raw_msg.sender)), contract, msg: raw_msg.msg, @@ -623,11 +759,11 @@ impl CosmosMsg { pub fn sender(&self) -> Option<&CanonicalAddr> { match self { - CosmosMsg::Execute { sender, .. } | CosmosMsg::Instantiate { sender, .. } => { - Some(sender) - } - CosmosMsg::MsgRecvPacket { .. } => None, - CosmosMsg::Other => None, + CosmosSdkMsg::MsgExecuteContract { sender, .. } + | CosmosSdkMsg::MsgInstantiateContract { sender, .. } => Some(sender), + CosmosSdkMsg::MsgRecvPacket { .. } => None, + CosmosSdkMsg::MsgAcknowledgement { .. } => None, + CosmosSdkMsg::Other => None, } } } diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index 44bba3b8c..69800f07b 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -2451,3 +2451,58 @@ func TestIBCHooksIncomingTransfer(t *testing.T) { } } } + +func TestIBCHooksOutgoingTransferAck(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + data := ibctransfertypes.FungibleTokenPacketData{ + Denom: "ignored", + Amount: "1", + Sender: contractAddress.String(), // must be the contract address, like in the memo + Receiver: "ignored", + Memo: fmt.Sprintf(`{"ibc_callback":"%s"}`, contractAddress.String()), + } + dataBytes, err := json.Marshal(data) + require.NoError(t, err) + + sdkMsg := ibcchanneltypes.MsgAcknowledgement{ + Packet: ibcchanneltypes.Packet{ + Sequence: 0, + SourcePort: "transfer", // port on the other chain + SourceChannel: "channel-0", // channel on the other chain + DestinationPort: "transfer", // port on Secret + DestinationChannel: "channel-0", // channel on Secret + Data: dataBytes, + TimeoutHeight: ibcclienttypes.Height{}, + TimeoutTimestamp: 0, + }, + Acknowledgement: []byte(`blabla`), + ProofAcked: []byte{}, + ProofHeight: ibcclienttypes.Height{}, + Signer: walletA.String(), + } + + ctx = PrepareSignedTx(t, keeper, ctx, walletA, privKeyA, &sdkMsg) + + _, execErr := keeper.Execute(ctx, contractAddress, walletA, []byte(`{"ibc_lifecycle_complete":{"ibc_ack":{"channel":"channel-0","sequence":0,"ack":"blabla","success":true}}}`), sdk.NewCoins(), nil, cosmwasm.HandleTypeIbcWasmHooksOutgoingTransferAck) + + require.Empty(t, execErr) + + events := tryDecryptWasmEvents(ctx, nil) + + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "ibc_lifecycle_complete.ibc_ack.channel", Value: "channel-0"}, + {Key: "ibc_lifecycle_complete.ibc_ack.sequence", Value: "0"}, + {Key: "ibc_lifecycle_complete.ibc_ack.ack", Value: "blabla"}, + {Key: "ibc_lifecycle_complete.ibc_ack.success", Value: "true"}, + }, + }, + events, + ) +} From 1760865d8f9497e614350f91cb4c2d2d885c2495 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 28 May 2023 14:16:12 +0300 Subject: [PATCH 31/54] IBC hooks outgoing transfer ack validation :tada: --- .../src/contract_validation.rs | 223 +++++++++--------- .../keeper/secret_contracts_exec_test.go | 171 ++++++++++---- 2 files changed, 240 insertions(+), 154 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 91dc3cbf7..88ad1db74 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -1,4 +1,4 @@ -use cw_types_v1::ibc::{IbcPacketReceiveMsg}; +use cw_types_v1::ibc::IbcPacketReceiveMsg; use cw_types_v1::results::REPLY_ENCRYPTION_MAGIC_BYTES; use log::*; @@ -8,8 +8,10 @@ use cw_types_generic::BaseEnv; use cw_types_v010::types::{CanonicalAddr, Coin, HumanAddr}; use enclave_cosmos_types::traits::CosmosAminoPubkey; use enclave_cosmos_types::types::{ - ContractCode, CosmosSdkMsg, CosmosPubKey, FungibleTokenPacketData, HandleType, - SigInfo, SignDoc, StdSignDoc, IbcHooksIncomingTransferMsg, Packet, IbcHooksOutgoingTransferMemo, IBCLifecycleComplete, is_transfer_ack_error, IBCPacketAckMsg, IBCLifecycleCompleteOptions, + is_transfer_ack_error, ContractCode, CosmosPubKey, CosmosSdkMsg, FungibleTokenPacketData, + HandleType, IBCLifecycleComplete, IBCLifecycleCompleteOptions, IBCPacketAckMsg, + IbcHooksIncomingTransferMsg, IbcHooksOutgoingTransferMemo, Packet, SigInfo, SignDoc, + StdSignDoc, }; use enclave_crypto::traits::VerifyingKey; use enclave_crypto::{sha_256, AESKey, Hmac, Kdf, HASH_SIZE, KEY_MANAGER}; @@ -362,8 +364,7 @@ pub fn verify_params( sender: &CanonicalAddr, contract_address: &HumanAddr, msg: &SecretMessage, - #[cfg(feature = "light-client-validation")] - og_msg: &[u8], + #[cfg(feature = "light-client-validation")] og_msg: &[u8], should_validate_sig_info: bool, should_validate_input: bool, handle_type: HandleType, @@ -464,7 +465,11 @@ pub fn verify_params( Ok(()) } -fn get_signer(sign_info: &SigInfo, sender: &CanonicalAddr, handle_type: HandleType) -> Result { +fn get_signer( + sign_info: &SigInfo, + sender: &CanonicalAddr, + handle_type: HandleType, +) -> Result { use cosmos_proto::tx::signing::SignMode::*; match sign_info.sign_mode { SIGN_MODE_DIRECT => { @@ -525,7 +530,10 @@ fn get_signer(sign_info: &SigInfo, sender: &CanonicalAddr, handle_type: HandleTy } } -fn get_messages(sign_info: &SigInfo, handle_type: HandleType) -> Result, EnclaveError> { +fn get_messages( + sign_info: &SigInfo, + handle_type: HandleType, +) -> Result, EnclaveError> { use cosmos_proto::tx::signing::SignMode::*; match sign_info.sign_mode { SIGN_MODE_DIRECT => { @@ -637,7 +645,7 @@ fn verify_callback_sig_impl( } /// Get the cosmwasm message that contains the encrypted message -fn get_verified_msg<'sd>( +fn verify_and_get_sdk_msg<'sd>( messages: &'sd [CosmosSdkMsg], msg_sender: &CanonicalAddr, sent_msg: &SecretMessage, @@ -710,24 +718,23 @@ fn get_verified_msg<'sd>( CosmosSdkMsg::MsgAcknowledgement { packet, acknowledgement, signer,.. } => { match handle_type { HandleType::HANDLE_TYPE_IBC_PACKET_ACK => { - let ibc_packet_ack_msg = serde_json::from_slice::(&sent_msg.msg); - if ibc_packet_ack_msg.is_err(){ - trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_ACK: sent_msg.msg cannot be parsed as IBCPacketAckMsg: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), ibc_packet_ack_msg.err()); + let send_msg_ack_msg = serde_json::from_slice::(&sent_msg.msg); + if send_msg_ack_msg.is_err(){ + trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_ACK: sent_msg.msg cannot be parsed as IBCPacketAckMsg: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), send_msg_ack_msg.err()); return false; } - let ibc_packet_ack_msg= ibc_packet_ack_msg.unwrap(); - - ibc_packet_ack_msg.original_packet.src.channel_id == packet.source_channel && - ibc_packet_ack_msg.original_packet.src.port_id == packet.source_port && - ibc_packet_ack_msg.original_packet.dest.channel_id == packet.destination_channel && - ibc_packet_ack_msg.original_packet.dest.port_id == packet.destination_port && - ibc_packet_ack_msg.original_packet.sequence == packet.sequence && - ibc_packet_ack_msg.original_packet.data == packet.data && - ibc_packet_ack_msg.relayer == *signer && - ibc_packet_ack_msg.acknowledgement.data == *acknowledgement + let sent_msg_ack_msg= send_msg_ack_msg.unwrap(); + + sent_msg_ack_msg.original_packet.src.channel_id == packet.source_channel && + sent_msg_ack_msg.original_packet.src.port_id == packet.source_port && + sent_msg_ack_msg.original_packet.dest.channel_id == packet.destination_channel && + sent_msg_ack_msg.original_packet.dest.port_id == packet.destination_port && + sent_msg_ack_msg.original_packet.sequence == packet.sequence && + sent_msg_ack_msg.original_packet.data == packet.data && + sent_msg_ack_msg.relayer == *signer && + sent_msg_ack_msg.acknowledgement.data == *acknowledgement }, HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK => { - trace!("ASSAF 1"); let ibc_lifecycle_complete = serde_json::from_slice::(&sent_msg.msg); if ibc_lifecycle_complete.is_err(){ trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK: sent_msg.msg cannot be parsed as IBCLifecycleComplete: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), ibc_lifecycle_complete.err()); @@ -735,9 +742,6 @@ fn get_verified_msg<'sd>( } let ibc_lifecycle_complete= ibc_lifecycle_complete.unwrap(); - trace!("ASSAF 2 {:?}", ibc_lifecycle_complete); - - match ibc_lifecycle_complete { IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCAck { channel, sequence, ack, success }) => channel == packet.source_channel @@ -756,7 +760,7 @@ fn get_verified_msg<'sd>( } /// Check that the contract listed in the cosmwasm message matches the one in env -fn verify_contract(msg: &CosmosSdkMsg, contract_address: &HumanAddr) -> bool { +fn verify_contract_address(msg: &CosmosSdkMsg, contract_address: &HumanAddr) -> bool { // Contract address is relevant only to execute, since during sending an instantiate message the contract address is not yet known match msg { CosmosSdkMsg::MsgExecuteContract { contract, .. } => { @@ -774,8 +778,12 @@ fn verify_contract(msg: &CosmosSdkMsg, contract_address: &HumanAddr) -> bool { CosmosSdkMsg::MsgInstantiateContract { .. } => true, CosmosSdkMsg::Other => false, CosmosSdkMsg::MsgRecvPacket { - packet:Packet{ destination_port, - data,..}, + packet: + Packet { + destination_port, + data, + .. + }, .. } => { if destination_port == "transfer" { @@ -806,7 +814,9 @@ fn verify_contract(msg: &CosmosSdkMsg, contract_address: &HumanAddr) -> bool { }; // Parse data.memo as IbcHooksWasmMsg JSON - let wasm_msg: IbcHooksIncomingTransferMsg = match serde_json::from_slice(memo.as_bytes()) { + let wasm_msg: IbcHooksIncomingTransferMsg = match serde_json::from_slice( + memo.as_bytes(), + ) { Ok(wasm_msg) => wasm_msg, Err(err) => { trace!( @@ -857,66 +867,68 @@ fn verify_contract(msg: &CosmosSdkMsg, contract_address: &HumanAddr) -> bool { } is_verified } - }, - CosmosSdkMsg::MsgAcknowledgement{ - packet:Packet{ - source_port, - data,.. }, + } + CosmosSdkMsg::MsgAcknowledgement { + packet: Packet { + source_port, data, .. + }, .. } => { if source_port == "transfer" { -// Packet was sent from a contract via the transfer port. -// We're getting the ack here because the memo field contained `{"ibc_callback": "secret1contractAddr"}`, -// and ibc-hooks routes the ack into `secret1contractAddr`. - -// Parse data as FungibleTokenPacketData JSON -let packet_data: FungibleTokenPacketData = match serde_json::from_slice( - data.as_slice(), -) { - Ok(packet_data) => packet_data, - Err(err) => { - trace!( - "Contract was called via ibc-hooks ack callback but packet_data cannot be parsed as FungibleTokenPacketData: {:?} Error: {:?}", - String::from_utf8_lossy(data.as_slice()), - err, - ); - return false; - } -}; + // Packet was sent from a contract via the transfer port. + // We're getting the ack here because the memo field contained `{"ibc_callback": "secret1contractAddr"}`, + // and ibc-hooks routes the ack into `secret1contractAddr`. -// memo must be set in ibc-hooks -let memo = match packet_data.memo { - Some(memo) => memo, - None => { - trace!("Contract was called via ibc-hooks ack callback but packet_data.memo is empty"); - return false; - } -}; + // Parse data as FungibleTokenPacketData JSON + let packet_data: FungibleTokenPacketData = match serde_json::from_slice( + data.as_slice(), + ) { + Ok(packet_data) => packet_data, + Err(err) => { + trace!( + "Contract was called via ibc-hooks ack callback but packet_data cannot be parsed as FungibleTokenPacketData: {:?} Error: {:?}", + String::from_utf8_lossy(data.as_slice()), + err, + ); + return false; + } + }; -// Parse data.memo as `{"ibc_callback": "secret1contractAddr"}` JSON -let ibc_hooks_outgoing_memo: IbcHooksOutgoingTransferMemo = match serde_json::from_slice(memo.as_bytes()) { - Ok(wasm_msg) => wasm_msg, - Err(err) => { - trace!( - "Contract was called via ibc-hooks but packet_data.memo cannot be parsed as IbcHooksWasmMsg: {:?} Error: {:?}", - memo, - err, - ); - return false; - } -}; + // memo must be set in ibc-hooks + let memo = match packet_data.memo { + Some(memo) => memo, + None => { + trace!("Contract was called via ibc-hooks ack callback but packet_data.memo is empty"); + return false; + } + }; -let is_verified = *contract_address == ibc_hooks_outgoing_memo.ibc_callback && *contract_address == packet_data.sender; -if !is_verified { - trace!( - "Contract address sent to enclave {:?} is not the same as in ibc-hooks outgoing transfer callback address packet {:?}", - contract_address, - ibc_hooks_outgoing_memo.ibc_callback - ); -} -is_verified + // Parse data.memo as `{"ibc_callback": "secret1contractAddr"}` JSON + let ibc_hooks_outgoing_memo: IbcHooksOutgoingTransferMemo = + match serde_json::from_slice(memo.as_bytes()) { + Ok(wasm_msg) => wasm_msg, + Err(err) => { + trace!( + "Contract was called via ibc-hooks but packet_data.memo cannot be parsed as IbcHooksWasmMsg: {:?} Error: {:?}", + memo, + err, + ); + return false; + } + }; + + let is_verified = *contract_address == ibc_hooks_outgoing_memo.ibc_callback + && *contract_address == packet_data.sender; + if !is_verified { + trace!( + "Contract address sent to enclave {:?} is not the same as in ibc-hooks outgoing transfer callback address packet {:?}", + contract_address, + ibc_hooks_outgoing_memo.ibc_callback + ); + } + is_verified } else { - // Packet was sent from an IBC enabled contract + // Packet was sent from an IBC enabled contract // source_port is of the form "wasm.{contract_address}" // Extract contract_address from source_port @@ -942,13 +954,12 @@ is_verified } is_verified } - } } } /// Check that the funds listed in the cosmwasm message matches the ones in env -fn verify_funds(msg: &CosmosSdkMsg, sent_funds_msg: &[Coin]) -> bool { +fn verify_sent_funds(msg: &CosmosSdkMsg, sent_funds_msg: &[Coin]) -> bool { match msg { CosmosSdkMsg::MsgExecuteContract { sent_funds, .. } | CosmosSdkMsg::MsgInstantiateContract { @@ -957,14 +968,15 @@ fn verify_funds(msg: &CosmosSdkMsg, sent_funds_msg: &[Coin]) -> bool { } => sent_funds_msg == sent_funds, CosmosSdkMsg::Other => false, CosmosSdkMsg::MsgRecvPacket { - packet: Packet { - data, - source_port, - source_channel, - destination_port, - destination_channel, - .. - }, + packet: + Packet { + data, + source_port, + source_channel, + destination_port, + destination_channel, + .. + }, .. } => { if destination_port == "transfer" { @@ -1064,10 +1076,9 @@ fn verify_funds(msg: &CosmosSdkMsg, sent_funds_msg: &[Coin]) -> bool { } } CosmosSdkMsg::MsgAcknowledgement { .. } => { - - // No funds should be sent with a MsgAcknowledgement - sent_funds_msg.is_empty() - }, + // No funds should be sent with a MsgAcknowledgement + sent_funds_msg.is_empty() + } } } @@ -1082,7 +1093,7 @@ fn verify_message_params( info!("Verifying message..."); // If msg is not found (is None) then it means message verification failed, // since it didn't find a matching signed message - let msg = get_verified_msg(messages, sender, sent_msg, handle_type); + let msg = verify_and_get_sdk_msg(messages, sender, sent_msg, handle_type); if msg.is_none() { debug!("Message verification failed!"); trace!( @@ -1096,12 +1107,13 @@ fn verify_message_params( let msg = msg.unwrap(); match msg { - CosmosSdkMsg::MsgRecvPacket{..} | - CosmosSdkMsg::MsgAcknowledgement{..} => { + CosmosSdkMsg::MsgRecvPacket { .. } | CosmosSdkMsg::MsgAcknowledgement { .. } => { // No sender to verify. // Going to pass null sender to the contract if all other checks pass. } - CosmosSdkMsg::MsgExecuteContract { .. } | CosmosSdkMsg::MsgInstantiateContract { .. } | CosmosSdkMsg::Other => { + CosmosSdkMsg::MsgExecuteContract { .. } + | CosmosSdkMsg::MsgInstantiateContract { .. } + | CosmosSdkMsg::Other => { if msg.sender() != Some(sender) { warn!( "message sender did not match cosmwasm message sender: {:?} {:?}", @@ -1113,13 +1125,13 @@ fn verify_message_params( } info!("Verifying contract address.."); - if !verify_contract(msg, contract_address) { + if !verify_contract_address(msg, contract_address) { warn!("Contract address verification failed!"); return false; } - info!("Verifying funds.."); - if !verify_funds(msg, sent_funds) { + info!("Verifying funds {:?}...",sent_funds); + if !verify_sent_funds(msg, sent_funds) { warn!("Funds verification failed!"); return false; } @@ -1210,10 +1222,7 @@ fn parse_denom_trace(raw_denom: &str) -> DenomTrace { let (path, base_denom) = extract_path_and_base_from_full_denom(&denom_split); - DenomTrace { - path, - base_denom, - } + DenomTrace { path, base_denom } } /// extract_path_and_base_from_full_denom returns the trace path and the base denom from diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index 69800f07b..b7043be45 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -2453,56 +2453,133 @@ func TestIBCHooksIncomingTransfer(t *testing.T) { } func TestIBCHooksOutgoingTransferAck(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - - _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) - require.Empty(t, initErr) - - data := ibctransfertypes.FungibleTokenPacketData{ - Denom: "ignored", - Amount: "1", - Sender: contractAddress.String(), // must be the contract address, like in the memo - Receiver: "ignored", - Memo: fmt.Sprintf(`{"ibc_callback":"%s"}`, contractAddress.String()), - } - dataBytes, err := json.Marshal(data) - require.NoError(t, err) - - sdkMsg := ibcchanneltypes.MsgAcknowledgement{ - Packet: ibcchanneltypes.Packet{ - Sequence: 0, - SourcePort: "transfer", // port on the other chain - SourceChannel: "channel-0", // channel on the other chain - DestinationPort: "transfer", // port on Secret - DestinationChannel: "channel-0", // channel on Secret - Data: dataBytes, - TimeoutHeight: ibcclienttypes.Height{}, - TimeoutTimestamp: 0, + for _, test := range []struct { + name string + sdkMsgSrcPort string + sdkMsgSrcChannel string + sdkMsgDestPort string + sdkMsgDestChannel string + sdkMsgAck string + wasmInputSrcChannel string + wasmInputAck string + wasmInputCoin sdk.Coins + err string + }{ + { + name: "happy path", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: "blabla", + wasmInputSrcChannel: "channel-0", + wasmInputAck: "blabla", + wasmInputCoin: sdk.NewCoins(), + err: "", }, - Acknowledgement: []byte(`blabla`), - ProofAcked: []byte{}, - ProofHeight: ibcclienttypes.Height{}, - Signer: walletA.String(), - } - - ctx = PrepareSignedTx(t, keeper, ctx, walletA, privKeyA, &sdkMsg) + { + name: "channel mismatch", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: "blabla", + wasmInputSrcChannel: "channel-1", + wasmInputAck: "blabla", + wasmInputCoin: sdk.NewCoins(), + err: "failed to verify transaction", + }, + { + name: "no coins should be sent", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: "blabla", + wasmInputSrcChannel: "channel-0", + wasmInputAck: "blabla", + wasmInputCoin: sdk.NewCoins(sdk.NewInt64Coin("denom", 1)), + err: "failed to verify transaction", + }, + { + name: "ack mismatch", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: "yadayada", + wasmInputSrcChannel: "channel-0", + wasmInputAck: "blabla", + wasmInputCoin: sdk.NewCoins(), + err: "failed to verify transaction", + }, + } { + t.Run(test.name, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) - _, execErr := keeper.Execute(ctx, contractAddress, walletA, []byte(`{"ibc_lifecycle_complete":{"ibc_ack":{"channel":"channel-0","sequence":0,"ack":"blabla","success":true}}}`), sdk.NewCoins(), nil, cosmwasm.HandleTypeIbcWasmHooksOutgoingTransferAck) + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) - require.Empty(t, execErr) + data := ibctransfertypes.FungibleTokenPacketData{ + Denom: "ignored", + Amount: "1", + Sender: contractAddress.String(), // must be the contract address, like in the memo + Receiver: "ignored", + Memo: fmt.Sprintf(`{"ibc_callback":"%s"}`, contractAddress.String()), + } + dataBytes, err := json.Marshal(data) + require.NoError(t, err) + + sdkMsg := ibcchanneltypes.MsgAcknowledgement{ + Packet: ibcchanneltypes.Packet{ + Sequence: 0, + SourcePort: test.sdkMsgSrcPort, // port on Secret + SourceChannel: test.sdkMsgSrcChannel, // channel on Secret + DestinationPort: test.sdkMsgDestPort, // port on the other chain + DestinationChannel: test.sdkMsgDestChannel, // channel on the other chain + Data: dataBytes, + TimeoutHeight: ibcclienttypes.Height{}, + TimeoutTimestamp: 0, + }, + Acknowledgement: []byte(test.sdkMsgAck), + ProofAcked: []byte{}, + ProofHeight: ibcclienttypes.Height{}, + Signer: walletA.String(), + } - events := tryDecryptWasmEvents(ctx, nil) + ctx = PrepareSignedTx(t, keeper, ctx, walletA, privKeyA, &sdkMsg) + + _, execErr := keeper.Execute(ctx, + contractAddress, + walletA, + []byte( + fmt.Sprintf(`{"ibc_lifecycle_complete":{"ibc_ack":{"channel":"%s","sequence":0,"ack":"%s","success":true}}}`, + test.wasmInputSrcChannel, + test.wasmInputAck, + )), + test.wasmInputCoin, + nil, + cosmwasm.HandleTypeIbcWasmHooksOutgoingTransferAck, + ) - requireEvents(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "ibc_lifecycle_complete.ibc_ack.channel", Value: "channel-0"}, - {Key: "ibc_lifecycle_complete.ibc_ack.sequence", Value: "0"}, - {Key: "ibc_lifecycle_complete.ibc_ack.ack", Value: "blabla"}, - {Key: "ibc_lifecycle_complete.ibc_ack.success", Value: "true"}, - }, - }, - events, - ) + if test.err == "" { + require.Empty(t, execErr) + events := tryDecryptWasmEvents(ctx, nil) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "ibc_lifecycle_complete.ibc_ack.channel", Value: test.sdkMsgSrcChannel}, + {Key: "ibc_lifecycle_complete.ibc_ack.sequence", Value: "0"}, + {Key: "ibc_lifecycle_complete.ibc_ack.ack", Value: test.sdkMsgAck}, + {Key: "ibc_lifecycle_complete.ibc_ack.success", Value: "true"}, + }, + }, + events, + ) + } else { + require.Contains(t, execErr.Error(), test.err) + } + }) + } } From fe275022db83ba32136b6136dc0b102e558847cf Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 28 May 2023 17:12:49 +0300 Subject: [PATCH 32/54] IBC hooks outgoing transfer timeout validation + more tests for ack + fix rustfmt (sorry) --- .../block-verifier/src/validator_whitelist.rs | 8 +- .../shared/block-verifier/src/verify/mod.rs | 4 +- .../src/contract_validation.rs | 72 ++++- .../shared/contract-engine/src/gas.rs | 2 +- .../enclaves/shared/contract-engine/src/io.rs | 136 ++++---- .../shared/contract-engine/src/lib.rs | 2 - .../shared/contract-engine/src/message.rs | 8 +- .../enclaves/shared/cosmos-types/src/types.rs | 59 +++- .../enclaves/shared/crypto/src/key_manager.rs | 30 +- cosmwasm/enclaves/shared/utils/src/lib.rs | 2 +- .../enclaves/shared/utils/src/tx_bytes.rs | 16 +- .../keeper/secret_contracts_exec_test.go | 298 +++++++++++++++--- 12 files changed, 474 insertions(+), 163 deletions(-) diff --git a/cosmwasm/enclaves/shared/block-verifier/src/validator_whitelist.rs b/cosmwasm/enclaves/shared/block-verifier/src/validator_whitelist.rs index 68d1e446f..f44252d80 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/validator_whitelist.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/validator_whitelist.rs @@ -36,7 +36,13 @@ impl ValidatorList { } pub fn whitelisted_validators_in_block(untrusted_block: &UntrustedBlockState) -> bool { - untrusted_block.validators.validators().iter().filter(|&a| {VALIDATOR_WHITELIST.contains(&a.address.to_string())}).count() >= VALIDATOR_THRESHOLD + untrusted_block + .validators + .validators() + .iter() + .filter(|&a| VALIDATOR_WHITELIST.contains(&a.address.to_string())) + .count() + >= VALIDATOR_THRESHOLD } #[cfg(feature = "test")] diff --git a/cosmwasm/enclaves/shared/block-verifier/src/verify/mod.rs b/cosmwasm/enclaves/shared/block-verifier/src/verify/mod.rs index 72ee509d4..7ae0d01c0 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/verify/mod.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/verify/mod.rs @@ -1,8 +1,8 @@ -pub mod txs; -pub mod validator_set; pub mod block; pub mod commit; pub mod header; +pub mod txs; +pub mod validator_set; #[cfg(feature = "random")] pub mod random; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 88ad1db74..b268b526d 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -10,8 +10,8 @@ use enclave_cosmos_types::traits::CosmosAminoPubkey; use enclave_cosmos_types::types::{ is_transfer_ack_error, ContractCode, CosmosPubKey, CosmosSdkMsg, FungibleTokenPacketData, HandleType, IBCLifecycleComplete, IBCLifecycleCompleteOptions, IBCPacketAckMsg, - IbcHooksIncomingTransferMsg, IbcHooksOutgoingTransferMemo, Packet, SigInfo, SignDoc, - StdSignDoc, + IBCPacketTimeoutMsg, IbcHooksIncomingTransferMsg, IbcHooksOutgoingTransferMemo, Packet, + SigInfo, SignDoc, StdSignDoc, }; use enclave_crypto::traits::VerifyingKey; use enclave_crypto::{sha_256, AESKey, Hmac, Kdf, HASH_SIZE, KEY_MANAGER}; @@ -679,7 +679,7 @@ fn verify_and_get_sdk_msg<'sd>( return &sent_msg.to_vec() == data; } let parsed = parsed_sent_msg.unwrap(); - + parsed.packet.data.as_slice() == data.as_slice() && parsed.packet.sequence == *sequence && parsed.packet.src.port_id == *source_port @@ -703,7 +703,6 @@ fn verify_and_get_sdk_msg<'sd>( return false; } let ibc_hooks_incoming_transfer_msg = ibc_hooks_incoming_transfer_msg.unwrap(); - let sent_msg_value = serde_json::from_slice::(&sent_msg.msg); if sent_msg_value.is_err(){ trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: sent_msg.msg cannot be parsed as serde_json::Value: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), sent_msg_value.err()); @@ -743,17 +742,53 @@ fn verify_and_get_sdk_msg<'sd>( let ibc_lifecycle_complete= ibc_lifecycle_complete.unwrap(); match ibc_lifecycle_complete { - IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCAck { channel, sequence, ack, success }) => + IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCAck { channel, sequence, ack, success }) => channel == packet.source_channel && sequence == packet.sequence && ack == String::from_utf8_lossy( acknowledgement) - && success == !is_transfer_ack_error(acknowledgement) - , + && success == !is_transfer_ack_error(acknowledgement), IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCTimeout { .. }) => false, } }, _ => false, + } + }, + CosmosSdkMsg::MsgTimeout { packet, signer,.. } => { + match handle_type { + HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => { + let send_msg_timeout_msg = serde_json::from_slice::(&sent_msg.msg); + if send_msg_timeout_msg.is_err(){ + trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_TIMEOUT: sent_msg.msg cannot be parsed as IBCPacketTimeoutMsg: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), send_msg_timeout_msg.err()); + return false; + } + let sent_msg_timeout_msg= send_msg_timeout_msg.unwrap(); + + sent_msg_timeout_msg.original_packet.src.channel_id == packet.source_channel && + sent_msg_timeout_msg.original_packet.src.port_id == packet.source_port && + sent_msg_timeout_msg.original_packet.dest.channel_id == packet.destination_channel && + sent_msg_timeout_msg.original_packet.dest.port_id == packet.destination_port && + sent_msg_timeout_msg.original_packet.sequence == packet.sequence && + sent_msg_timeout_msg.original_packet.data == packet.data && + sent_msg_timeout_msg.relayer == *signer + }, + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT => { + let ibc_lifecycle_complete = serde_json::from_slice::(&sent_msg.msg); + if ibc_lifecycle_complete.is_err(){ + trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT: sent_msg.msg cannot be parsed as IBCLifecycleComplete: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), ibc_lifecycle_complete.err()); + return false; + } + let ibc_lifecycle_complete= ibc_lifecycle_complete.unwrap(); + + match ibc_lifecycle_complete { + IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCAck {..}) => false , + IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCTimeout { channel, sequence }) => + channel == packet.source_channel + && sequence == packet.sequence, + } + }, + _ => false, + } }, }) @@ -873,10 +908,16 @@ fn verify_contract_address(msg: &CosmosSdkMsg, contract_address: &HumanAddr) -> source_port, data, .. }, .. + } + | CosmosSdkMsg::MsgTimeout { + packet: Packet { + source_port, data, .. + }, + .. } => { if source_port == "transfer" { // Packet was sent from a contract via the transfer port. - // We're getting the ack here because the memo field contained `{"ibc_callback": "secret1contractAddr"}`, + // We're getting the ack (and timeout) here because the memo field contained `{"ibc_callback": "secret1contractAddr"}`, // and ibc-hooks routes the ack into `secret1contractAddr`. // Parse data as FungibleTokenPacketData JSON @@ -1079,6 +1120,10 @@ fn verify_sent_funds(msg: &CosmosSdkMsg, sent_funds_msg: &[Coin]) -> bool { // No funds should be sent with a MsgAcknowledgement sent_funds_msg.is_empty() } + CosmosSdkMsg::MsgTimeout { .. } => { + // No funds should be sent with a MsgTimeout + sent_funds_msg.is_empty() + } } } @@ -1090,7 +1135,7 @@ fn verify_message_params( sent_msg: &SecretMessage, handle_type: HandleType, ) -> bool { - info!("Verifying message..."); + info!("Verifying sdk message against wasm input..."); // If msg is not found (is None) then it means message verification failed, // since it didn't find a matching signed message let msg = verify_and_get_sdk_msg(messages, sender, sent_msg, handle_type); @@ -1106,8 +1151,11 @@ fn verify_message_params( } let msg = msg.unwrap(); + info!("Verifying message sender..."); match msg { - CosmosSdkMsg::MsgRecvPacket { .. } | CosmosSdkMsg::MsgAcknowledgement { .. } => { + CosmosSdkMsg::MsgRecvPacket { .. } + | CosmosSdkMsg::MsgAcknowledgement { .. } + | CosmosSdkMsg::MsgTimeout { .. } => { // No sender to verify. // Going to pass null sender to the contract if all other checks pass. } @@ -1124,13 +1172,13 @@ fn verify_message_params( } } - info!("Verifying contract address.."); + info!("Verifying contract address..."); if !verify_contract_address(msg, contract_address) { warn!("Contract address verification failed!"); return false; } - info!("Verifying funds {:?}...",sent_funds); + info!("Verifying sent funds..."); if !verify_sent_funds(msg, sent_funds) { warn!("Funds verification failed!"); return false; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/gas.rs b/cosmwasm/enclaves/shared/contract-engine/src/gas.rs index 3bbd59ac2..e52e011e4 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/gas.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/gas.rs @@ -81,7 +81,7 @@ impl Default for WasmCosts { external_secp256k1_sign: 100000, external_ed25519_sign: 75000, external_check_gas_used: 8192, - external_minimum_gas_evaporate: 8000 + external_minimum_gas_evaporate: 8000, } } } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/io.rs b/cosmwasm/enclaves/shared/contract-engine/src/io.rs index be809d946..71cda8c2c 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/io.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/io.rs @@ -1,5 +1,5 @@ -use core::fmt; use crate::contract_validation::ReplyParams; +use core::fmt; /// This contains all the user-facing functions. In these functions we will be using /// the consensus_io_exchange_keypair and a user-generated key to create a symmetric key @@ -241,7 +241,7 @@ pub fn finalize_raw_output( is_query_output: bool, is_ibc: bool, is_msg_encrypted: bool, -) -> Result , EnclaveError> { +) -> Result, EnclaveError> { let mut wasm_output = WasmOutput::default(); match raw_output { @@ -280,7 +280,7 @@ pub fn finalize_raw_output( }); wasm_output.internal_reply_enclave_sig = internal_reply_enclave_sig; wasm_output.internal_msg_id = internal_msg_id; - }, + } RawWasmOutput::OkV1 { ok, internal_reply_enclave_sig, @@ -304,19 +304,19 @@ pub fn finalize_raw_output( ok: Some(ok), }); } - }, + } RawWasmOutput::QueryOkV010 { ok } | RawWasmOutput::QueryOkV1 { ok } => { wasm_output.query = Some(QueryOutput { ok: Some(ok), err: None, }); - }, + } RawWasmOutput::OkIBCPacketReceive { ok } => { wasm_output.ibc_packet_receive = Some(IBCReceiveOutput { err: None, ok: Some(ok), }); - }, + } RawWasmOutput::OkIBCOpenChannel { ok } => { wasm_output.ibc_open_channel = Some(IBCOpenChannelOutput { err: None, @@ -446,10 +446,11 @@ pub fn set_all_logs_to_plaintext(raw_output: &mut RawWasmOutput) { } } -fn deserialize_output( - output: Vec -) -> Result { - info!("output as received from contract: {:?}", String::from_utf8_lossy(&output)); +fn deserialize_output(output: Vec) -> Result { + info!( + "output as received from contract: {:?}", + String::from_utf8_lossy(&output) + ); let output: RawWasmOutput = serde_json::from_slice(&output).map_err(|err| { warn!("got an error while trying to deserialize output bytes from json"); @@ -487,8 +488,7 @@ fn encrypt_output( let encryption_key = calc_encryption_key(&secret_msg.nonce, &secret_msg.user_public_key); info!( "message nonce and public key for encryption: {:?} {:?}", - secret_msg.nonce, - secret_msg.user_public_key + secret_msg.nonce, secret_msg.user_public_key ); match &mut output { @@ -529,7 +529,12 @@ fn encrypt_output( } } RawWasmOutput::OkV1 { ok, .. } => { - encrypt_v1_non_result_fields(&mut ok.messages, &mut ok.attributes, &mut ok.events, secret_msg)?; + encrypt_v1_non_result_fields( + &mut ok.messages, + &mut ok.attributes, + &mut ok.events, + secret_msg, + )?; if let Some(data) = &mut ok.data { if is_ibc_output { warn!("IBC output should not contain any data"); @@ -545,7 +550,12 @@ fn encrypt_output( } } RawWasmOutput::OkIBCPacketReceive { ok } => { - encrypt_v1_non_result_fields(&mut ok.messages, &mut ok.attributes, &mut ok.events, secret_msg)?; + encrypt_v1_non_result_fields( + &mut ok.messages, + &mut ok.attributes, + &mut ok.events, + secret_msg, + )?; ok.acknowledgement = Binary::from_base64(&encrypt_serializable( &encryption_key, @@ -575,17 +585,14 @@ fn encrypt_v1_non_result_fields( // v1: The attributes that will be emitted as part of a "wasm" event. for attr in attributes.iter_mut().filter(|attr| attr.encrypted) { attr.key = encrypt_preserialized_string(&encryption_key, &attr.key, &None, false)?; - attr.value = - encrypt_preserialized_string(&encryption_key, &attr.value, &None, false)?; + attr.value = encrypt_preserialized_string(&encryption_key, &attr.value, &None, false)?; } // v1: Extra, custom events separate from the main wasm one. These will have "wasm-"" prepended to the type. for event in events.iter_mut() { for attr in event.attributes.iter_mut().filter(|attr| attr.encrypted) { - attr.key = - encrypt_preserialized_string(&encryption_key, &attr.key, &None, false)?; - attr.value = - encrypt_preserialized_string(&encryption_key, &attr.value, &None, false)?; + attr.key = encrypt_preserialized_string(&encryption_key, &attr.key, &None, false)?; + attr.value = encrypt_preserialized_string(&encryption_key, &attr.value, &None, false)?; } } @@ -599,8 +606,8 @@ fn encrypt_wasm_submsg( // Messages other than Wasm (Bank, Staking, etc.) are kept plaintext if let cw_types_v1::results::CosmosMsg::Wasm(wasm_msg) = &mut sub_msg.msg { match wasm_msg { - cw_types_v1::results::WasmMsg::Instantiate { msg, .. } | - cw_types_v1::results::WasmMsg::Execute { msg, .. } => { + cw_types_v1::results::WasmMsg::Instantiate { msg, .. } + | cw_types_v1::results::WasmMsg::Execute { msg, .. } => { let mut msg_to_encrypt = SecretMessage { msg: msg.as_slice().to_vec(), nonce: secret_msg.nonce, @@ -632,13 +639,9 @@ fn attach_reply_headers_to_submsgs( reply_params: &Option>, ) -> Result { let sub_msgs = match &mut output { - RawWasmOutput::OkV1 { ok, .. } => { - &mut ok.messages - }, - RawWasmOutput::OkIBCPacketReceive { ok } => { - &mut ok.messages - }, - _ => return Ok(output) + RawWasmOutput::OkV1 { ok, .. } => &mut ok.messages, + RawWasmOutput::OkIBCPacketReceive { ok } => &mut ok.messages, + _ => return Ok(output), }; for sub_msg in sub_msgs { @@ -675,20 +678,26 @@ fn create_callback_sig_for_submsgs( contract_addr: &CanonicalAddr, ) -> Result { let sub_msgs = match &mut output { - RawWasmOutput::OkV1 { ok, .. } => { - &mut ok.messages - }, - RawWasmOutput::OkIBCPacketReceive { ok } => { - &mut ok.messages - }, - _ => return Ok(output) + RawWasmOutput::OkV1 { ok, .. } => &mut ok.messages, + RawWasmOutput::OkIBCPacketReceive { ok } => &mut ok.messages, + _ => return Ok(output), }; for sub_msg in sub_msgs { if let cw_types_v1::results::CosmosMsg::Wasm(wasm_msg) = &mut sub_msg.msg { match wasm_msg { - cw_types_v1::results::WasmMsg::Execute { msg, callback_sig, funds, .. } - | cw_types_v1::results::WasmMsg::Instantiate { msg, callback_sig, funds, .. } => { + cw_types_v1::results::WasmMsg::Execute { + msg, + callback_sig, + funds, + .. + } + | cw_types_v1::results::WasmMsg::Instantiate { + msg, + callback_sig, + funds, + .. + } => { *callback_sig = Some(create_callback_signature( contract_addr, &SecretMessage::from_slice(msg.as_slice())?.msg, @@ -708,7 +717,6 @@ fn create_callback_sig_for_submsgs( Ok(output) } - /// Adapt the output of a contract to be returned as a Reply message. /// If the contract's execution was not called from another contract, the output is returned as is. /// Otherwise, the fields `internal_msg_id` and `internal_reply_enclave_sig` of the output are populated. @@ -731,7 +739,7 @@ fn adapt_output_for_reply( if reply_params.is_none() { // This message was not called from another contract, // no need to adapt output as a reply - return Ok(output) + return Ok(output); } let encryption_key = calc_encryption_key(&secret_msg.nonce, &secret_msg.user_public_key); @@ -757,7 +765,7 @@ fn adapt_output_for_reply( }); should_append_reply_params = false; - }, + } RawWasmOutput::OkV1 { ok, .. } => { output_result = SubMsgResult::Ok(SubMsgResponse { events: vec![], @@ -765,14 +773,26 @@ fn adapt_output_for_reply( }); should_append_reply_params = true; - }, - _ => return Ok(output) + } + _ => return Ok(output), } match &mut output { - RawWasmOutput::Err { internal_msg_id, internal_reply_enclave_sig, .. } | - RawWasmOutput::OkV010 { internal_msg_id, internal_reply_enclave_sig, .. } | - RawWasmOutput::OkV1 { internal_msg_id, internal_reply_enclave_sig, .. } => { + RawWasmOutput::Err { + internal_msg_id, + internal_reply_enclave_sig, + .. + } + | RawWasmOutput::OkV010 { + internal_msg_id, + internal_reply_enclave_sig, + .. + } + | RawWasmOutput::OkV1 { + internal_msg_id, + internal_reply_enclave_sig, + .. + } => { let (msg_id, callback_sig) = get_reply_info_for_output( output_result, reply_params, @@ -783,7 +803,7 @@ fn adapt_output_for_reply( *internal_msg_id = Some(msg_id); *internal_reply_enclave_sig = Some(callback_sig); - }, + } _ => {} } @@ -819,9 +839,7 @@ fn get_reply_info_for_output( EnclaveError::FailedToSerialize })?; - let sig = Binary::from( - create_callback_signature(sender_addr, &reply_json, &[]).as_slice(), - ); + let sig = Binary::from(create_callback_signature(sender_addr, &reply_json, &[]).as_slice()); trace!( "Generated internal callback signature for msg {:?} signature is: {:?}", @@ -865,7 +883,11 @@ fn encrypt_v010_wasm_msg( msg_to_pass.encrypt_in_place()?; *msg = Binary::from(msg_to_pass.to_vec().as_slice()); - *callback_sig = Some(create_callback_signature(contract_addr, &msg_to_pass.msg, send)); + *callback_sig = Some(create_callback_signature( + contract_addr, + &msg_to_pass.msg, + send, + )); } } @@ -881,16 +903,8 @@ fn attach_reply_headers_to_v1_wasm_msg( reply_params: &Option>, ) -> Result<(), EnclaveError> { match wasm_msg { - cw_types_v1::results::WasmMsg::Execute { - msg, - code_hash, - .. - } - | cw_types_v1::results::WasmMsg::Instantiate { - msg, - code_hash, - .. - } => { + cw_types_v1::results::WasmMsg::Execute { msg, code_hash, .. } + | cw_types_v1::results::WasmMsg::Instantiate { msg, code_hash, .. } => { // On cosmwasm v1, submessages execute contracts whose results are sent back to the original caller by using "Reply". // Such submessages should be encrypted, but they weren't initially meant to be sent back to the enclave as an input of another contract. // To support "sending back" behavior, the enclave expects every encrypted input to be prepended by the recipient's contract hash. diff --git a/cosmwasm/enclaves/shared/contract-engine/src/lib.rs b/cosmwasm/enclaves/shared/contract-engine/src/lib.rs index 7f6a99e63..c7bbe6905 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/lib.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/lib.rs @@ -23,8 +23,6 @@ mod query_chain; mod random; mod reply_message; pub(crate) mod types; -#[cfg(feature = "wasmi-engine")] -mod wasm; #[cfg(feature = "wasm3")] mod wasm3; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/message.rs b/cosmwasm/enclaves/shared/contract-engine/src/message.rs index 156b8b1b6..c92143944 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/message.rs @@ -21,9 +21,7 @@ pub fn parse_message( HandleType::HANDLE_TYPE_REPLY => parse_reply_message(message), HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN | HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT - | HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE - | HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT - | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT => { + | HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => { trace!( "parsing {} msg (Should always be plaintext): {:?}", HandleType::get_export_name(handle_type), @@ -35,7 +33,9 @@ pub fn parse_message( HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => parse_ibc_receive_message(message), HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER | HandleType::HANDLE_TYPE_IBC_PACKET_ACK - | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK => { + | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK + | HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT + | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT => { parse_plaintext_ibc_validated_message(message) } }; diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 23001afd0..ecdb526b7 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -474,6 +474,12 @@ pub struct IBCAcknowledgement { pub data: Vec, } +#[derive(Debug, Deserialize)] +pub struct IBCPacketTimeoutMsg { + pub original_packet: IBCPacket, + pub relayer: String, +} + #[derive(Debug, Deserialize)] pub struct IBCPacket { pub data: Vec, @@ -546,7 +552,13 @@ pub enum CosmosSdkMsg { proof_height: Option, signer: String, }, - // MsgTimeout {}, // TODO + MsgTimeout { + packet: Packet, + proof_unreceived: Vec, + proof_height: Option, + next_sequence_recv: u64, + signer: String, + }, MsgRecvPacket { packet: Packet, proof_commitment: Vec, @@ -571,17 +583,17 @@ impl CosmosSdkMsg { HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN => Ok(CosmosSdkMsg::Other), HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT => Ok(CosmosSdkMsg::Other), HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => Ok(CosmosSdkMsg::Other), - HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => Self::try_parse_ibc_recv_packet(bytes), - HandleType::HANDLE_TYPE_IBC_PACKET_ACK => Self::try_parse_ibc_ack(bytes), - HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => Ok(CosmosSdkMsg::Other), - HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { + HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE + | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { Self::try_parse_ibc_recv_packet(bytes) } - HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK => { + HandleType::HANDLE_TYPE_IBC_PACKET_ACK + | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK => { Self::try_parse_ibc_ack(bytes) } - HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT => { - Ok(CosmosSdkMsg::Other) + HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT + | HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT => { + Self::try_parse_ibc_timeout(bytes) } } } @@ -638,9 +650,33 @@ impl CosmosSdkMsg { } } - // fn try_parse_msg_timeout(bytes: &[u8]) -> Result { - // todo!() - // } + fn try_parse_ibc_timeout(bytes: &[u8]) -> Result { + use proto::ibc::tx::MsgTimeout; + + let raw_msg = + MsgTimeout::parse_from_bytes(bytes).map_err(|_| EnclaveError::FailedToDeserialize)?; + + match raw_msg.packet.clone().into_option() { + None => Err(EnclaveError::FailedToDeserialize), + Some(packet) => Ok(CosmosSdkMsg::MsgTimeout { + packet: Packet { + sequence: packet.sequence, + source_port: packet.source_port, + source_channel: packet.source_channel, + destination_port: packet.destination_port, + destination_channel: packet.destination_channel, + data: packet.data, + }, + next_sequence_recv: raw_msg.next_sequence_recv, + proof_unreceived: raw_msg.proof_unreceived, + proof_height: raw_msg.proof_height.into_option().map(|height| Height { + revision_number: height.revision_number, + revision_height: height.revision_height, + }), + signer: raw_msg.signer, + }), + } + } fn try_parse_ibc_recv_packet(bytes: &[u8]) -> Result { use proto::ibc::tx::MsgRecvPacket; @@ -763,6 +799,7 @@ impl CosmosSdkMsg { | CosmosSdkMsg::MsgInstantiateContract { sender, .. } => Some(sender), CosmosSdkMsg::MsgRecvPacket { .. } => None, CosmosSdkMsg::MsgAcknowledgement { .. } => None, + CosmosSdkMsg::MsgTimeout { .. } => None, CosmosSdkMsg::Other => None, } } diff --git a/cosmwasm/enclaves/shared/crypto/src/key_manager.rs b/cosmwasm/enclaves/shared/crypto/src/key_manager.rs index 6a34b5fb6..47e31b429 100644 --- a/cosmwasm/enclaves/shared/crypto/src/key_manager.rs +++ b/cosmwasm/enclaves/shared/crypto/src/key_manager.rs @@ -416,29 +416,21 @@ impl Keychain { #[cfg(feature = "random")] { - let rek = self - .consensus_seed - .unwrap() - .current - .derive_key_from_this(&RANDOMNESS_ENCRYPTION_KEY_SECRET_DERIVE_ORDER.to_be_bytes()); - - let irs = self - .consensus_seed - .unwrap() - .current - .derive_key_from_this(&INITIAL_RANDOMNESS_SEED_SECRET_DERIVE_ORDER.to_be_bytes()); + let rek = + self.consensus_seed.unwrap().current.derive_key_from_this( + &RANDOMNESS_ENCRYPTION_KEY_SECRET_DERIVE_ORDER.to_be_bytes(), + ); + + let irs = + self.consensus_seed.unwrap().current.derive_key_from_this( + &INITIAL_RANDOMNESS_SEED_SECRET_DERIVE_ORDER.to_be_bytes(), + ); self.initial_randomness_seed = Some(irs); self.random_encryption_key = Some(rek); - trace!( - "initial_randomness_seed: {:?}", - hex::encode(irs.get()) - ); - trace!( - "random_encryption_key: {:?}", - hex::encode(rek.get()) - ); + trace!("initial_randomness_seed: {:?}", hex::encode(irs.get())); + trace!("random_encryption_key: {:?}", hex::encode(rek.get())); self.write_randomness_keys(); } diff --git a/cosmwasm/enclaves/shared/utils/src/lib.rs b/cosmwasm/enclaves/shared/utils/src/lib.rs index 54291388c..63449a329 100644 --- a/cosmwasm/enclaves/shared/utils/src/lib.rs +++ b/cosmwasm/enclaves/shared/utils/src/lib.rs @@ -15,5 +15,5 @@ pub mod pointers; pub mod recursion_depth; mod results; pub mod storage; -pub mod validator_set; pub mod tx_bytes; +pub mod validator_set; diff --git a/cosmwasm/enclaves/shared/utils/src/tx_bytes.rs b/cosmwasm/enclaves/shared/utils/src/tx_bytes.rs index 9f3a291a3..3b1dae985 100644 --- a/cosmwasm/enclaves/shared/utils/src/tx_bytes.rs +++ b/cosmwasm/enclaves/shared/utils/src/tx_bytes.rs @@ -10,10 +10,10 @@ fn path_from_env(file_name: &str) -> String { path::Path::new( &env::var(SCRT_SGX_STORAGE_ENV_VAR).unwrap_or_else(|_| DEFAULT_SGX_SECRET_PATH.to_string()), ) - .join(file_name) - .to_str() - .unwrap_or(DEFAULT_SGX_SECRET_PATH) - .to_string() + .join(file_name) + .to_str() + .unwrap_or(DEFAULT_SGX_SECRET_PATH) + .to_string() } lazy_static::lazy_static! { @@ -30,15 +30,13 @@ pub struct TxBytesForHeight { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Tx { - pub tx: Vec + pub tx: Vec, } impl TxBytesForHeight { pub fn unseal() -> SgxResult { - let val_set_from_storage: Self = serde_json::from_slice( - unseal(&TX_BYTES_SEALING_PATH)?.as_slice(), - ) - .map_err(|e| { + let val_set_from_storage: Self = + serde_json::from_slice(unseal(&TX_BYTES_SEALING_PATH)?.as_slice()).map_err(|e| { error!("Error decoding tx bytes from json {:?}", e); sgx_status_t::SGX_ERROR_UNEXPECTED })?; diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index b7043be45..198d3ad51 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -2454,16 +2454,210 @@ func TestIBCHooksIncomingTransfer(t *testing.T) { func TestIBCHooksOutgoingTransferAck(t *testing.T) { for _, test := range []struct { - name string - sdkMsgSrcPort string - sdkMsgSrcChannel string - sdkMsgDestPort string - sdkMsgDestChannel string - sdkMsgAck string - wasmInputSrcChannel string - wasmInputAck string - wasmInputCoin sdk.Coins - err string + name string + sdkMsgSrcPort string + sdkMsgSrcChannel string + sdkMsgDestPort string + sdkMsgDestChannel string + sdkMsgAck string + wasmInputSrcChannel string + wasmInputAck string + wasmInputCoin sdk.Coins + ics20PacketSender string + ics20PacketMemoSender string + err string + }{ + { + name: "happy path", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: "blabla", + wasmInputSrcChannel: "channel-0", + wasmInputAck: "blabla", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "", + ics20PacketMemoSender: "", + err: "", + }, + { + name: "contract address mismatch", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: "blabla", + wasmInputSrcChannel: "channel-0", + wasmInputAck: "blabla", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", + ics20PacketMemoSender: "", + err: "failed to verify transaction", + }, + { + name: "contract address mismatch 2", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: "blabla", + wasmInputSrcChannel: "channel-0", + wasmInputAck: "blabla", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "", + ics20PacketMemoSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", + err: "failed to verify transaction", + }, + { + name: "contract address mismatch 3", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: "blabla", + wasmInputSrcChannel: "channel-0", + wasmInputAck: "blabla", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "secret19e75l25r6sa6nhdf4lggjmgpw0vmpfvsw5cnpe", + ics20PacketMemoSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", + err: "failed to verify transaction", + }, + { + name: "channel mismatch", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: "blabla", + wasmInputSrcChannel: "channel-1", + wasmInputAck: "blabla", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "", + ics20PacketMemoSender: "", + err: "failed to verify transaction", + }, + { + name: "no coins should be sent", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: "blabla", + wasmInputSrcChannel: "channel-0", + wasmInputAck: "blabla", + wasmInputCoin: sdk.NewCoins(sdk.NewInt64Coin("denom", 1)), + ics20PacketSender: "", + ics20PacketMemoSender: "", + err: "failed to verify transaction", + }, + { + name: "ack mismatch", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + sdkMsgAck: "yadayada", + wasmInputSrcChannel: "channel-0", + wasmInputAck: "blabla", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "", + ics20PacketMemoSender: "", + err: "failed to verify transaction", + }, + } { + t.Run(test.name, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) + require.Empty(t, initErr) + + testIcs20PacketSender := test.ics20PacketSender + if testIcs20PacketSender == "" { + testIcs20PacketSender = contractAddress.String() + } + + testIcs20PacketMemoSender := test.ics20PacketMemoSender + if testIcs20PacketMemoSender == "" { + testIcs20PacketMemoSender = contractAddress.String() + } + + data := ibctransfertypes.FungibleTokenPacketData{ + Denom: "ignored", + Amount: "1", + Sender: testIcs20PacketSender, // must be the contract address, like in the memo + Receiver: "ignored", + Memo: fmt.Sprintf(`{"ibc_callback":"%s"}`, testIcs20PacketMemoSender), + } + dataBytes, err := json.Marshal(data) + require.NoError(t, err) + + sdkMsg := ibcchanneltypes.MsgAcknowledgement{ + Packet: ibcchanneltypes.Packet{ + Sequence: 0, + SourcePort: test.sdkMsgSrcPort, // port on Secret + SourceChannel: test.sdkMsgSrcChannel, // channel on Secret + DestinationPort: test.sdkMsgDestPort, // port on the other chain + DestinationChannel: test.sdkMsgDestChannel, // channel on the other chain + Data: dataBytes, + TimeoutHeight: ibcclienttypes.Height{}, + TimeoutTimestamp: 0, + }, + Acknowledgement: []byte(test.sdkMsgAck), + ProofAcked: []byte{}, + ProofHeight: ibcclienttypes.Height{}, + Signer: walletA.String(), + } + + ctx = PrepareSignedTx(t, keeper, ctx, walletA, privKeyA, &sdkMsg) + + _, execErr := keeper.Execute(ctx, + contractAddress, + walletA, + []byte( + fmt.Sprintf(`{"ibc_lifecycle_complete":{"ibc_ack":{"channel":"%s","sequence":0,"ack":"%s","success":true}}}`, + test.wasmInputSrcChannel, + test.wasmInputAck, + )), + test.wasmInputCoin, + nil, + cosmwasm.HandleTypeIbcWasmHooksOutgoingTransferAck, + ) + + if test.err == "" { + require.Empty(t, execErr) + events := tryDecryptWasmEvents(ctx, nil) + requireEvents(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "ibc_lifecycle_complete.ibc_ack.channel", Value: test.sdkMsgSrcChannel}, + {Key: "ibc_lifecycle_complete.ibc_ack.sequence", Value: "0"}, + {Key: "ibc_lifecycle_complete.ibc_ack.ack", Value: test.sdkMsgAck}, + {Key: "ibc_lifecycle_complete.ibc_ack.success", Value: "true"}, + }, + }, + events, + ) + } else { + require.Contains(t, execErr.Error(), test.err) + } + }) + } +} + +func TestIBCHooksOutgoingTransferTimeout(t *testing.T) { + for _, test := range []struct { + name string + sdkMsgSrcPort string + sdkMsgSrcChannel string + sdkMsgDestPort string + sdkMsgDestChannel string + wasmInputSrcChannel string + wasmInputCoin sdk.Coins + ics20PacketSender string + ics20PacketMemoSender string + err string }{ { name: "happy path", @@ -2471,21 +2665,53 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { sdkMsgSrcChannel: "channel-0", sdkMsgDestPort: "transfer", sdkMsgDestChannel: "channel-1", - sdkMsgAck: "blabla", wasmInputSrcChannel: "channel-0", - wasmInputAck: "blabla", wasmInputCoin: sdk.NewCoins(), err: "", }, + { + name: "contract address mismatch", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + wasmInputSrcChannel: "channel-0", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", + ics20PacketMemoSender: "", + err: "failed to verify transaction", + }, + { + name: "contract address mismatch 2", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + wasmInputSrcChannel: "channel-0", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "", + ics20PacketMemoSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", + err: "failed to verify transaction", + }, + { + name: "contract address mismatch 3", + sdkMsgSrcPort: "transfer", + sdkMsgSrcChannel: "channel-0", + sdkMsgDestPort: "transfer", + sdkMsgDestChannel: "channel-1", + wasmInputSrcChannel: "channel-0", + wasmInputCoin: sdk.NewCoins(), + ics20PacketSender: "secret19e75l25r6sa6nhdf4lggjmgpw0vmpfvsw5cnpe", + ics20PacketMemoSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", + err: "failed to verify transaction", + }, { name: "channel mismatch", sdkMsgSrcPort: "transfer", sdkMsgSrcChannel: "channel-0", sdkMsgDestPort: "transfer", sdkMsgDestChannel: "channel-1", - sdkMsgAck: "blabla", wasmInputSrcChannel: "channel-1", - wasmInputAck: "blabla", wasmInputCoin: sdk.NewCoins(), err: "failed to verify transaction", }, @@ -2495,24 +2721,10 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { sdkMsgSrcChannel: "channel-0", sdkMsgDestPort: "transfer", sdkMsgDestChannel: "channel-1", - sdkMsgAck: "blabla", wasmInputSrcChannel: "channel-0", - wasmInputAck: "blabla", wasmInputCoin: sdk.NewCoins(sdk.NewInt64Coin("denom", 1)), err: "failed to verify transaction", }, - { - name: "ack mismatch", - sdkMsgSrcPort: "transfer", - sdkMsgSrcChannel: "channel-0", - sdkMsgDestPort: "transfer", - sdkMsgDestChannel: "channel-1", - sdkMsgAck: "yadayada", - wasmInputSrcChannel: "channel-0", - wasmInputAck: "blabla", - wasmInputCoin: sdk.NewCoins(), - err: "failed to verify transaction", - }, } { t.Run(test.name, func(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, TestContractPaths[v1Contract], sdk.NewCoins()) @@ -2520,17 +2732,27 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, true, defaultGasForTests) require.Empty(t, initErr) + testIcs20PacketSender := test.ics20PacketSender + if testIcs20PacketSender == "" { + testIcs20PacketSender = contractAddress.String() + } + + testIcs20PacketMemoSender := test.ics20PacketMemoSender + if testIcs20PacketMemoSender == "" { + testIcs20PacketMemoSender = contractAddress.String() + } + data := ibctransfertypes.FungibleTokenPacketData{ Denom: "ignored", Amount: "1", - Sender: contractAddress.String(), // must be the contract address, like in the memo + Sender: testIcs20PacketSender, // must be the contract address, like in the memo Receiver: "ignored", - Memo: fmt.Sprintf(`{"ibc_callback":"%s"}`, contractAddress.String()), + Memo: fmt.Sprintf(`{"ibc_callback":"%s"}`, testIcs20PacketMemoSender), } dataBytes, err := json.Marshal(data) require.NoError(t, err) - sdkMsg := ibcchanneltypes.MsgAcknowledgement{ + sdkMsg := ibcchanneltypes.MsgTimeout{ Packet: ibcchanneltypes.Packet{ Sequence: 0, SourcePort: test.sdkMsgSrcPort, // port on Secret @@ -2541,8 +2763,7 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { TimeoutHeight: ibcclienttypes.Height{}, TimeoutTimestamp: 0, }, - Acknowledgement: []byte(test.sdkMsgAck), - ProofAcked: []byte{}, + ProofUnreceived: []byte{}, ProofHeight: ibcclienttypes.Height{}, Signer: walletA.String(), } @@ -2553,13 +2774,12 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { contractAddress, walletA, []byte( - fmt.Sprintf(`{"ibc_lifecycle_complete":{"ibc_ack":{"channel":"%s","sequence":0,"ack":"%s","success":true}}}`, + fmt.Sprintf(`{"ibc_lifecycle_complete":{"ibc_timeout":{"channel":"%s","sequence":0}}}`, test.wasmInputSrcChannel, - test.wasmInputAck, )), test.wasmInputCoin, nil, - cosmwasm.HandleTypeIbcWasmHooksOutgoingTransferAck, + cosmwasm.HandleTypeIbcWasmHooksOutgoingTransferTimeout, ) if test.err == "" { @@ -2569,10 +2789,8 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { []ContractEvent{ { {Key: "contract_address", Value: contractAddress.String()}, - {Key: "ibc_lifecycle_complete.ibc_ack.channel", Value: test.sdkMsgSrcChannel}, - {Key: "ibc_lifecycle_complete.ibc_ack.sequence", Value: "0"}, - {Key: "ibc_lifecycle_complete.ibc_ack.ack", Value: test.sdkMsgAck}, - {Key: "ibc_lifecycle_complete.ibc_ack.success", Value: "true"}, + {Key: "ibc_lifecycle_complete.ibc_timeout.channel", Value: test.sdkMsgSrcChannel}, + {Key: "ibc_lifecycle_complete.ibc_timeout.sequence", Value: "0"}, }, }, events, From 91804a34e345eb432e097ff84d65937fff3eb673 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 28 May 2023 22:20:32 +0300 Subject: [PATCH 33/54] Clippy --- .../shared/contract-engine/src/contract_operations.rs | 4 ++-- .../shared/contract-engine/src/contract_validation.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 1d58d86ab..116876556 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -295,7 +295,7 @@ pub fn handle( msg, should_validate_sig_info, should_validate_input, - parsed_handle_type.clone(), + parsed_handle_type, )?; let mut validated_msg = decrypted_msg.clone(); @@ -305,7 +305,7 @@ pub fn handle( &decrypted_msg, &contract_hash, data_for_validation, - Some(parsed_handle_type.clone()), + Some(parsed_handle_type), )?; validated_msg = x.validated_msg; reply_params = x.reply_params; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index b268b526d..66e3d79c0 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -208,7 +208,7 @@ pub fn validate_msg( ) -> Result { match handle_type { None => validate_basic_msg(msg, contract_hash, data_for_validation), - Some(h) => match is_ibc_msg(h.clone()) { + Some(h) => match is_ibc_msg(h) { false => validate_basic_msg(msg, contract_hash, data_for_validation), true => validate_ibc_msg(msg, contract_hash, data_for_validation, h), }, @@ -746,7 +746,7 @@ fn verify_and_get_sdk_msg<'sd>( channel == packet.source_channel && sequence == packet.sequence && ack == String::from_utf8_lossy( acknowledgement) - && success == !is_transfer_ack_error(acknowledgement), + && success != is_transfer_ack_error(acknowledgement), IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCTimeout { .. }) => false, } }, From 4a32a921766ed66cdc09bca86e2730dd2af691cd Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 28 May 2023 22:51:14 +0300 Subject: [PATCH 34/54] Fix validation of HANDLE_TYPE_IBC_PACKET_{ACK,TIMEOUT} --- .../contract-engine/src/contract_validation.rs | 16 ++++++++-------- .../enclaves/shared/cosmos-types/src/types.rs | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 66e3d79c0..550575de2 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -729,9 +729,9 @@ fn verify_and_get_sdk_msg<'sd>( sent_msg_ack_msg.original_packet.dest.channel_id == packet.destination_channel && sent_msg_ack_msg.original_packet.dest.port_id == packet.destination_port && sent_msg_ack_msg.original_packet.sequence == packet.sequence && - sent_msg_ack_msg.original_packet.data == packet.data && + sent_msg_ack_msg.original_packet.data.0 == packet.data && sent_msg_ack_msg.relayer == *signer && - sent_msg_ack_msg.acknowledgement.data == *acknowledgement + sent_msg_ack_msg.acknowledgement.data.0 == *acknowledgement }, HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK => { let ibc_lifecycle_complete = serde_json::from_slice::(&sent_msg.msg); @@ -764,12 +764,12 @@ fn verify_and_get_sdk_msg<'sd>( } let sent_msg_timeout_msg= send_msg_timeout_msg.unwrap(); - sent_msg_timeout_msg.original_packet.src.channel_id == packet.source_channel && - sent_msg_timeout_msg.original_packet.src.port_id == packet.source_port && - sent_msg_timeout_msg.original_packet.dest.channel_id == packet.destination_channel && - sent_msg_timeout_msg.original_packet.dest.port_id == packet.destination_port && - sent_msg_timeout_msg.original_packet.sequence == packet.sequence && - sent_msg_timeout_msg.original_packet.data == packet.data && + sent_msg_timeout_msg.packet.src.channel_id == packet.source_channel && + sent_msg_timeout_msg.packet.src.port_id == packet.source_port && + sent_msg_timeout_msg.packet.dest.channel_id == packet.destination_channel && + sent_msg_timeout_msg.packet.dest.port_id == packet.destination_port && + sent_msg_timeout_msg.packet.sequence == packet.sequence && + sent_msg_timeout_msg.packet.data.0 == packet.data && sent_msg_timeout_msg.relayer == *signer }, HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT => { diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index ecdb526b7..1de468a4d 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -471,18 +471,18 @@ pub struct IBCPacketAckMsg { #[derive(Debug, Deserialize)] pub struct IBCAcknowledgement { - pub data: Vec, + pub data: Binary, } #[derive(Debug, Deserialize)] pub struct IBCPacketTimeoutMsg { - pub original_packet: IBCPacket, + pub packet: IBCPacket, pub relayer: String, } #[derive(Debug, Deserialize)] pub struct IBCPacket { - pub data: Vec, + pub data: Binary, pub src: IBCEndpoint, pub dest: IBCEndpoint, pub sequence: u64, @@ -498,7 +498,7 @@ pub struct IBCEndpoint { #[derive(Debug, Deserialize)] pub struct IBCTimeout { pub block: Option, - pub timestamp: Option, + pub timestamp: Option, } #[derive(Debug, Deserialize)] From d91cb2179be8f271c9088f01081ac041fbb829d5 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 30 May 2023 21:21:47 +0300 Subject: [PATCH 35/54] Refactor verify_params() --- .../src/contract_validation.rs | 139 +++++++++--------- 1 file changed, 66 insertions(+), 73 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 550575de2..03567fbd2 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -356,7 +356,6 @@ pub fn validate_basic_msg( }) } -/// Verify all the parameters sent to the enclave match up, and were signed by the right account. #[allow(clippy::too_many_arguments)] pub fn verify_params( sig_info: &SigInfo, @@ -372,96 +371,90 @@ pub fn verify_params( if should_validate_sig_info { debug!("Verifying message signatures for: {:?}", sig_info); - //let start = Instant::now(); - // If there's no callback signature - it's not a callback and there has to be a tx signer + signature if let Some(callback_sig) = &sig_info.callback_sig { return verify_callback_sig(callback_sig.as_slice(), sender, msg, sent_funds); } - // let duration = start.elapsed(); - // trace!( - // "verify_params: Time elapsed in verify_callback_sig: {:?}", - // duration - // ); + #[cfg(feature = "light-client-validation")] if !check_msg_matches_state(og_msg) { return Err(EnclaveError::ValidationFailure); } - // check if sign_bytes are in approved tx list - - trace!( - "Sign bytes are: {:?}", - String::from_utf8_lossy(sig_info.sign_bytes.as_slice()) - ); - - //let start = Instant::now(); - let sender_public_key = get_signer(sig_info, sender, handle_type)?; - // let duration = start.elapsed(); - // trace!( - // "verify_params: Time elapsed in get_signer_and_messages: {:?}", - // duration - // ); - trace!( - "sender canonical address is: {:?}", - sender_public_key.get_address().0 .0 - ); - trace!("sender signature is: {:?}", sig_info.signature); - trace!("sign bytes are: {:?}", sig_info.sign_bytes); - - //let start = Instant::now(); - sender_public_key - .verify_bytes( - sig_info.sign_bytes.as_slice(), - sig_info.signature.as_slice(), - sig_info.sign_mode, - ) - .map_err(|err| { - warn!("Signature verification failed: {:?}", err); - EnclaveError::FailedTxVerification - })?; - // let duration = start.elapsed(); - // trace!( - // "verify_params: Time elapsed in verify_bytes: {:?}", - // duration - // ); - - let signer_addr = sender_public_key.get_address(); - if &signer_addr != sender { - warn!("Sender verification failed!"); - trace!( - "Message sender {:?} does not match with the message signer {:?}", - sender, - signer_addr - ); - return Err(EnclaveError::FailedTxVerification); - } + verify_signature(sig_info, sender, handle_type)?; } if should_validate_input { - let messages = get_messages(sig_info, handle_type)?; - - // let start = Instant::now(); - let is_verified = verify_message_params( - &messages, - sender, + verify_input( + sig_info, sent_funds, + sender, contract_address, msg, handle_type, - ); - // let duration = start.elapsed(); - // trace!( - // "verify_params: Time elapsed in verify_message_params: {:?}", - // duration - // ); - - if !is_verified { - warn!("Parameter verification failed"); - return Err(EnclaveError::FailedTxVerification); - } + )?; } info!("Parameters verified successfully"); + + Ok(()) +} + +fn verify_signature( + sig_info: &SigInfo, + sender: &CanonicalAddr, + handle_type: HandleType, +) -> Result<(), EnclaveError> { + let sender_public_key = get_signer(sig_info, sender, handle_type)?; + + sender_public_key + .verify_bytes( + sig_info.sign_bytes.as_slice(), + sig_info.signature.as_slice(), + sig_info.sign_mode, + ) + .map_err(|err| { + warn!("Signature verification failed: {:?}", err); + EnclaveError::FailedTxVerification + })?; + + let signer_addr = sender_public_key.get_address(); + if &signer_addr != sender { + warn!("Sender verification failed!"); + trace!( + "Message sender {:?} does not match with the message signer {:?}", + sender, + signer_addr + ); + return Err(EnclaveError::FailedTxVerification); + } + + Ok(()) +} + +fn verify_input( + sig_info: &SigInfo, + sent_funds: &[Coin], + sender: &CanonicalAddr, + contract_address: &HumanAddr, + msg: &SecretMessage, + handle_type: HandleType, +) -> Result<(), EnclaveError> { + let messages = get_messages(sig_info, handle_type)?; + + let is_verified = verify_message_params( + &messages, + sender, + sent_funds, + contract_address, + msg, + handle_type, + ); + + if !is_verified { + warn!("Parameter verification failed"); + return Err(EnclaveError::FailedTxVerification); + } + Ok(()) } From b9e7c73eca0e49f77d5d9e6ecf117ca24d57c2e0 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 30 May 2023 21:25:26 +0300 Subject: [PATCH 36/54] Refactor some param names --- .../compute-tests/test-compute-contract/src/msg.rs | 2 +- .../contract-engine/src/contract_operations.rs | 8 ++++---- .../contract-engine/src/contract_validation.rs | 8 ++++---- .../shared/contract-engine/src/execute_message.rs | 8 ++++---- .../shared/contract-engine/src/ibc_message.rs | 14 +++++++------- .../shared/contract-engine/src/reply_message.rs | 8 ++++---- .../enclaves/shared/contract-engine/src/types.rs | 4 ++-- 7 files changed, 26 insertions(+), 26 deletions(-) diff --git a/cosmwasm/contracts/v1/compute-tests/test-compute-contract/src/msg.rs b/cosmwasm/contracts/v1/compute-tests/test-compute-contract/src/msg.rs index 48e151525..09415d242 100644 --- a/cosmwasm/contracts/v1/compute-tests/test-compute-contract/src/msg.rs +++ b/cosmwasm/contracts/v1/compute-tests/test-compute-contract/src/msg.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{Binary, Coin, Uint64}; +use cosmwasm_std::{Binary, Coin}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 116876556..eb0d4ace6 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -265,8 +265,8 @@ pub fn handle( trace!("Handle type is {:?}", parsed_handle_type); let ParsedMessage { - should_validate_sig_info, - should_validate_input, + should_verify_sig_info, + should_verify_input, was_msg_encrypted, should_encrypt_output, secret_msg, @@ -293,8 +293,8 @@ pub fn handle( &secret_msg, #[cfg(feature = "light-client-validation")] msg, - should_validate_sig_info, - should_validate_input, + should_verify_sig_info, + should_verify_input, parsed_handle_type, )?; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 03567fbd2..8112c559f 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -364,11 +364,11 @@ pub fn verify_params( contract_address: &HumanAddr, msg: &SecretMessage, #[cfg(feature = "light-client-validation")] og_msg: &[u8], - should_validate_sig_info: bool, - should_validate_input: bool, + should_verify_sig_info: bool, + should_verify_input: bool, handle_type: HandleType, ) -> Result<(), EnclaveError> { - if should_validate_sig_info { + if should_verify_sig_info { debug!("Verifying message signatures for: {:?}", sig_info); if let Some(callback_sig) = &sig_info.callback_sig { @@ -383,7 +383,7 @@ pub fn verify_params( verify_signature(sig_info, sender, handle_type)?; } - if should_validate_input { + if should_verify_input { verify_input( sig_info, sent_funds, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/execute_message.rs b/cosmwasm/enclaves/shared/contract-engine/src/execute_message.rs index a9f915930..fcb935fef 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/execute_message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/execute_message.rs @@ -11,8 +11,8 @@ pub fn parse_execute_message(message: &[u8]) -> Result Result Result { Ok(ParsedMessage { - should_validate_sig_info: false, - should_validate_input: false, + should_verify_sig_info: false, + should_verify_input: false, was_msg_encrypted: false, should_encrypt_output: false, secret_msg: SecretMessage { @@ -68,8 +68,8 @@ pub fn parse_ibc_receive_message(message: &[u8]) -> Result Result Result { Ok(ParsedMessage { - should_validate_sig_info: false, - should_validate_input: true, + should_verify_sig_info: false, + should_verify_input: true, was_msg_encrypted: false, should_encrypt_output: false, secret_msg: SecretMessage { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/reply_message.rs b/cosmwasm/enclaves/shared/contract-engine/src/reply_message.rs index dd9899d64..4ac633771 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/reply_message.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/reply_message.rs @@ -156,8 +156,8 @@ fn wrap_results_as_parsed_message( }; Ok(ParsedMessage { - should_validate_sig_info: true, - should_validate_input: true, + should_verify_sig_info: true, + should_verify_input: true, was_msg_encrypted: true, should_encrypt_output: true, secret_msg: reply_secret_msg, @@ -286,8 +286,8 @@ fn parse_plaintext_reply_message( // There's no msg.sender in reply, therefore we don't need to validate the sender. // It's also not possible to validate with our current design, since contracts // don't know if their output is a reply to another contract, thus can't sign it as such - should_validate_sig_info: false, - should_validate_input: false, + should_verify_sig_info: false, + should_verify_input: false, was_msg_encrypted: false, should_encrypt_output: parsed_reply.was_orig_msg_encrypted, secret_msg: reply_secret_msg, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/types.rs b/cosmwasm/enclaves/shared/contract-engine/src/types.rs index 4b333e81a..735156198 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/types.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/types.rs @@ -15,8 +15,8 @@ pub struct SecretMessage { } pub struct ParsedMessage { - pub should_validate_sig_info: bool, - pub should_validate_input: bool, + pub should_verify_sig_info: bool, + pub should_verify_input: bool, pub was_msg_encrypted: bool, pub should_encrypt_output: bool, pub secret_msg: SecretMessage, From d487b138c6ad4222217ca83664bcc9b6afc94cd8 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 30 May 2023 21:30:26 +0300 Subject: [PATCH 37/54] Refactor DenomTrace --- .../src/contract_validation.rs | 131 +----------------- .../contract-engine/src/ibc_denom_utils.rs | 130 +++++++++++++++++ .../shared/contract-engine/src/lib.rs | 1 + 3 files changed, 132 insertions(+), 130 deletions(-) create mode 100644 cosmwasm/enclaves/shared/contract-engine/src/ibc_denom_utils.rs diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index 8112c559f..be28c63ae 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -17,6 +17,7 @@ use enclave_crypto::traits::VerifyingKey; use enclave_crypto::{sha_256, AESKey, Hmac, Kdf, HASH_SIZE, KEY_MANAGER}; use enclave_ffi_types::EnclaveError; +use crate::ibc_denom_utils::{get_denom_prefix, parse_denom_trace, receiver_chain_is_source}; use crate::io::create_callback_signature; use crate::message::is_ibc_msg; use crate::types::SecretMessage; @@ -24,7 +25,6 @@ use crate::types::SecretMessage; #[cfg(feature = "light-client-validation")] use block_verifier::VERIFIED_MESSAGES; -use sha2::{Digest, Sha256}; extern crate hex; pub type ContractKey = [u8; CONTRACT_KEY_LENGTH]; @@ -1179,132 +1179,3 @@ fn verify_message_params( true } - -/// ReceiverChainIsSource returns true if the denomination originally came -/// from the receiving chain and false otherwise. -fn receiver_chain_is_source(source_port: &str, source_channel: &str, denom: &str) -> bool { - // The prefix passed in should contain the SourcePort and SourceChannel. - // If the receiver chain originally sent the token to the sender chain - // the denom will have the sender's SourcePort and SourceChannel as the - // prefix. - let voucher_prefix = get_denom_prefix(source_port, source_channel); - denom.starts_with(&voucher_prefix) -} - -/// GetDenomPrefix returns the receiving denomination prefix -fn get_denom_prefix(port_id: &str, channel_id: &str) -> String { - format!("{}/{}/", port_id, channel_id) -} - -/// DenomTrace contains the base denomination for ICS20 fungible tokens and the -/// source tracing information path. -struct DenomTrace { - /// path defines the chain of port/channel identifiers used for tracing the - /// source of the fungible token. - path: String, - /// base denomination of the relayed fungible token. - base_denom: String, -} - -impl DenomTrace { - /// Hash returns the hex bytes of the SHA256 hash of the DenomTrace fields using the following formula: - /// hash = sha256(tracePath + "/" + baseDenom) - pub fn hash(&self) -> Vec { - let hash = Sha256::digest(self.get_full_denom_path().as_bytes()); - hash.to_vec() - } - - /// IBCDenom a coin denomination for an ICS20 fungible token in the format - /// 'ibc/{hash(tracePath + baseDenom)}'. If the trace is empty, it will return the base denomination. - pub fn ibc_denom(&self) -> String { - if !self.path.is_empty() { - format!("ibc/{}", hex::encode(self.hash())) - } else { - self.base_denom.clone() - } - } - - /// GetFullDenomPath returns the full denomination according to the ICS20 specification: - /// tracePath + "/" + baseDenom - /// If there exists no trace then the base denomination is returned. - pub fn get_full_denom_path(&self) -> String { - if self.path.is_empty() { - self.base_denom.clone() - } else { - self.get_prefix() + &self.base_denom - } - } - - // GetPrefix returns the receiving denomination prefix composed by the trace info and a separator. - fn get_prefix(&self) -> String { - return format!("{}/", self.path); - } -} - -/// ParseDenomTrace parses a string with the ibc prefix (denom trace) and the base denomination -/// into a DenomTrace type. -/// -/// Examples: -/// -/// - "portidone/channel-0/uatom" => DenomTrace{Path: "portidone/channel-0", BaseDenom: "uatom"} -/// - "portidone/channel-0/portidtwo/channel-1/uatom" => DenomTrace{Path: "portidone/channel-0/portidtwo/channel-1", BaseDenom: "uatom"} -/// - "portidone/channel-0/gamm/pool/1" => DenomTrace{Path: "portidone/channel-0", BaseDenom: "gamm/pool/1"} -/// - "gamm/pool/1" => DenomTrace{Path: "", BaseDenom: "gamm/pool/1"} -/// - "uatom" => DenomTrace{Path: "", BaseDenom: "uatom"} -fn parse_denom_trace(raw_denom: &str) -> DenomTrace { - let denom_split: Vec<&str> = raw_denom.split('/').collect(); - - if denom_split.len() == 1 { - return DenomTrace { - path: "".to_string(), - base_denom: raw_denom.to_string(), - }; - } - - let (path, base_denom) = extract_path_and_base_from_full_denom(&denom_split); - - DenomTrace { path, base_denom } -} - -/// extract_path_and_base_from_full_denom returns the trace path and the base denom from -/// the elements that constitute the complete denom. -fn extract_path_and_base_from_full_denom(full_denom_items: &[&str]) -> (String, String) { - let mut path = vec![]; - let mut base_denom = vec![]; - - let length = full_denom_items.len(); - let mut i = 0; - - while i < length { - // The IBC specification does not guarantee the expected format of the - // destination port or destination channel identifier. A short term solution - // to determine base denomination is to expect the channel identifier to be the - // one ibc-go specifies. A longer term solution is to separate the path and base - // denomination in the ICS20 packet. If an intermediate hop prefixes the full denom - // with a channel identifier format different from our own, the base denomination - // will be incorrectly parsed, but the token will continue to be treated correctly - // as an IBC denomination. The hash used to store the token internally on our chain - // will be the same value as the base denomination being correctly parsed. - if i < length - 1 && length > 2 && is_valid_channel_id(full_denom_items[i + 1]) { - path.push(full_denom_items[i].to_owned()); - path.push(full_denom_items[i + 1].to_owned()); - i += 2; - } else { - base_denom = full_denom_items[i..].to_vec(); - break; - } - } - - (path.join("/"), base_denom.join("/")) -} - -/// IsValidChannelID checks if a channelID is valid and can be parsed to the channel -/// identifier format. -fn is_valid_channel_id(channel_id: &str) -> bool { - parse_channel_sequence(channel_id).is_some() -} - -/// ParseChannelSequence parses the channel sequence from the channel identifier. -fn parse_channel_sequence(channel_id: &str) -> Option<&str> { - channel_id.strip_prefix("channel-") -} diff --git a/cosmwasm/enclaves/shared/contract-engine/src/ibc_denom_utils.rs b/cosmwasm/enclaves/shared/contract-engine/src/ibc_denom_utils.rs new file mode 100644 index 000000000..a3bfc5f5e --- /dev/null +++ b/cosmwasm/enclaves/shared/contract-engine/src/ibc_denom_utils.rs @@ -0,0 +1,130 @@ +use sha2::{Digest, Sha256}; + +/// ReceiverChainIsSource returns true if the denomination originally came +/// from the receiving chain and false otherwise. +pub fn receiver_chain_is_source(source_port: &str, source_channel: &str, denom: &str) -> bool { + // The prefix passed in should contain the SourcePort and SourceChannel. + // If the receiver chain originally sent the token to the sender chain + // the denom will have the sender's SourcePort and SourceChannel as the + // prefix. + let voucher_prefix = get_denom_prefix(source_port, source_channel); + denom.starts_with(&voucher_prefix) +} + +/// GetDenomPrefix returns the receiving denomination prefix +pub fn get_denom_prefix(port_id: &str, channel_id: &str) -> String { + format!("{}/{}/", port_id, channel_id) +} + +/// DenomTrace contains the base denomination for ICS20 fungible tokens and the +/// source tracing information path. +pub struct DenomTrace { + /// path defines the chain of port/channel identifiers used for tracing the + /// source of the fungible token. + pub path: String, + /// base denomination of the relayed fungible token. + pub base_denom: String, +} + +impl DenomTrace { + /// Hash returns the hex bytes of the SHA256 hash of the DenomTrace fields using the following formula: + /// hash = sha256(tracePath + "/" + baseDenom) + pub fn hash(&self) -> Vec { + let hash = Sha256::digest(self.get_full_denom_path().as_bytes()); + hash.to_vec() + } + + /// IBCDenom a coin denomination for an ICS20 fungible token in the format + /// 'ibc/{hash(tracePath + baseDenom)}'. If the trace is empty, it will return the base denomination. + pub fn ibc_denom(&self) -> String { + if !self.path.is_empty() { + format!("ibc/{}", hex::encode(self.hash())) + } else { + self.base_denom.clone() + } + } + + /// GetFullDenomPath returns the full denomination according to the ICS20 specification: + /// tracePath + "/" + baseDenom + /// If there exists no trace then the base denomination is returned. + pub fn get_full_denom_path(&self) -> String { + if self.path.is_empty() { + self.base_denom.clone() + } else { + self.get_prefix() + &self.base_denom + } + } + + // GetPrefix returns the receiving denomination prefix composed by the trace info and a separator. + pub fn get_prefix(&self) -> String { + return format!("{}/", self.path); + } +} + +/// ParseDenomTrace parses a string with the ibc prefix (denom trace) and the base denomination +/// into a DenomTrace type. +/// +/// Examples: +/// +/// - "portidone/channel-0/uatom" => DenomTrace{Path: "portidone/channel-0", BaseDenom: "uatom"} +/// - "portidone/channel-0/portidtwo/channel-1/uatom" => DenomTrace{Path: "portidone/channel-0/portidtwo/channel-1", BaseDenom: "uatom"} +/// - "portidone/channel-0/gamm/pool/1" => DenomTrace{Path: "portidone/channel-0", BaseDenom: "gamm/pool/1"} +/// - "gamm/pool/1" => DenomTrace{Path: "", BaseDenom: "gamm/pool/1"} +/// - "uatom" => DenomTrace{Path: "", BaseDenom: "uatom"} +pub fn parse_denom_trace(raw_denom: &str) -> DenomTrace { + let denom_split: Vec<&str> = raw_denom.split('/').collect(); + + if denom_split.len() == 1 { + return DenomTrace { + path: "".to_string(), + base_denom: raw_denom.to_string(), + }; + } + + let (path, base_denom) = extract_path_and_base_from_full_denom(&denom_split); + + DenomTrace { path, base_denom } +} + +/// extract_path_and_base_from_full_denom returns the trace path and the base denom from +/// the elements that constitute the complete denom. +pub fn extract_path_and_base_from_full_denom(full_denom_items: &[&str]) -> (String, String) { + let mut path = vec![]; + let mut base_denom = vec![]; + + let length = full_denom_items.len(); + let mut i = 0; + + while i < length { + // The IBC specification does not guarantee the expected format of the + // destination port or destination channel identifier. A short term solution + // to determine base denomination is to expect the channel identifier to be the + // one ibc-go specifies. A longer term solution is to separate the path and base + // denomination in the ICS20 packet. If an intermediate hop prefixes the full denom + // with a channel identifier format different from our own, the base denomination + // will be incorrectly parsed, but the token will continue to be treated correctly + // as an IBC denomination. The hash used to store the token internally on our chain + // will be the same value as the base denomination being correctly parsed. + if i < length - 1 && length > 2 && is_valid_channel_id(full_denom_items[i + 1]) { + path.push(full_denom_items[i].to_owned()); + path.push(full_denom_items[i + 1].to_owned()); + i += 2; + } else { + base_denom = full_denom_items[i..].to_vec(); + break; + } + } + + (path.join("/"), base_denom.join("/")) +} + +/// IsValidChannelID checks if a channelID is valid and can be parsed to the channel +/// identifier format. +pub fn is_valid_channel_id(channel_id: &str) -> bool { + parse_channel_sequence(channel_id).is_some() +} + +/// ParseChannelSequence parses the channel sequence from the channel identifier. +pub fn parse_channel_sequence(channel_id: &str) -> Option<&str> { + channel_id.strip_prefix("channel-") +} diff --git a/cosmwasm/enclaves/shared/contract-engine/src/lib.rs b/cosmwasm/enclaves/shared/contract-engine/src/lib.rs index c7bbe6905..2be3cb4c7 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/lib.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/lib.rs @@ -15,6 +15,7 @@ mod errors; mod execute_message; pub mod external; mod gas; +mod ibc_denom_utils; mod ibc_message; mod io; mod message; From c3addbc8bc4cd04e4a5d3ca102dfe4ba00567d63 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 30 May 2023 22:46:04 +0300 Subject: [PATCH 38/54] Refactor input verification code --- .../src/contract_validation.rs | 513 +----------------- .../contract_address_validation.rs | 217 ++++++++ .../src/input_validation/mod.rs | 4 + .../src/input_validation/msg_validation.rs | 215 ++++++++ .../send_funds_validations.rs | 136 +++++ .../src/input_validation/sender_validation.rs | 27 + .../shared/contract-engine/src/lib.rs | 1 + 7 files changed, 607 insertions(+), 506 deletions(-) create mode 100644 cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs create mode 100644 cosmwasm/enclaves/shared/contract-engine/src/input_validation/mod.rs create mode 100644 cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs create mode 100644 cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs create mode 100644 cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index be28c63ae..7dd7757a5 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -8,16 +8,16 @@ use cw_types_generic::BaseEnv; use cw_types_v010::types::{CanonicalAddr, Coin, HumanAddr}; use enclave_cosmos_types::traits::CosmosAminoPubkey; use enclave_cosmos_types::types::{ - is_transfer_ack_error, ContractCode, CosmosPubKey, CosmosSdkMsg, FungibleTokenPacketData, - HandleType, IBCLifecycleComplete, IBCLifecycleCompleteOptions, IBCPacketAckMsg, - IBCPacketTimeoutMsg, IbcHooksIncomingTransferMsg, IbcHooksOutgoingTransferMemo, Packet, - SigInfo, SignDoc, StdSignDoc, + ContractCode, CosmosPubKey, CosmosSdkMsg, HandleType, SigInfo, SignDoc, StdSignDoc, }; use enclave_crypto::traits::VerifyingKey; use enclave_crypto::{sha_256, AESKey, Hmac, Kdf, HASH_SIZE, KEY_MANAGER}; use enclave_ffi_types::EnclaveError; -use crate::ibc_denom_utils::{get_denom_prefix, parse_denom_trace, receiver_chain_is_source}; +use crate::input_validation::contract_address_validation::verify_contract_address; +use crate::input_validation::msg_validation::verify_and_get_sdk_msg; +use crate::input_validation::send_funds_validations::verify_sent_funds; +use crate::input_validation::sender_validation::verify_sender; use crate::io::create_callback_signature; use crate::message::is_ibc_msg; use crate::types::SecretMessage; @@ -637,489 +637,6 @@ fn verify_callback_sig_impl( true } -/// Get the cosmwasm message that contains the encrypted message -fn verify_and_get_sdk_msg<'sd>( - messages: &'sd [CosmosSdkMsg], - msg_sender: &CanonicalAddr, - sent_msg: &SecretMessage, - handle_type: HandleType, -) -> Option<&'sd CosmosSdkMsg> { - trace!("get_verified_msg: {:?}", messages); - - messages.iter().find(|&m| match m { - CosmosSdkMsg::MsgExecuteContract { msg, sender, .. } - | CosmosSdkMsg::MsgInstantiateContract { - init_msg: msg, - sender, - .. - } => msg_sender == sender && &sent_msg.to_vec() == msg, - CosmosSdkMsg::MsgRecvPacket { - packet: Packet { - sequence, - source_port, - source_channel, - destination_port, - destination_channel, - data, - }, .. - } => match handle_type { - HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => { - let parsed_sent_msg = serde_json::from_slice::(&sent_msg.msg); - if parsed_sent_msg.is_err() { - trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_RECEIVE: sent_msg.msg cannot be parsed as IbcPacketReceiveMsg: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), parsed_sent_msg.err()); - - trace!("Checking if sent_msg & data are encrypted"); - return &sent_msg.to_vec() == data; - } - let parsed = parsed_sent_msg.unwrap(); - - parsed.packet.data.as_slice() == data.as_slice() - && parsed.packet.sequence == *sequence - && parsed.packet.src.port_id == *source_port - && parsed.packet.src.channel_id == *source_channel - && parsed.packet.dest.port_id == *destination_port - && parsed.packet.dest.channel_id == *destination_channel - // TODO check timeout too? sequence + destination_channel + data should be enough - } - HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { - let fungible_token_packet_data = serde_json::from_slice::(data); - if fungible_token_packet_data.is_err(){ - trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: data cannot be parsed as FungibleTokenPacketData: {:?} Error: {:?}", String::from_utf8_lossy(data), fungible_token_packet_data.err()); - return false; - } - let fungible_token_packet_data= fungible_token_packet_data.unwrap(); - - - let ibc_hooks_incoming_transfer_msg = serde_json::from_slice::(fungible_token_packet_data.memo.clone().unwrap_or_else(|| "".to_string()).as_bytes()); - if ibc_hooks_incoming_transfer_msg.is_err(){ - trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: fungible_token_packet_data.memo cannot be parsed as IbcHooksIncomingTransferMsg: {:?} Error: {:?}", fungible_token_packet_data.memo, ibc_hooks_incoming_transfer_msg.err()); - return false; - } - let ibc_hooks_incoming_transfer_msg = ibc_hooks_incoming_transfer_msg.unwrap(); - let sent_msg_value = serde_json::from_slice::(&sent_msg.msg); - if sent_msg_value.is_err(){ - trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: sent_msg.msg cannot be parsed as serde_json::Value: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), sent_msg_value.err()); - return false; - } - - ibc_hooks_incoming_transfer_msg.wasm.msg == sent_msg_value.unwrap() - } - _ => false, - }, - CosmosSdkMsg::Other => false, - CosmosSdkMsg::MsgAcknowledgement { packet, acknowledgement, signer,.. } => { - match handle_type { - HandleType::HANDLE_TYPE_IBC_PACKET_ACK => { - let send_msg_ack_msg = serde_json::from_slice::(&sent_msg.msg); - if send_msg_ack_msg.is_err(){ - trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_ACK: sent_msg.msg cannot be parsed as IBCPacketAckMsg: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), send_msg_ack_msg.err()); - return false; - } - let sent_msg_ack_msg= send_msg_ack_msg.unwrap(); - - sent_msg_ack_msg.original_packet.src.channel_id == packet.source_channel && - sent_msg_ack_msg.original_packet.src.port_id == packet.source_port && - sent_msg_ack_msg.original_packet.dest.channel_id == packet.destination_channel && - sent_msg_ack_msg.original_packet.dest.port_id == packet.destination_port && - sent_msg_ack_msg.original_packet.sequence == packet.sequence && - sent_msg_ack_msg.original_packet.data.0 == packet.data && - sent_msg_ack_msg.relayer == *signer && - sent_msg_ack_msg.acknowledgement.data.0 == *acknowledgement - }, - HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK => { - let ibc_lifecycle_complete = serde_json::from_slice::(&sent_msg.msg); - if ibc_lifecycle_complete.is_err(){ - trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK: sent_msg.msg cannot be parsed as IBCLifecycleComplete: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), ibc_lifecycle_complete.err()); - return false; - } - let ibc_lifecycle_complete= ibc_lifecycle_complete.unwrap(); - - match ibc_lifecycle_complete { - IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCAck { channel, sequence, ack, success }) => - channel == packet.source_channel - && sequence == packet.sequence - && ack == String::from_utf8_lossy( acknowledgement) - && success != is_transfer_ack_error(acknowledgement), - IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCTimeout { .. }) => false, - } - }, - _ => false, - - } - }, - CosmosSdkMsg::MsgTimeout { packet, signer,.. } => { - match handle_type { - HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => { - let send_msg_timeout_msg = serde_json::from_slice::(&sent_msg.msg); - if send_msg_timeout_msg.is_err(){ - trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_TIMEOUT: sent_msg.msg cannot be parsed as IBCPacketTimeoutMsg: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), send_msg_timeout_msg.err()); - return false; - } - let sent_msg_timeout_msg= send_msg_timeout_msg.unwrap(); - - sent_msg_timeout_msg.packet.src.channel_id == packet.source_channel && - sent_msg_timeout_msg.packet.src.port_id == packet.source_port && - sent_msg_timeout_msg.packet.dest.channel_id == packet.destination_channel && - sent_msg_timeout_msg.packet.dest.port_id == packet.destination_port && - sent_msg_timeout_msg.packet.sequence == packet.sequence && - sent_msg_timeout_msg.packet.data.0 == packet.data && - sent_msg_timeout_msg.relayer == *signer - }, - HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT => { - let ibc_lifecycle_complete = serde_json::from_slice::(&sent_msg.msg); - if ibc_lifecycle_complete.is_err(){ - trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT: sent_msg.msg cannot be parsed as IBCLifecycleComplete: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), ibc_lifecycle_complete.err()); - return false; - } - let ibc_lifecycle_complete= ibc_lifecycle_complete.unwrap(); - - match ibc_lifecycle_complete { - IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCAck {..}) => false , - IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCTimeout { channel, sequence }) => - channel == packet.source_channel - && sequence == packet.sequence, - } - }, - _ => false, - - } - }, - }) -} - -/// Check that the contract listed in the cosmwasm message matches the one in env -fn verify_contract_address(msg: &CosmosSdkMsg, contract_address: &HumanAddr) -> bool { - // Contract address is relevant only to execute, since during sending an instantiate message the contract address is not yet known - match msg { - CosmosSdkMsg::MsgExecuteContract { contract, .. } => { - info!("Verifying contract address.."); - let is_verified = contract_address == contract; - if !is_verified { - trace!( - "Contract address sent to enclave {:?} is not the same as the signed one {:?}", - contract_address, - *contract - ); - } - is_verified - } - CosmosSdkMsg::MsgInstantiateContract { .. } => true, - CosmosSdkMsg::Other => false, - CosmosSdkMsg::MsgRecvPacket { - packet: - Packet { - destination_port, - data, - .. - }, - .. - } => { - if destination_port == "transfer" { - // Packet was routed here through ibc-hooks - - // Parse data as FungibleTokenPacketData JSON - let packet_data: FungibleTokenPacketData = match serde_json::from_slice( - data.as_slice(), - ) { - Ok(packet_data) => packet_data, - Err(err) => { - trace!( - "Contract was called via ibc-hooks but packet_data cannot be parsed as FungibleTokenPacketData: {:?} Error: {:?}", - String::from_utf8_lossy(data.as_slice()), - err, - ); - return false; - } - }; - - // memo must be set in ibc-hooks - let memo = match packet_data.memo { - Some(memo) => memo, - None => { - trace!("Contract was called via ibc-hooks but packet_data.memo is empty"); - return false; - } - }; - - // Parse data.memo as IbcHooksWasmMsg JSON - let wasm_msg: IbcHooksIncomingTransferMsg = match serde_json::from_slice( - memo.as_bytes(), - ) { - Ok(wasm_msg) => wasm_msg, - Err(err) => { - trace!( - "Contract was called via ibc-hooks but packet_data.memo cannot be parsed as IbcHooksWasmMsg: {:?} Error: {:?}", - memo, - err, - ); - return false; - } - }; - - // In ibc-hooks contract_address == packet_data.memo.wasm.contract == packet_data.receiver - let is_verified = *contract_address == packet_data.receiver - && *contract_address == wasm_msg.wasm.contract; - if !is_verified { - trace!( - "Contract address sent to enclave {:?} is not the same as in ibc-hooks packet receiver={:?} memo={:?}", - contract_address, - packet_data.receiver, - wasm_msg.wasm.contract - ); - } - is_verified - } else { - // Packet is for an IBC enabled contract - // destination_port is of the form "wasm.{contract_address}" - - // Extract contract_address from destination_port - // This also checks that destination_port starts with "wasm." - let contract_address_from_port = match destination_port.strip_prefix("wasm.") { - Some(contract_address) => contract_address, - None => { - trace!( - "IBC-enabled Contract was called via MsgRecvPacket but destination_port doesn't start with \"wasm.\": {:?}", - destination_port, - ); - return false; - } - }; - - let is_verified = *contract_address == HumanAddr::from(contract_address_from_port); - if !is_verified { - trace!( - "IBC-enabled Contract address sent to enclave {:?} is not the same as extracted from MsgRecvPacket but destination_port: {:?}", - contract_address, - contract_address_from_port, - ); - } - is_verified - } - } - CosmosSdkMsg::MsgAcknowledgement { - packet: Packet { - source_port, data, .. - }, - .. - } - | CosmosSdkMsg::MsgTimeout { - packet: Packet { - source_port, data, .. - }, - .. - } => { - if source_port == "transfer" { - // Packet was sent from a contract via the transfer port. - // We're getting the ack (and timeout) here because the memo field contained `{"ibc_callback": "secret1contractAddr"}`, - // and ibc-hooks routes the ack into `secret1contractAddr`. - - // Parse data as FungibleTokenPacketData JSON - let packet_data: FungibleTokenPacketData = match serde_json::from_slice( - data.as_slice(), - ) { - Ok(packet_data) => packet_data, - Err(err) => { - trace!( - "Contract was called via ibc-hooks ack callback but packet_data cannot be parsed as FungibleTokenPacketData: {:?} Error: {:?}", - String::from_utf8_lossy(data.as_slice()), - err, - ); - return false; - } - }; - - // memo must be set in ibc-hooks - let memo = match packet_data.memo { - Some(memo) => memo, - None => { - trace!("Contract was called via ibc-hooks ack callback but packet_data.memo is empty"); - return false; - } - }; - - // Parse data.memo as `{"ibc_callback": "secret1contractAddr"}` JSON - let ibc_hooks_outgoing_memo: IbcHooksOutgoingTransferMemo = - match serde_json::from_slice(memo.as_bytes()) { - Ok(wasm_msg) => wasm_msg, - Err(err) => { - trace!( - "Contract was called via ibc-hooks but packet_data.memo cannot be parsed as IbcHooksWasmMsg: {:?} Error: {:?}", - memo, - err, - ); - return false; - } - }; - - let is_verified = *contract_address == ibc_hooks_outgoing_memo.ibc_callback - && *contract_address == packet_data.sender; - if !is_verified { - trace!( - "Contract address sent to enclave {:?} is not the same as in ibc-hooks outgoing transfer callback address packet {:?}", - contract_address, - ibc_hooks_outgoing_memo.ibc_callback - ); - } - is_verified - } else { - // Packet was sent from an IBC enabled contract - // source_port is of the form "wasm.{contract_address}" - - // Extract contract_address from source_port - // This also checks that source_port starts with "wasm." - let contract_address_from_port = match source_port.strip_prefix("wasm.") { - Some(contract_address) => contract_address, - None => { - trace!( - "IBC-enabled Contract was called via MsgAcknowledgement but source_port doesn't start with \"wasm.\": {:?}", - source_port, - ); - return false; - } - }; - - let is_verified = *contract_address == HumanAddr::from(contract_address_from_port); - if !is_verified { - trace!( - "Contract address sent to enclave {:?} is not the same as extracted from MsgAcknowledgement but source_port: {:?}", - contract_address, - contract_address_from_port, - ); - } - is_verified - } - } - } -} - -/// Check that the funds listed in the cosmwasm message matches the ones in env -fn verify_sent_funds(msg: &CosmosSdkMsg, sent_funds_msg: &[Coin]) -> bool { - match msg { - CosmosSdkMsg::MsgExecuteContract { sent_funds, .. } - | CosmosSdkMsg::MsgInstantiateContract { - init_funds: sent_funds, - .. - } => sent_funds_msg == sent_funds, - CosmosSdkMsg::Other => false, - CosmosSdkMsg::MsgRecvPacket { - packet: - Packet { - data, - source_port, - source_channel, - destination_port, - destination_channel, - .. - }, - .. - } => { - if destination_port == "transfer" { - // Packet was routed here through ibc-hooks - - // Should be just one coin - if sent_funds_msg.len() != 1 { - trace!( - "Contract was called via ibc-hooks but sent_funds_msg.len() != 1: {:?}", - sent_funds_msg, - ); - return false; - } - - let sent_funds_msg_coin = &sent_funds_msg[0]; - - // Parse data as FungibleTokenPacketData JSON - let packet_data: FungibleTokenPacketData = match serde_json::from_slice( - data.as_slice(), - ) { - Ok(packet_data) => packet_data, - Err(err) => { - trace!( - "Contract was called via ibc-hooks but packet_data cannot be parsed as FungibleTokenPacketData: {:?} Error: {:?}", - String::from_utf8_lossy(data.as_slice()), - err, - ); - return false; - } - }; - - // Check amount - if sent_funds_msg_coin.amount != packet_data.amount { - trace!( - "Contract was called via ibc-hooks but sent_funds_msg_coin.amount != packet_data.amount: {:?} != {:?}", - sent_funds_msg_coin.amount, - packet_data.amount, - ); - return false; - } - - // The packet's denom is the denom in the sender chain. - // It needs to be converted to the local denom. - // Logic source: https://github.com/scrtlabs/SecretNetwork/blob/96b0ba7d6/x/ibc-hooks/wasm_hook.go#L483-L513 - let denom: String = if receiver_chain_is_source( - source_port, - source_channel, - &packet_data.denom, - ) { - // remove prefix added by sender chain - let voucher_prefix = get_denom_prefix(source_port, source_channel); - - let unprefixed_denom: String = match packet_data - .denom - .strip_prefix(&voucher_prefix) - { - Some(unprefixed_denom) => unprefixed_denom.to_string(), - None => { - trace!( - "Contract was called via ibc-hooks but packet_data.denom doesn't start with voucher_prefix: {:?} != {:?}", - packet_data.denom, - voucher_prefix, - ); - return false; - } - }; - - // The denomination used to send the coins is either the native denom or the hash of the path - // if the denomination is not native. - let denom_trace = parse_denom_trace(&unprefixed_denom); - if !denom_trace.path.is_empty() { - denom_trace.ibc_denom() - } else { - unprefixed_denom - } - } else { - let prefixed_denom = get_denom_prefix(destination_port, destination_channel) - + &packet_data.denom; - parse_denom_trace(&prefixed_denom).ibc_denom() - }; - - // Check denom - if sent_funds_msg_coin.denom.to_lowercase() != denom.to_lowercase() { - trace!( - "Contract was called via ibc-hooks but sent_funds_msg_coin.denom != denom: {:?} != {:?}", - sent_funds_msg_coin.denom, - denom, - ); - return false; - } - - true - } else { - // Packet is for an IBC enabled contract - // No funds should be sent - sent_funds_msg.is_empty() - } - } - CosmosSdkMsg::MsgAcknowledgement { .. } => { - // No funds should be sent with a MsgAcknowledgement - sent_funds_msg.is_empty() - } - CosmosSdkMsg::MsgTimeout { .. } => { - // No funds should be sent with a MsgTimeout - sent_funds_msg.is_empty() - } - } -} - fn verify_message_params( messages: &[CosmosSdkMsg], sender: &CanonicalAddr, @@ -1145,24 +662,8 @@ fn verify_message_params( let msg = msg.unwrap(); info!("Verifying message sender..."); - match msg { - CosmosSdkMsg::MsgRecvPacket { .. } - | CosmosSdkMsg::MsgAcknowledgement { .. } - | CosmosSdkMsg::MsgTimeout { .. } => { - // No sender to verify. - // Going to pass null sender to the contract if all other checks pass. - } - CosmosSdkMsg::MsgExecuteContract { .. } - | CosmosSdkMsg::MsgInstantiateContract { .. } - | CosmosSdkMsg::Other => { - if msg.sender() != Some(sender) { - warn!( - "message sender did not match cosmwasm message sender: {:?} {:?}", - sender, msg - ); - return false; - } - } + if let Some(value) = verify_sender(msg, sender) { + return value; } info!("Verifying contract address..."); diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs new file mode 100644 index 000000000..6c9521476 --- /dev/null +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs @@ -0,0 +1,217 @@ +use cw_types_v010::types::HumanAddr; +use enclave_cosmos_types::types::{ + CosmosSdkMsg, FungibleTokenPacketData, IbcHooksIncomingTransferMsg, + IbcHooksOutgoingTransferMemo, Packet, +}; +use log::*; + +/// Check that the contract listed in the cosmos sdk message matches the one in env +pub fn verify_contract_address(msg: &CosmosSdkMsg, contract_address: &HumanAddr) -> bool { + // Contract address is relevant only to execute, since during sending an instantiate message the contract address is not yet known + match msg { + CosmosSdkMsg::MsgExecuteContract { contract, .. } => { + verify_msg_execute_contract_address(contract_address, contract) + } + // During sending an instantiate message the contract address is not yet known + CosmosSdkMsg::MsgInstantiateContract { .. } => true, + CosmosSdkMsg::MsgRecvPacket { + packet: + Packet { + destination_port, + data, + .. + }, + .. + } => verify_contract_address_msg_recv_packet(destination_port, data, contract_address), + CosmosSdkMsg::MsgAcknowledgement { + packet: Packet { + source_port, data, .. + }, + .. + } + | CosmosSdkMsg::MsgTimeout { + packet: Packet { + source_port, data, .. + }, + .. + } => verify_contract_address_msg_ack_or_timeout(source_port, data, contract_address), + CosmosSdkMsg::Other => false, + } +} + +fn verify_msg_execute_contract_address(contract_address: &HumanAddr, contract: &HumanAddr) -> bool { + info!("Verifying contract address.."); + let is_verified = contract_address == contract; + if !is_verified { + trace!( + "Contract address sent to enclave {:?} is not the same as the signed one {:?}", + contract_address, + *contract + ); + } + is_verified +} + +fn verify_contract_address_msg_ack_or_timeout( + source_port: &String, + data: &Vec, + contract_address: &HumanAddr, +) -> bool { + if source_port == "transfer" { + // Packet was sent from a contract via the transfer port. + verify_contract_address_ibc_wasm_hooks_outgoing_transfer(data, contract_address) + } else { + // Packet was sent from an IBC enabled contract + verify_contract_address_ibc_contract(source_port, contract_address) + } +} + +fn verify_contract_address_ibc_wasm_hooks_outgoing_transfer( + data: &Vec, + contract_address: &HumanAddr, +) -> bool { + // We're getting the ack (and timeout) here because the memo field contained `{"ibc_callback": "secret1contractAddr"}`, + // and ibc-hooks routes the ack into `secret1contractAddr`. + + // Parse data as FungibleTokenPacketData JSON + let packet_data: FungibleTokenPacketData = match serde_json::from_slice(data.as_slice()) { + Ok(packet_data) => packet_data, + Err(err) => { + trace!( + "Contract was called via ibc-hooks ack callback but packet_data cannot be parsed as FungibleTokenPacketData: {:?} Error: {:?}", + String::from_utf8_lossy(data.as_slice()), + err, + ); + return false; + } + }; + + // memo must be set in ibc-hooks + let memo = match packet_data.memo { + Some(memo) => memo, + None => { + trace!("Contract was called via ibc-hooks ack callback but packet_data.memo is empty"); + return false; + } + }; + + // Parse data.memo as `{"ibc_callback": "secret1contractAddr"}` JSON + let ibc_hooks_outgoing_memo: IbcHooksOutgoingTransferMemo = match serde_json::from_slice( + memo.as_bytes(), + ) { + Ok(wasm_msg) => wasm_msg, + Err(err) => { + trace!( + "Contract was called via ibc-hooks but packet_data.memo cannot be parsed as IbcHooksWasmMsg: {:?} Error: {:?}", + memo, + err, + ); + return false; + } + }; + + let is_verified = *contract_address == ibc_hooks_outgoing_memo.ibc_callback + && *contract_address == packet_data.sender; + if !is_verified { + trace!( + "Contract address sent to enclave {:?} is not the same as in ibc-hooks outgoing transfer callback address packet {:?}", + contract_address, + ibc_hooks_outgoing_memo.ibc_callback + ); + } + is_verified +} + +fn verify_contract_address_msg_recv_packet( + destination_port: &String, + data: &Vec, + contract_address: &HumanAddr, +) -> bool { + if destination_port == "transfer" { + // Packet was routed here through ibc-hooks + return verify_contract_address_ibc_wasm_hooks_incoming_transfer(data, contract_address); + } else { + // Packet is for an IBC enabled contract + return verify_contract_address_ibc_contract(destination_port, contract_address); + } +} + +fn verify_contract_address_ibc_contract(port: &String, contract_address: &HumanAddr) -> bool { + // port is of the form "wasm.{contract_address}" + + // Extract contract_address from port + // This also checks that port starts with "wasm." + let contract_address_from_port = match port.strip_prefix("wasm.") { + Some(contract_address) => contract_address, + None => { + trace!( + "IBC-enabled contract was called but port doesn't start with \"wasm.\": {:?}", + port, + ); + return false; + } + }; + + let is_verified = *contract_address == HumanAddr::from(contract_address_from_port); + if !is_verified { + trace!( + "IBC-enabled contract address sent to enclave {:?} is not the same as extracted from SDK message: {:?}", + contract_address, + contract_address_from_port, + ); + } + is_verified +} + +fn verify_contract_address_ibc_wasm_hooks_incoming_transfer( + data: &Vec, + contract_address: &HumanAddr, +) -> bool { + // Parse data as FungibleTokenPacketData JSON + let packet_data: FungibleTokenPacketData = match serde_json::from_slice(data.as_slice()) { + Ok(packet_data) => packet_data, + Err(err) => { + trace!( + "Contract was called via ibc-hooks but packet_data cannot be parsed as FungibleTokenPacketData: {:?} Error: {:?}", + String::from_utf8_lossy(data.as_slice()), + err, + ); + return false; + } + }; + + // memo must be set in ibc-hooks + let memo = match packet_data.memo { + Some(memo) => memo, + None => { + trace!("Contract was called via ibc-hooks but packet_data.memo is empty"); + return false; + } + }; + + // Parse data.memo as IbcHooksWasmMsg JSON + let wasm_msg: IbcHooksIncomingTransferMsg = match serde_json::from_slice(memo.as_bytes()) { + Ok(wasm_msg) => wasm_msg, + Err(err) => { + trace!( + "Contract was called via ibc-hooks but packet_data.memo cannot be parsed as IbcHooksWasmMsg: {:?} Error: {:?}", + memo, + err, + ); + return false; + } + }; + + // In ibc-hooks contract_address == packet_data.memo.wasm.contract == packet_data.receiver + let is_verified = + *contract_address == packet_data.receiver && *contract_address == wasm_msg.wasm.contract; + if !is_verified { + trace!( + "Contract address sent to enclave {:?} is not the same as in ibc-hooks packet receiver={:?} memo={:?}", + contract_address, + packet_data.receiver, + wasm_msg.wasm.contract + ); + } + is_verified +} diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/mod.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/mod.rs new file mode 100644 index 000000000..79f8d0a3f --- /dev/null +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/mod.rs @@ -0,0 +1,4 @@ +pub(crate) mod contract_address_validation; +pub(crate) mod msg_validation; +pub(crate) mod send_funds_validations; +pub(crate) mod sender_validation; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs new file mode 100644 index 000000000..1a34aecf5 --- /dev/null +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs @@ -0,0 +1,215 @@ +use cw_types_v010::types::CanonicalAddr; +use cw_types_v1::ibc::IbcPacketReceiveMsg; +use enclave_cosmos_types::types::{ + is_transfer_ack_error, CosmosSdkMsg, FungibleTokenPacketData, HandleType, IBCLifecycleComplete, + IBCLifecycleCompleteOptions, IBCPacketAckMsg, IBCPacketTimeoutMsg, IbcHooksIncomingTransferMsg, + Packet, +}; + +use log::*; + +use crate::types::SecretMessage; + +/// Get the cosmwasm message that contains the encrypted message +pub fn verify_and_get_sdk_msg<'sd>( + messages: &'sd [CosmosSdkMsg], + msg_sender: &CanonicalAddr, + sent_msg: &SecretMessage, + handle_type: HandleType, +) -> Option<&'sd CosmosSdkMsg> { + trace!("get_verified_msg: {:?}", messages); + + messages.iter().find(|&m| match m { + CosmosSdkMsg::Other => false, + CosmosSdkMsg::MsgExecuteContract { msg, sender, .. } + | CosmosSdkMsg::MsgInstantiateContract { + init_msg: msg, + sender, + .. + } => msg_sender == sender && &sent_msg.to_vec() == msg, + CosmosSdkMsg::MsgRecvPacket { packet, .. } => match handle_type { + HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => verify_ibc_packet_recv(sent_msg, packet), + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER => { + verify_ibc_wasm_hooks_incoming_transfer(sent_msg, packet) + } + _ => false, + }, + CosmosSdkMsg::MsgAcknowledgement { + packet, + acknowledgement, + signer, + .. + } => match handle_type { + HandleType::HANDLE_TYPE_IBC_PACKET_ACK => { + verify_ibc_packet_ack(sent_msg, packet, acknowledgement, signer) + } + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK => { + verify_ibc_wasm_hooks_outgoing_transfer_ack(sent_msg, packet, acknowledgement) + } + _ => false, + }, + CosmosSdkMsg::MsgTimeout { packet, signer, .. } => match handle_type { + HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => { + verify_ibc_packet_timeout(sent_msg, packet, signer) + } + HandleType::HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT => { + verify_ibc_wasm_hooks_outgoing_transfer_timeout(sent_msg, packet) + } + _ => false, + }, + }) +} + +pub fn verify_ibc_packet_recv(sent_msg: &SecretMessage, packet: &Packet) -> bool { + let Packet { + sequence, + source_port, + source_channel, + destination_port, + destination_channel, + data, + } = packet; + + let parsed_sent_msg = serde_json::from_slice::(&sent_msg.msg); + if parsed_sent_msg.is_err() { + trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_RECEIVE: sent_msg.msg cannot be parsed as IbcPacketReceiveMsg: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), parsed_sent_msg.err()); + + trace!("Checking if sent_msg & data are encrypted"); + return &sent_msg.to_vec() == data; + } + let parsed = parsed_sent_msg.unwrap(); + + parsed.packet.data.as_slice() == data.as_slice() + && parsed.packet.sequence == *sequence + && parsed.packet.src.port_id == *source_port + && parsed.packet.src.channel_id == *source_channel + && parsed.packet.dest.port_id == *destination_port + && parsed.packet.dest.channel_id == *destination_channel +} + +pub fn verify_ibc_wasm_hooks_incoming_transfer(sent_msg: &SecretMessage, packet: &Packet) -> bool { + let Packet { data, .. } = packet; + + let fungible_token_packet_data = serde_json::from_slice::(data); + if fungible_token_packet_data.is_err() { + trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: data cannot be parsed as FungibleTokenPacketData: {:?} Error: {:?}", String::from_utf8_lossy(data), fungible_token_packet_data.err()); + return false; + } + let fungible_token_packet_data = fungible_token_packet_data.unwrap(); + + let ibc_hooks_incoming_transfer_msg = serde_json::from_slice::( + fungible_token_packet_data + .memo + .clone() + .unwrap_or_else(|| "".to_string()) + .as_bytes(), + ); + if ibc_hooks_incoming_transfer_msg.is_err() { + trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: fungible_token_packet_data.memo cannot be parsed as IbcHooksIncomingTransferMsg: {:?} Error: {:?}", fungible_token_packet_data.memo, ibc_hooks_incoming_transfer_msg.err()); + return false; + } + let ibc_hooks_incoming_transfer_msg = ibc_hooks_incoming_transfer_msg.unwrap(); + let sent_msg_value = serde_json::from_slice::(&sent_msg.msg); + if sent_msg_value.is_err() { + trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_INCOMING_TRANSFER: sent_msg.msg cannot be parsed as serde_json::Value: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), sent_msg_value.err()); + return false; + } + + ibc_hooks_incoming_transfer_msg.wasm.msg == sent_msg_value.unwrap() +} + +pub fn verify_ibc_packet_ack( + sent_msg: &SecretMessage, + packet: &Packet, + acknowledgement: &Vec, + signer: &String, +) -> bool { + let send_msg_ack_msg = serde_json::from_slice::(&sent_msg.msg); + if send_msg_ack_msg.is_err() { + trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_ACK: sent_msg.msg cannot be parsed as IBCPacketAckMsg: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), send_msg_ack_msg.err()); + return false; + } + let sent_msg_ack_msg = send_msg_ack_msg.unwrap(); + + sent_msg_ack_msg.original_packet.src.channel_id == packet.source_channel + && sent_msg_ack_msg.original_packet.src.port_id == packet.source_port + && sent_msg_ack_msg.original_packet.dest.channel_id == packet.destination_channel + && sent_msg_ack_msg.original_packet.dest.port_id == packet.destination_port + && sent_msg_ack_msg.original_packet.sequence == packet.sequence + && sent_msg_ack_msg.original_packet.data.0 == packet.data + && sent_msg_ack_msg.relayer == *signer + && sent_msg_ack_msg.acknowledgement.data.0 == *acknowledgement +} + +pub fn verify_ibc_wasm_hooks_outgoing_transfer_ack( + sent_msg: &SecretMessage, + packet: &Packet, + acknowledgement: &Vec, +) -> bool { + let ibc_lifecycle_complete = serde_json::from_slice::(&sent_msg.msg); + if ibc_lifecycle_complete.is_err() { + trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK: sent_msg.msg cannot be parsed as IBCLifecycleComplete: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), ibc_lifecycle_complete.err()); + return false; + } + let ibc_lifecycle_complete = ibc_lifecycle_complete.unwrap(); + + match ibc_lifecycle_complete { + IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCAck { + channel, + sequence, + ack, + success, + }) => { + channel == packet.source_channel + && sequence == packet.sequence + && ack == String::from_utf8_lossy(acknowledgement) + && success != is_transfer_ack_error(acknowledgement) + } + IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCTimeout { + .. + }) => false, + } +} + +pub fn verify_ibc_packet_timeout( + sent_msg: &SecretMessage, + packet: &Packet, + signer: &String, +) -> bool { + let send_msg_timeout_msg = serde_json::from_slice::(&sent_msg.msg); + if send_msg_timeout_msg.is_err() { + trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_TIMEOUT: sent_msg.msg cannot be parsed as IBCPacketTimeoutMsg: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), send_msg_timeout_msg.err()); + return false; + } + let sent_msg_timeout_msg = send_msg_timeout_msg.unwrap(); + + sent_msg_timeout_msg.packet.src.channel_id == packet.source_channel + && sent_msg_timeout_msg.packet.src.port_id == packet.source_port + && sent_msg_timeout_msg.packet.dest.channel_id == packet.destination_channel + && sent_msg_timeout_msg.packet.dest.port_id == packet.destination_port + && sent_msg_timeout_msg.packet.sequence == packet.sequence + && sent_msg_timeout_msg.packet.data.0 == packet.data + && sent_msg_timeout_msg.relayer == *signer +} + +pub fn verify_ibc_wasm_hooks_outgoing_transfer_timeout( + sent_msg: &SecretMessage, + packet: &Packet, +) -> bool { + let ibc_lifecycle_complete = serde_json::from_slice::(&sent_msg.msg); + if ibc_lifecycle_complete.is_err() { + trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_TIMEOUT: sent_msg.msg cannot be parsed as IBCLifecycleComplete: {:?} Error: {:?}", String::from_utf8_lossy(&sent_msg.msg), ibc_lifecycle_complete.err()); + return false; + } + let ibc_lifecycle_complete = ibc_lifecycle_complete.unwrap(); + + match ibc_lifecycle_complete { + IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCAck { + .. + }) => false, + IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCTimeout { + channel, + sequence, + }) => channel == packet.source_channel && sequence == packet.sequence, + } +} diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs new file mode 100644 index 000000000..af9f9079b --- /dev/null +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs @@ -0,0 +1,136 @@ +use crate::ibc_denom_utils::{get_denom_prefix, parse_denom_trace, receiver_chain_is_source}; +use cw_types_v010::types::Coin; +use enclave_cosmos_types::types::{CosmosSdkMsg, FungibleTokenPacketData, Packet}; +use log::*; + +/// Check that the funds listed in the cosmwasm message matches the ones in env +pub fn verify_sent_funds(msg: &CosmosSdkMsg, sent_funds_msg: &[Coin]) -> bool { + match msg { + CosmosSdkMsg::MsgExecuteContract { sent_funds, .. } + | CosmosSdkMsg::MsgInstantiateContract { + init_funds: sent_funds, + .. + } => sent_funds_msg == sent_funds, + CosmosSdkMsg::Other => false, + CosmosSdkMsg::MsgRecvPacket { + packet: + Packet { + data, + source_port, + source_channel, + destination_port, + destination_channel, + .. + }, + .. + } => { + if destination_port == "transfer" { + // Packet was routed here through ibc-hooks + verify_sent_funds_ibc_wasm_hooks_incoming_transfer( + sent_funds_msg, + data, + source_port, + source_channel, + destination_port, + destination_channel, + ) + } else { + // Packet is for an IBC enabled contract + // No funds should be sent + sent_funds_msg.is_empty() + } + } + CosmosSdkMsg::MsgAcknowledgement { .. } | CosmosSdkMsg::MsgTimeout { .. } => { + sent_funds_msg.is_empty() + } + } +} + +fn verify_sent_funds_ibc_wasm_hooks_incoming_transfer( + sent_funds_msg: &[Coin], + data: &Vec, + source_port: &String, + source_channel: &String, + destination_port: &String, + destination_channel: &String, +) -> bool { + // Should be just one coin + if sent_funds_msg.len() != 1 { + trace!( + "Contract was called via ibc-hooks but sent_funds_msg.len() != 1: {:?}", + sent_funds_msg, + ); + return false; + } + + let sent_funds_msg_coin = &sent_funds_msg[0]; + + // Parse data as FungibleTokenPacketData JSON + let packet_data: FungibleTokenPacketData = match serde_json::from_slice(data.as_slice()) { + Ok(packet_data) => packet_data, + Err(err) => { + trace!( + "Contract was called via ibc-hooks but packet_data cannot be parsed as FungibleTokenPacketData: {:?} Error: {:?}", + String::from_utf8_lossy(data.as_slice()), + err, + ); + return false; + } + }; + + // Check amount + if sent_funds_msg_coin.amount != packet_data.amount { + trace!( + "Contract was called via ibc-hooks but sent_funds_msg_coin.amount != packet_data.amount: {:?} != {:?}", + sent_funds_msg_coin.amount, + packet_data.amount, + ); + return false; + } + + // The packet's denom is the denom in the sender chain. + // It needs to be converted to the local denom. + // Logic source: https://github.com/scrtlabs/SecretNetwork/blob/96b0ba7d6/x/ibc-hooks/wasm_hook.go#L483-L513 + let denom: String = if receiver_chain_is_source(source_port, source_channel, &packet_data.denom) + { + // remove prefix added by sender chain + let voucher_prefix = get_denom_prefix(source_port, source_channel); + + let unprefixed_denom: String = match packet_data.denom.strip_prefix(&voucher_prefix) { + Some(unprefixed_denom) => unprefixed_denom.to_string(), + None => { + trace!( + "Contract was called via ibc-hooks but packet_data.denom doesn't start with voucher_prefix: {:?} != {:?}", + packet_data.denom, + voucher_prefix, + ); + return false; + } + }; + + // The denomination used to send the coins is either the native denom or the hash of the path + // if the denomination is not native. + let denom_trace = parse_denom_trace(&unprefixed_denom); + if !denom_trace.path.is_empty() { + denom_trace.ibc_denom() + } else { + unprefixed_denom + } + } else { + let prefixed_denom = + get_denom_prefix(destination_port, destination_channel) + &packet_data.denom; + parse_denom_trace(&prefixed_denom).ibc_denom() + }; + + // Check denom + if sent_funds_msg_coin.denom.to_lowercase() != denom.to_lowercase() { + trace!( + "Contract was called via ibc-hooks but sent_funds_msg_coin.denom != denom: {:?} != {:?}", + sent_funds_msg_coin.denom, + denom, + ); + return false; + } + + true +} diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs new file mode 100644 index 000000000..5193c6ea2 --- /dev/null +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/sender_validation.rs @@ -0,0 +1,27 @@ +use cw_types_v010::types::CanonicalAddr; +use enclave_cosmos_types::types::CosmosSdkMsg; +use log::*; + +pub fn verify_sender(msg: &CosmosSdkMsg, sender: &CanonicalAddr) -> Option { + match msg { + CosmosSdkMsg::MsgRecvPacket { .. } + | CosmosSdkMsg::MsgAcknowledgement { .. } + | CosmosSdkMsg::MsgTimeout { .. } => { + // No sender to verify. + // Going to pass null sender to the contract if all other checks pass. + } + CosmosSdkMsg::MsgExecuteContract { .. } + | CosmosSdkMsg::MsgInstantiateContract { .. } + | CosmosSdkMsg::Other => { + if msg.sender() != Some(sender) { + trace!( + "sender {:?} did not match sdk message sender: {:?}", + sender, + msg + ); + return Some(false); + } + } + } + None +} diff --git a/cosmwasm/enclaves/shared/contract-engine/src/lib.rs b/cosmwasm/enclaves/shared/contract-engine/src/lib.rs index 2be3cb4c7..118e1e75d 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/lib.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/lib.rs @@ -17,6 +17,7 @@ pub mod external; mod gas; mod ibc_denom_utils; mod ibc_message; +mod input_validation; mod io; mod message; mod message_utils; From 39009cd054311814d36b530a57cea086f025dde7 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Tue, 30 May 2023 22:55:50 +0300 Subject: [PATCH 39/54] Clippy --- .../src/input_validation/contract_address_validation.rs | 4 ++-- .../src/input_validation/msg_validation.rs | 2 +- .../src/input_validation/send_funds_validations.rs | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs index 6c9521476..9bbd449b4 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/contract_address_validation.rs @@ -129,10 +129,10 @@ fn verify_contract_address_msg_recv_packet( ) -> bool { if destination_port == "transfer" { // Packet was routed here through ibc-hooks - return verify_contract_address_ibc_wasm_hooks_incoming_transfer(data, contract_address); + verify_contract_address_ibc_wasm_hooks_incoming_transfer(data, contract_address) } else { // Packet is for an IBC enabled contract - return verify_contract_address_ibc_contract(destination_port, contract_address); + verify_contract_address_ibc_contract(destination_port, contract_address) } } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs index 1a34aecf5..dfe6a3b70 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs @@ -144,7 +144,7 @@ pub fn verify_ibc_packet_ack( pub fn verify_ibc_wasm_hooks_outgoing_transfer_ack( sent_msg: &SecretMessage, packet: &Packet, - acknowledgement: &Vec, + acknowledgement: &[u8], ) -> bool { let ibc_lifecycle_complete = serde_json::from_slice::(&sent_msg.msg); if ibc_lifecycle_complete.is_err() { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs index af9f9079b..adec38780 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/send_funds_validations.rs @@ -49,10 +49,10 @@ pub fn verify_sent_funds(msg: &CosmosSdkMsg, sent_funds_msg: &[Coin]) -> bool { fn verify_sent_funds_ibc_wasm_hooks_incoming_transfer( sent_funds_msg: &[Coin], data: &Vec, - source_port: &String, - source_channel: &String, - destination_port: &String, - destination_channel: &String, + source_port: &str, + source_channel: &str, + destination_port: &str, + destination_channel: &str, ) -> bool { // Should be just one coin if sent_funds_msg.len() != 1 { From 2387ea733ab5e915ced9c40f9b7659e18b8533ce Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 31 May 2023 11:02:17 +0300 Subject: [PATCH 40/54] Try to fix IBC verification issue https://github.com/scrtlabs/SecretNetwork/actions/runs/5125623580/jobs/9219535452#step:7:383 --- x/compute/internal/keeper/keeper.go | 2 +- x/compute/internal/keeper/relay.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index c4e6a1e52..9a72f4e97 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -226,7 +226,7 @@ func (k Keeper) GetTxInfo(ctx sdk.Context, sender sdk.AccAddress) ([]byte, sdktx } parsedTx = sdktx.Tx{ - Body: nil, + Body: nil, // parsing rawTx.BodyBytes is the reason for the error, and it isn't used anyway AuthInfo: &txAuthInfo, Signatures: rawTx.Signatures, } diff --git a/x/compute/internal/keeper/relay.go b/x/compute/internal/keeper/relay.go index 253d382a2..4fe35107d 100644 --- a/x/compute/internal/keeper/relay.go +++ b/x/compute/internal/keeper/relay.go @@ -295,7 +295,7 @@ func (k Keeper) OnTimeoutPacket( } func (k Keeper) handleIBCBasicContractResponse(ctx sdk.Context, addr sdk.AccAddress, ibcPortID string, inputMsg []byte, res *v1types.IBCBasicResponse) error { - verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED, []byte{}, []byte{}, []byte{}, nil) + verificationInfo := types.NewVerificationInfo([]byte{}, sdktxsigning.SignMode_SIGN_MODE_DIRECT, []byte{}, []byte{}, []byte{}, nil) _, err := k.handleContractResponse(ctx, addr, ibcPortID, res.Messages, res.Attributes, res.Events, nil, inputMsg, verificationInfo) return err From 1f406a0f86ad5c1605e206662e1c9d070836db39 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 31 May 2023 14:12:13 +0300 Subject: [PATCH 41/54] localsecret: fix tm-enclave reference --- deployment/dockerfiles/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/dockerfiles/Dockerfile b/deployment/dockerfiles/Dockerfile index a91285976..50f1a572a 100644 --- a/deployment/dockerfiles/Dockerfile +++ b/deployment/dockerfiles/Dockerfile @@ -83,7 +83,7 @@ RUN git clone --branch main https://github.com/scrtlabs/tm-secret-enclave.git WORKDIR tm-secret-enclave RUN git fetch -RUN git checkout tags/v1.9.2 +RUN git checkout tags/v1.9.3 RUN git submodule init RUN git submodule update --remote From 6338db4d6c61a069d7acd3847592b127e39942b3 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Wed, 31 May 2023 15:19:32 +0300 Subject: [PATCH 42/54] Fix GetTxInfo() for some IBC txs --- x/compute/internal/keeper/keeper.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 9a72f4e97..957eed017 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -280,6 +280,18 @@ func (k Keeper) GetTxInfo(ctx sdk.Context, sender sdk.AccAddress) ([]byte, sdktx switch signData := signatures[pkIndex].Data.(type) { case *sdktxsigning.SingleSignatureData: signMode = signData.SignMode + if signMode == sdktxsigning.SignMode_SIGN_MODE_UNSPECIFIED { + // Some shitness with IBC txs' internals - they are not registered properly with the app, + // and I think that it's something in the ibc-go repo that needs to be fixed. + // For some txs (e.g. MsgChannelOpenInit), we can unmarsal it into parsedTx + // but signMode turns out to be SIGN_MODE_UNSPECIFIED which is not true + // and always should be SignMode_SIGN_MODE_DIRECT (as IBC txs don't support Amino encoding) + // which causes `modeHandler.GetSignBytes()` down the line to fail with "can't verify sign mode SIGN_MODE_UNSPECIFIED" + // this is a stop gap solution, however we should investigate why this is happening + // and fix the `k.cdc.Unmarshal(ctx.TxBytes(), &parsedTx)` above, which will maybe allow us to remove + // the rawTx parsing code + signMode = sdktxsigning.SignMode_SIGN_MODE_DIRECT + } case *sdktxsigning.MultiSignatureData: signMode = sdktxsigning.SignMode_SIGN_MODE_LEGACY_AMINO_JSON } From 0cd91309c851f5fd44a888c3105bb5227c679a6f Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 1 Jun 2023 08:42:46 +0300 Subject: [PATCH 43/54] Fix build localsecret in CI? --- deployment/dockerfiles/Dockerfile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/deployment/dockerfiles/Dockerfile b/deployment/dockerfiles/Dockerfile index 50f1a572a..5c70d7bc5 100644 --- a/deployment/dockerfiles/Dockerfile +++ b/deployment/dockerfiles/Dockerfile @@ -78,13 +78,10 @@ ARG FEATURES_U ARG SGX_MODE=${SGX_MODE} ENV FEATURES_U=${FEATURES_U} -RUN git clone --branch main https://github.com/scrtlabs/tm-secret-enclave.git +RUN git clone --branch v1.9.3 --depth 1 https://github.com/scrtlabs/tm-secret-enclave.git WORKDIR tm-secret-enclave -RUN git fetch -RUN git checkout tags/v1.9.3 - RUN git submodule init RUN git submodule update --remote From 35199908ebe1ed2307872714f9a5eadf699c270b Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Thu, 1 Jun 2023 13:32:43 +0300 Subject: [PATCH 44/54] Fix verify_ibc_packet_ack() for fee middleware Fee middleware wraps the ack with IncentivizedAcknowledgement --- .../src/input_validation/msg_validation.rs | 24 ++++++++++++++++--- .../enclaves/shared/cosmos-types/src/types.rs | 7 ++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs index dfe6a3b70..1df4e4cfe 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs @@ -3,7 +3,7 @@ use cw_types_v1::ibc::IbcPacketReceiveMsg; use enclave_cosmos_types::types::{ is_transfer_ack_error, CosmosSdkMsg, FungibleTokenPacketData, HandleType, IBCLifecycleComplete, IBCLifecycleCompleteOptions, IBCPacketAckMsg, IBCPacketTimeoutMsg, IbcHooksIncomingTransferMsg, - Packet, + IncentivizedAcknowledgement, Packet, }; use log::*; @@ -131,14 +131,32 @@ pub fn verify_ibc_packet_ack( } let sent_msg_ack_msg = send_msg_ack_msg.unwrap(); - sent_msg_ack_msg.original_packet.src.channel_id == packet.source_channel + let incentivized_acknowledgement = + serde_json::from_slice::(&acknowledgement); + let is_ack_verified = match incentivized_acknowledgement { + Ok(incentivized_acknowledgement) => { + trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_ACK is an IncentivizedAcknowledgement, using app_acknowledgement"); + + sent_msg_ack_msg.acknowledgement.data + == incentivized_acknowledgement.app_acknowledgement + } + Err(_) => { + trace!( + "get_verified_msg HANDLE_TYPE_IBC_PACKET_ACK is not an IncentivizedAcknowledgement, continuing with acknowledgement" + ); + + sent_msg_ack_msg.acknowledgement.data.0 == *acknowledgement + } + }; + + is_ack_verified + && sent_msg_ack_msg.original_packet.src.channel_id == packet.source_channel && sent_msg_ack_msg.original_packet.src.port_id == packet.source_port && sent_msg_ack_msg.original_packet.dest.channel_id == packet.destination_channel && sent_msg_ack_msg.original_packet.dest.port_id == packet.destination_port && sent_msg_ack_msg.original_packet.sequence == packet.sequence && sent_msg_ack_msg.original_packet.data.0 == packet.data && sent_msg_ack_msg.relayer == *signer - && sent_msg_ack_msg.acknowledgement.data.0 == *acknowledgement } pub fn verify_ibc_wasm_hooks_outgoing_transfer_ack( diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index 1de468a4d..f0049d69a 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -474,6 +474,13 @@ pub struct IBCAcknowledgement { pub data: Binary, } +#[derive(Debug, Deserialize)] +pub struct IncentivizedAcknowledgement { + pub app_acknowledgement: Binary, + pub forward_relayer_address: String, + pub underlying_app_success: bool, +} + #[derive(Debug, Deserialize)] pub struct IBCPacketTimeoutMsg { pub packet: IBCPacket, From e71746256808b45e6183243cf735df513390898d Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 4 Jun 2023 12:01:02 +0300 Subject: [PATCH 45/54] Lint --- x/compute/internal/keeper/handler_plugin.go | 7 +++---- x/emergencybutton/module.go | 8 ++++---- x/emergencybutton/types/genesis.go | 5 +---- x/emergencybutton/types/params.go | 6 +----- 4 files changed, 9 insertions(+), 17 deletions(-) diff --git a/x/compute/internal/keeper/handler_plugin.go b/x/compute/internal/keeper/handler_plugin.go index 0f2f19431..a8ece9e90 100644 --- a/x/compute/internal/keeper/handler_plugin.go +++ b/x/compute/internal/keeper/handler_plugin.go @@ -9,7 +9,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" ibcclienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" channelkeeper "github.com/cosmos/ibc-go/v4/modules/core/04-channel/keeper" channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" @@ -58,11 +57,11 @@ func NewSDKMessageHandler(router MessageRouter, legacyRouter sdk.Router, encoder // IBCRawPacketHandler handels IBC.SendPacket messages which are published to an IBC channel. type IBCRawPacketHandler struct { channelKeeper channelkeeper.Keeper - ics4Wrapper transfertypes.ICS4Wrapper + ics4Wrapper ibctransfertypes.ICS4Wrapper capabilityKeeper capabilitykeeper.ScopedKeeper } -func NewIBCRawPacketHandler(channelKeeper channelkeeper.Keeper, ics4Wrapper transfertypes.ICS4Wrapper, capabilityKeeper capabilitykeeper.ScopedKeeper) IBCRawPacketHandler { +func NewIBCRawPacketHandler(channelKeeper channelkeeper.Keeper, ics4Wrapper ibctransfertypes.ICS4Wrapper, capabilityKeeper capabilitykeeper.ScopedKeeper) IBCRawPacketHandler { return IBCRawPacketHandler{ channelKeeper: channelKeeper, ics4Wrapper: ics4Wrapper, @@ -85,7 +84,7 @@ func NewMessageHandler( legacyMsgRouter sdk.Router, customEncoders *MessageEncoders, channelKeeper channelkeeper.Keeper, - ics4Wrapper transfertypes.ICS4Wrapper, + ics4Wrapper ibctransfertypes.ICS4Wrapper, capabilityKeeper capabilitykeeper.ScopedKeeper, portSource types.ICS20TransferPortSource, unpacker codectypes.AnyUnpacker, diff --git a/x/emergencybutton/module.go b/x/emergencybutton/module.go index bb5b53f5b..f39bf8b1b 100644 --- a/x/emergencybutton/module.go +++ b/x/emergencybutton/module.go @@ -32,7 +32,7 @@ type AppModuleBasic struct{} func (AppModuleBasic) Name() string { return types.ModuleName } -func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { +func (AppModuleBasic) RegisterLegacyAminoCodec(_ *codec.LegacyAmino) { } func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { @@ -40,7 +40,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { } // ValidateGenesis performs genesis state validation for the emergencybutton module. -func (b AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { +func (b AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { var genState types.GenesisState if err := cdc.UnmarshalJSON(bz, &genState); err != nil { return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) @@ -50,7 +50,7 @@ func (b AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEnc // --------------------------------------- // Interfaces. -func (b AppModuleBasic) RegisterRESTRoutes(ctx client.Context, r *mux.Router) { +func (b AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) { } func (b AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { @@ -102,7 +102,7 @@ func (am AppModule) Route() sdk.Route { func (AppModule) QuerierRoute() string { return types.RouterKey } // LegacyQuerierHandler is a no-op. Needed to meet AppModule interface. -func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { +func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { return func(sdk.Context, []string, abci.RequestQuery) ([]byte, error) { return nil, fmt.Errorf("legacy querier not supported for the x/%s module", types.ModuleName) } diff --git a/x/emergencybutton/types/genesis.go b/x/emergencybutton/types/genesis.go index 9167936c6..ba794af32 100644 --- a/x/emergencybutton/types/genesis.go +++ b/x/emergencybutton/types/genesis.go @@ -10,8 +10,5 @@ func DefaultGenesis() *GenesisState { // Validate performs basic genesis state validation returning an error upon any // failure. func (gs GenesisState) Validate() error { - if err := gs.Params.Validate(); err != nil { - return err - } - return nil + return gs.Params.Validate() } diff --git a/x/emergencybutton/types/params.go b/x/emergencybutton/types/params.go index 3730dd54d..6c052459f 100644 --- a/x/emergencybutton/types/params.go +++ b/x/emergencybutton/types/params.go @@ -33,11 +33,7 @@ func DefaultParams() Params { // validate params. func (p Params) Validate() error { - if err := validatePauserAddress(p.PauserAddress); err != nil { - return err - } - - return nil + return validatePauserAddress(p.PauserAddress) } // Implements params.ParamSet. From afa7ed1ba28e5397bf2423c15b63a40e8459fc4b Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 4 Jun 2023 12:01:32 +0300 Subject: [PATCH 46/54] Fix IBC setup --- app/keepers/keepers.go | 93 ++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index d7b2f78de..5f42eecd5 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -294,62 +294,65 @@ func (ak *SecretAppKeepers) InitCustomKeepers( // That means that whenever a packet is being send via Fee as an ics4wrapper, it will go through the switch middleware first (ref: https://github.com/cosmos/ibc-go/blob/v4.3.0/modules/apps/29-fee/keeper/relay.go#L15-L18). // Then we'll pass Fee as an ics4wrapper to everything else. // - // Compute: WASM Hooks -> Fee -> Switch - // Transfer: Packet Forward -> Fee -> Switch + // Compute send: Switch -> Fee -> Packet Forward -> WASM Hooks + // Compute receive: Switch -> Fee -> Packet Forward -> WASM Hooks + // + // Transfer send: Switch -> Fee -> Packet Forward -> WASM Hooks (WASM Hooks isn't necessary here, but we'll add it for consistency) + // Transfer receive: Switch -> Fee -> Packet Forward -> WASM Hooks // // Note: we need to make sure that every underlying IBC app/middleware that we're adding uses the ics4wrapper to send packets, and not the IBC channel keeper. - // Initialize channel for stacks that can turn off - // todo: verify that I don't have to create a new middleware instance for every different stack - ibcSwitchKeeper := ibcswitch.NewKeeper( - ak.IbcKeeper.ChannelKeeper, - ak.GetSubspace(ibcswitch.ModuleName), + // Setup the ICS4Wrapper used by the hooks middleware + // Configure the hooks keeper + ibcHooksKeeper := ibchookskeeper.NewKeeper( + ak.keys[ibchookstypes.StoreKey], ) - ak.IbcSwitchKeeper = &ibcSwitchKeeper + ak.IbcHooksKeeper = &ibcHooksKeeper - ak.IbcFeeKeeper = ibcfeekeeper.NewKeeper( - appCodec, - ak.keys[ibcfeetypes.StoreKey], - ak.GetSubspace(ibcfeetypes.ModuleName), // this isn't even used in the keeper but is required? - ak.IbcSwitchKeeper, + wasmHooks := ibchooks.NewWasmHooks( + &ibcHooksKeeper, + nil, // The compute keeper will be set later on + sdk.GetConfig().GetBech32AccountAddrPrefix(), + ) + ibcHooksICS4Wrapper := ibchooks.NewICS4Middleware( ak.IbcKeeper.ChannelKeeper, - &ak.IbcKeeper.PortKeeper, - ak.AccountKeeper, - ak.BankKeeper, + &wasmHooks, ) - // Initialize packet forward middleware router + // Initialize packet forward middleware ak.PacketForwardKeeper = ibcpacketforwardkeeper.NewKeeper( appCodec, ak.keys[ibcpacketforwardtypes.StoreKey], ak.GetSubspace(ibcpacketforwardtypes.ModuleName), - ak.TransferKeeper, + nil, // transfer keeper will be set later on ak.IbcKeeper.ChannelKeeper, ak.DistrKeeper, ak.BankKeeper, - ak.IbcFeeKeeper, + ibcHooksICS4Wrapper, ) - // Setup the ICS4Wrapper used by the hooks middleware - // Configure the hooks keeper - hooksKeeper := ibchookskeeper.NewKeeper( - ak.keys[ibchookstypes.StoreKey], + ak.IbcFeeKeeper = ibcfeekeeper.NewKeeper( + appCodec, + ak.keys[ibcfeetypes.StoreKey], + ak.GetSubspace(ibcfeetypes.ModuleName), + ak.PacketForwardKeeper, + ak.IbcKeeper.ChannelKeeper, + &ak.IbcKeeper.PortKeeper, + ak.AccountKeeper, + ak.BankKeeper, ) - ak.IbcHooksKeeper = &hooksKeeper - // The compute keeper in wasmHooks will be set later on - wasmHooks := ibchooks.NewWasmHooks(&hooksKeeper, nil, sdk.GetConfig().GetBech32AccountAddrPrefix()) - ibcHooksICS4Wrapper := ibchooks.NewICS4Middleware( + ibcSwitchKeeper := ibcswitch.NewKeeper( ak.IbcFeeKeeper, - &wasmHooks, + ak.GetSubspace(ibcswitch.ModuleName), ) + ak.IbcSwitchKeeper = &ibcSwitchKeeper icaControllerKeeper := icacontrollerkeeper.NewKeeper( appCodec, ak.keys[icacontrollertypes.StoreKey], ak.GetSubspace(icacontrollertypes.SubModuleName), - // todo: how can this work if IbcFeeKeeper does not implement ics4Wrapper?? Juno seems to have a bug - ak.IbcFeeKeeper, // integrate fee channel with ica + ak.IbcSwitchKeeper, ak.IbcKeeper.ChannelKeeper, &ak.IbcKeeper.PortKeeper, ak.ScopedICAControllerKeeper, @@ -361,7 +364,6 @@ func (ak *SecretAppKeepers) InitCustomKeepers( appCodec, ak.keys[icahosttypes.StoreKey], ak.GetSubspace(icahosttypes.SubModuleName), - // todo: maybe integrate feekeeper with ica host too ak.IbcKeeper.ChannelKeeper, &ak.IbcKeeper.PortKeeper, ak.AccountKeeper, @@ -377,10 +379,7 @@ func (ak *SecretAppKeepers) InitCustomKeepers( appCodec, ak.keys[ibctransfertypes.StoreKey], ak.GetSubspace(ibctransfertypes.ModuleName), - // todo: verify the following: the transfer keeper does not need to know about packet forward keeper, because - // we don't want to go through forward module if the packets originated in this chain. - // todo: verify the following: we want fees for the transfer app (it previously didn't have) - ak.IbcFeeKeeper, // integrate fee channel with transfer + ak.IbcSwitchKeeper, ak.IbcKeeper.ChannelKeeper, &ak.IbcKeeper.PortKeeper, ak.AccountKeeper, @@ -391,19 +390,18 @@ func (ak *SecretAppKeepers) InitCustomKeepers( ak.PacketForwardKeeper.SetTransferKeeper(ak.TransferKeeper) + // Transfer receive: Switch -> Fee -> Packet Forward -> WASM Hooks var transferStack porttypes.IBCModule transferStack = transfer.NewIBCModule(ak.TransferKeeper) + transferStack = ibchooks.NewIBCMiddleware(transferStack, &ibcHooksICS4Wrapper) transferStack = ibcpacketforward.NewIBCMiddleware( transferStack, ak.PacketForwardKeeper, 0, - // 10 minutes - ibcpacketforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp, - // 28 days - ibcpacketforwardkeeper.DefaultRefundTransferPacketTimeoutTimestamp, + ibcpacketforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp, // 10 minutes + ibcpacketforwardkeeper.DefaultRefundTransferPacketTimeoutTimestamp, // 28 days ) transferStack = ibcfee.NewIBCMiddleware(transferStack, ak.IbcFeeKeeper) - transferStack = ibchooks.NewIBCMiddleware(transferStack, &ibcHooksICS4Wrapper) transferStack = ibcswitch.NewIBCMiddleware(transferStack, ak.IbcSwitchKeeper) var icaHostStack porttypes.IBCModule @@ -435,7 +433,7 @@ func (ak *SecretAppKeepers) InitCustomKeepers( ak.IbcKeeper.PortKeeper, ak.TransferKeeper, ak.IbcKeeper.ChannelKeeper, - ibcHooksICS4Wrapper, + ak.IbcSwitchKeeper, app.Router(), app.MsgServiceRouter(), app.GRPCQueryRouter(), @@ -449,15 +447,22 @@ func (ak *SecretAppKeepers) InitCustomKeepers( ak.ComputeKeeper = &computeKeeper wasmHooks.ContractKeeper = ak.ComputeKeeper - // Create fee enabled wasm ibc Stack + // Compute receive: Switch -> Fee -> Packet Forward -> WASM Hooks var computeStack porttypes.IBCModule computeStack = compute.NewIBCHandler(ak.ComputeKeeper, ak.IbcKeeper.ChannelKeeper, ak.IbcFeeKeeper) + computeStack = ibchooks.NewIBCMiddleware(computeStack, &ibcHooksICS4Wrapper) + computeStack = ibcpacketforward.NewIBCMiddleware( + computeStack, + ak.PacketForwardKeeper, + 0, + ibcpacketforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp, // 10 minutes + ibcpacketforwardkeeper.DefaultRefundTransferPacketTimeoutTimestamp, // 28 days + ) computeStack = ibcfee.NewIBCMiddleware(computeStack, ak.IbcFeeKeeper) computeStack = ibcswitch.NewIBCMiddleware(computeStack, ak.IbcSwitchKeeper) // Create static IBC router, add ibc-transfer module route, then set and seal it - ibcRouter := porttypes.NewRouter() - ibcRouter. + ibcRouter := porttypes.NewRouter(). AddRoute(ibctransfertypes.ModuleName, transferStack). AddRoute(compute.ModuleName, computeStack). AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). From c31caadaa5b61cde35dd600ef049d2d01af67172 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 4 Jun 2023 12:20:20 +0300 Subject: [PATCH 47/54] Fix WASM Hooks zeroSender in GetTxInfo() --- x/compute/alias.go | 1 + x/compute/internal/keeper/keeper.go | 2 +- x/compute/internal/types/types.go | 10 ++++++++ x/ibc-hooks/wasm_hook.go | 36 +++++++++++------------------ 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/x/compute/alias.go b/x/compute/alias.go index 3cc2454b6..70e918170 100644 --- a/x/compute/alias.go +++ b/x/compute/alias.go @@ -95,6 +95,7 @@ var ( CodeKeyPrefix = types.CodeKeyPrefix ContractKeyPrefix = types.ContractKeyPrefix ContractStorePrefix = types.ContractStorePrefix + ZeroSender = types.ZeroSender ) type ( diff --git a/x/compute/internal/keeper/keeper.go b/x/compute/internal/keeper/keeper.go index 957eed017..9e79a0771 100644 --- a/x/compute/internal/keeper/keeper.go +++ b/x/compute/internal/keeper/keeper.go @@ -243,7 +243,7 @@ func (k Keeper) GetTxInfo(ctx sdk.Context, sender sdk.AccAddress) ([]byte, sdktx } pkIndex := -1 - if sender == nil { + if sender == nil || sender.Equals(types.ZeroSender) { // We are in a situation where the contract gets a null msg.sender, // however we still need to get the sign bytes for verification against the wasm input msg inside the enclave. // There can be multiple signers on the tx, for example one can be the msg.sender and the another can be the gas fee payer. Another example is if this tx also contains MsgMultiSend which supports multiple msg.senders thus requiring multiple signers. diff --git a/x/compute/internal/types/types.go b/x/compute/internal/types/types.go index 29f596371..7382f4b2d 100644 --- a/x/compute/internal/types/types.go +++ b/x/compute/internal/types/types.go @@ -289,3 +289,13 @@ contract-memory-cache-size = "{{ .WASMConfig.CacheSize }}" # The WASM VM memory cache size in number of cached modules. Can safely go up to 15, but not recommended for validators contract-memory-enclave-cache-size = "{{ .WASMConfig.EnclaveCacheSize }}" ` + +// ZeroSender is a valid 20 byte canonical address that's used to bypass the x/compute checks +// and later on is ignored by the enclave, which passes a null sender to the contract +// This is used in OnAcknowledgementPacketOverride & OnTimeoutPacketOverride +var ZeroSender = sdk.AccAddress{ + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, +} diff --git a/x/ibc-hooks/wasm_hook.go b/x/ibc-hooks/wasm_hook.go index 5e89476f0..069022f7e 100644 --- a/x/ibc-hooks/wasm_hook.go +++ b/x/ibc-hooks/wasm_hook.go @@ -6,7 +6,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - wasm "github.com/scrtlabs/SecretNetwork/x/compute" + "github.com/scrtlabs/SecretNetwork/x/compute" "github.com/scrtlabs/SecretNetwork/x/ibc-hooks/keeper" sdk "github.com/cosmos/cosmos-sdk/types" @@ -14,7 +14,7 @@ import ( channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported" - wasmtypes "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types" + computetypes "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types" "github.com/scrtlabs/SecretNetwork/x/ibc-hooks/types" ) @@ -24,12 +24,12 @@ type ContractAck struct { } type WasmHooks struct { - ContractKeeper *wasm.Keeper + ContractKeeper *compute.Keeper ibcHooksKeeper *keeper.Keeper bech32PrefixAccAddr string } -func NewWasmHooks(ibcHooksKeeper *keeper.Keeper, contractKeeper *wasm.Keeper, bech32PrefixAccAddr string) WasmHooks { +func NewWasmHooks(ibcHooksKeeper *keeper.Keeper, contractKeeper *compute.Keeper, bech32PrefixAccAddr string) WasmHooks { return WasmHooks{ ContractKeeper: contractKeeper, ibcHooksKeeper: ibcHooksKeeper, @@ -105,13 +105,13 @@ func (h WasmHooks) OnRecvPacketOverride(im IBCMiddleware, ctx sdk.Context, packe funds := sdk.NewCoins(sdk.NewCoin(denom, amount)) // Execute the contract - execMsg := wasm.MsgExecuteContract{ + execMsg := compute.MsgExecuteContract{ Sender: sdk.MustAccAddressFromBech32(senderBech32), // emptied out later by the enclave Contract: contractAddr, Msg: msgBytes, SentFunds: funds, } - response, err := h.execWasmMsg(ctx, &execMsg, wasmtypes.HandleTypeIbcWasmHooksIncomingTransfer) + response, err := h.execWasmMsg(ctx, &execMsg, computetypes.HandleTypeIbcWasmHooksIncomingTransfer) if err != nil { return NewEmitErrorAcknowledgement(ctx, types.ErrWasmError, err.Error()) } @@ -125,7 +125,7 @@ func (h WasmHooks) OnRecvPacketOverride(im IBCMiddleware, ctx sdk.Context, packe return channeltypes.NewResultAcknowledgement(bz) } -func (h WasmHooks) execWasmMsg(ctx sdk.Context, execMsg *wasm.MsgExecuteContract, handleType wasmtypes.HandleType) (*sdk.Result, error) { +func (h WasmHooks) execWasmMsg(ctx sdk.Context, execMsg *compute.MsgExecuteContract, handleType computetypes.HandleType) (*sdk.Result, error) { if err := execMsg.ValidateBasic(); err != nil { return nil, fmt.Errorf(types.ErrBadExecutionMsg, err.Error()) } @@ -302,16 +302,6 @@ func (h WasmHooks) SendPacketOverride(i ICS4Middleware, ctx sdk.Context, chanCap return nil } -// zeroSender is a valid 20 byte canonical address that's used to bypass the x/compute checks -// and later on is ignored by the enclave, which passes a null sender to the contract -// This is used in OnAcknowledgementPacketOverride & OnTimeoutPacketOverride -var zeroSender = sdk.AccAddress{ - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -} - type ( IbcLifecycleComplete struct { IbcLifecycleCompleteContainer `json:"ibc_lifecycle_complete"` @@ -384,14 +374,14 @@ func (h WasmHooks) OnAcknowledgementPacketOverride(im IBCMiddleware, ctx sdk.Con return err } - execMsg := wasm.MsgExecuteContract{ + execMsg := compute.MsgExecuteContract{ // Sender is ignored by the enclave, which passes a null msg.sender to the contract - Sender: zeroSender, + Sender: compute.ZeroSender, Contract: contractAddr, Msg: msg, SentFunds: sdk.NewCoins(), } - _, err = h.execWasmMsg(ctx, &execMsg, wasmtypes.HandleTypeIbcWasmHooksOutgoingTransferAck) + _, err = h.execWasmMsg(ctx, &execMsg, computetypes.HandleTypeIbcWasmHooksOutgoingTransferAck) if err != nil { // error processing the callback // ToDo: Open Question: Should we also delete the callback here? @@ -436,14 +426,14 @@ func (h WasmHooks) OnTimeoutPacketOverride(im IBCMiddleware, ctx sdk.Context, pa return err } - execMsg := wasm.MsgExecuteContract{ + execMsg := compute.MsgExecuteContract{ // Sender is ignored by the enclave, which passes a null msg.sender to the contract - Sender: zeroSender, + Sender: compute.ZeroSender, Contract: contractAddr, Msg: msg, SentFunds: sdk.NewCoins(), } - _, err = h.execWasmMsg(ctx, &execMsg, wasmtypes.HandleTypeIbcWasmHooksOutgoingTransferTimeout) + _, err = h.execWasmMsg(ctx, &execMsg, computetypes.HandleTypeIbcWasmHooksOutgoingTransferTimeout) if err != nil { // error processing the callback. This could be because the contract doesn't implement the message type to // process the callback. Retrying this will not help, so we can delete the callback from storage. From 4f7d75a79dae4a694426614e3f40fa50cced1d06 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 4 Jun 2023 13:47:12 +0300 Subject: [PATCH 48/54] clippy --- .../contract-engine/src/input_validation/msg_validation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs index 1df4e4cfe..b1f8cadbb 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs @@ -132,7 +132,7 @@ pub fn verify_ibc_packet_ack( let sent_msg_ack_msg = send_msg_ack_msg.unwrap(); let incentivized_acknowledgement = - serde_json::from_slice::(&acknowledgement); + serde_json::from_slice::(acknowledgement); let is_ack_verified = match incentivized_acknowledgement { Ok(incentivized_acknowledgement) => { trace!("get_verified_msg HANDLE_TYPE_IBC_PACKET_ACK is an IncentivizedAcknowledgement, using app_acknowledgement"); From 9cb35ad3b740cfc2c27cc2b6012a39cfde0a9f5e Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 4 Jun 2023 20:25:30 +0300 Subject: [PATCH 49/54] Fix verify_ibc_wasm_hooks_outgoing_transfer_ack() --- .../src/input_validation/msg_validation.rs | 25 +++++++++++++------ .../enclaves/shared/cosmos-types/src/types.rs | 21 +++++++++++----- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs index b1f8cadbb..623b0c369 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/input_validation/msg_validation.rs @@ -1,4 +1,4 @@ -use cw_types_v010::types::CanonicalAddr; +use cw_types_v010::{encoding::Binary, types::CanonicalAddr}; use cw_types_v1::ibc::IbcPacketReceiveMsg; use enclave_cosmos_types::types::{ is_transfer_ack_error, CosmosSdkMsg, FungibleTokenPacketData, HandleType, IBCLifecycleComplete, @@ -178,14 +178,25 @@ pub fn verify_ibc_wasm_hooks_outgoing_transfer_ack( ack, success, }) => { + let ack_as_string = serde_json::from_slice::(ack.as_bytes()); + if ack_as_string.is_err() { + trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK: ack cannot be parsed as String: {:?} Error: {:?}", ack, ack_as_string.err()); + return false; + } + let ack_as_string = ack_as_string.unwrap(); + let ack_as_binary = Binary::from_base64(&ack_as_string); + if ack_as_binary.is_err() { + trace!("get_verified_msg HANDLE_TYPE_IBC_WASM_HOOKS_OUTGOING_TRANSFER_ACK: ack_as_string cannot be parsed as Binary: {:?} Error: {:?}", ack_as_string, ack_as_binary.err()); + return false; + } + let ack_as_binary = ack_as_binary.unwrap(); + channel == packet.source_channel && sequence == packet.sequence - && ack == String::from_utf8_lossy(acknowledgement) + && ack_as_binary.as_slice() == acknowledgement && success != is_transfer_ack_error(acknowledgement) } - IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCTimeout { - .. - }) => false, + _ => false, } } @@ -222,12 +233,10 @@ pub fn verify_ibc_wasm_hooks_outgoing_transfer_timeout( let ibc_lifecycle_complete = ibc_lifecycle_complete.unwrap(); match ibc_lifecycle_complete { - IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCAck { - .. - }) => false, IBCLifecycleComplete::IBCLifecycleComplete(IBCLifecycleCompleteOptions::IBCTimeout { channel, sequence, }) => channel == packet.source_channel && sequence == packet.sequence, + _ => false, } } diff --git a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs index f0049d69a..e9acf9b29 100644 --- a/cosmwasm/enclaves/shared/cosmos-types/src/types.rs +++ b/cosmwasm/enclaves/shared/cosmos-types/src/types.rs @@ -448,20 +448,29 @@ pub enum IBCLifecycleCompleteOptions { } pub fn is_transfer_ack_error(acknowledgement: &[u8]) -> bool { - if let Ok(ack_err) = serde_json::from_slice::(acknowledgement) { - if !ack_err.error.is_empty() { - return true; + match serde_json::from_slice::(acknowledgement) { + Ok(ack_err) => { + if ack_err.error.is_some() { + return true; + } } + Err(_err) => {} } false } -#[derive(Deserialize)] +#[derive(Deserialize, Debug)] pub struct AcknowledgementError { - #[serde(rename = "error")] - pub error: String, + pub error: Option, } +// // This is needed to make sure that fields other than error are ignored as we don't care about them +// impl Default for AcknowledgementError { +// fn default() -> Self { +// Self { error: None } +// } +// } + #[derive(Debug, Deserialize)] pub struct IBCPacketAckMsg { pub acknowledgement: IBCAcknowledgement, From 7fea9288fe7d3ff5dc698a03adb427d5b9fad4d3 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Sun, 4 Jun 2023 20:52:39 +0300 Subject: [PATCH 50/54] Fix WASM Hooks ack/timeout callback --- x/ibc-hooks/wasm_hook.go | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/x/ibc-hooks/wasm_hook.go b/x/ibc-hooks/wasm_hook.go index 069022f7e..e8eebf20e 100644 --- a/x/ibc-hooks/wasm_hook.go +++ b/x/ibc-hooks/wasm_hook.go @@ -249,24 +249,8 @@ func (h WasmHooks) SendPacketOverride(i ICS4Middleware, ctx sdk.Context, chanCap return i.channel.SendPacket(ctx, chanCap, packet) // continue } - // We remove the callback metadata from the memo as it has already been processed. + // Originally, Osmosis removed the callback metadata from the memo as it had already fulfilled its purpose for them. We cannot do this on Secret, as later on the enclave needs to verify the contract address, and the only way to do this is to parse the memo of the original packet (which is signed by the relayer along with the ack/timeout) and compare it to the contract address that was given to the enclave. - // If the only available key in the memo is the callback, we should remove the memo - // from the data completely so the packet is sent without it. - // This way receiver chains that are on old versions of IBC will be able to process the packet - - callbackRaw := metadata[types.IBCCallbackKey] // This will be used later. - delete(metadata, types.IBCCallbackKey) - bzMetadata, err := json.Marshal(metadata) - if err != nil { - return sdkerrors.Wrap(err, "Send packet with callback error") - } - stringMetadata := string(bzMetadata) - if stringMetadata == "{}" { - data.Memo = "" - } else { - data.Memo = stringMetadata - } dataBytes, err := json.Marshal(data) if err != nil { return sdkerrors.Wrap(err, "Send packet with callback error") @@ -289,7 +273,7 @@ func (h WasmHooks) SendPacketOverride(i ICS4Middleware, ctx sdk.Context, chanCap } // Make sure the callback contract is a string and a valid bech32 addr. If it isn't, ignore this packet - contract, ok := callbackRaw.(string) + contract, ok := metadata[types.IBCCallbackKey].(string) if !ok { return nil } From 784408fc4e848ae777671cdd0669d3d46a5eb065 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 5 Jun 2023 00:17:55 +0300 Subject: [PATCH 51/54] Fix WASM Hooks incoming transfer intermediary account --- x/ibc-hooks/wasm_hook.go | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/x/ibc-hooks/wasm_hook.go b/x/ibc-hooks/wasm_hook.go index e8eebf20e..3331e50a1 100644 --- a/x/ibc-hooks/wasm_hook.go +++ b/x/ibc-hooks/wasm_hook.go @@ -63,24 +63,13 @@ func (h WasmHooks) OnRecvPacketOverride(im IBCMiddleware, ctx sdk.Context, packe return NewEmitErrorAcknowledgement(ctx, types.ErrMsgValidation) } - // Calculate the receiver / contract caller based on the packet's channel and sender - // Assaf: on Secret this later gets emptied out by the enclave. - // We cannot allow unsigned calls to MsgExecute, - // otherwise attackers would be able to run MsgExecute with a falsified sender. - channel := packet.GetDestChannel() - sender := data.GetSender() - senderBech32, err := keeper.DeriveIntermediateSender(channel, sender, h.bech32PrefixAccAddr) - if err != nil { - return NewEmitErrorAcknowledgement(ctx, types.ErrBadSender, fmt.Sprintf("cannot convert sender address %s/%s to bech32: %s", channel, sender, err.Error())) - } - // The funds sent on this packet need to be transferred to the intermediary account for the sender. // For this, we override the ICS20 packet's Receiver (essentially hijacking the funds to this new address) // and execute the underlying OnRecvPacket() call (which should eventually land on the transfer app's - // relay.go and send the sunds to the intermediary account. + // relay.go and send the funds to the intermediary account. // // If that succeeds, we make the contract call - data.Receiver = senderBech32 + data.Receiver = compute.ZeroSender.String() bz, err := json.Marshal(data) if err != nil { return NewEmitErrorAcknowledgement(ctx, types.ErrMarshaling, err.Error()) @@ -106,7 +95,8 @@ func (h WasmHooks) OnRecvPacketOverride(im IBCMiddleware, ctx sdk.Context, packe // Execute the contract execMsg := compute.MsgExecuteContract{ - Sender: sdk.MustAccAddressFromBech32(senderBech32), // emptied out later by the enclave + // Sender is ignored by the enclave, the contract sees a null msg.sender + Sender: compute.ZeroSender, Contract: contractAddr, Msg: msgBytes, SentFunds: funds, @@ -359,7 +349,7 @@ func (h WasmHooks) OnAcknowledgementPacketOverride(im IBCMiddleware, ctx sdk.Con } execMsg := compute.MsgExecuteContract{ - // Sender is ignored by the enclave, which passes a null msg.sender to the contract + // Sender is ignored by the enclave, the contract sees a null msg.sender Sender: compute.ZeroSender, Contract: contractAddr, Msg: msg, @@ -411,7 +401,7 @@ func (h WasmHooks) OnTimeoutPacketOverride(im IBCMiddleware, ctx sdk.Context, pa } execMsg := compute.MsgExecuteContract{ - // Sender is ignored by the enclave, which passes a null msg.sender to the contract + // Sender is ignored by the enclave, the contract sees a null msg.sender Sender: compute.ZeroSender, Contract: contractAddr, Msg: msg, From 95cff83f1e20d81262d5e94f9b32282c0459af49 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 5 Jun 2023 08:46:31 +0300 Subject: [PATCH 52/54] Fix TestIBCHooksOutgoingTransferAck() after fixing ack validation in 35199908ebe1ed2307872714f9a5eadf699c270b --- .../keeper/secret_contracts_exec_test.go | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_exec_test.go b/x/compute/internal/keeper/secret_contracts_exec_test.go index 198d3ad51..f1fd18e7b 100644 --- a/x/compute/internal/keeper/secret_contracts_exec_test.go +++ b/x/compute/internal/keeper/secret_contracts_exec_test.go @@ -2473,9 +2473,9 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { sdkMsgSrcChannel: "channel-0", sdkMsgDestPort: "transfer", sdkMsgDestChannel: "channel-1", - sdkMsgAck: "blabla", + sdkMsgAck: `{"result":"AQ=="}`, wasmInputSrcChannel: "channel-0", - wasmInputAck: "blabla", + wasmInputAck: "\\\"eyJyZXN1bHQiOiJBUT09In0=\\\"", wasmInputCoin: sdk.NewCoins(), ics20PacketSender: "", ics20PacketMemoSender: "", @@ -2487,9 +2487,9 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { sdkMsgSrcChannel: "channel-0", sdkMsgDestPort: "transfer", sdkMsgDestChannel: "channel-1", - sdkMsgAck: "blabla", + sdkMsgAck: `{"result":"AQ=="}`, wasmInputSrcChannel: "channel-0", - wasmInputAck: "blabla", + wasmInputAck: "\\\"eyJyZXN1bHQiOiJBUT09In0=\\\"", wasmInputCoin: sdk.NewCoins(), ics20PacketSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", ics20PacketMemoSender: "", @@ -2501,9 +2501,9 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { sdkMsgSrcChannel: "channel-0", sdkMsgDestPort: "transfer", sdkMsgDestChannel: "channel-1", - sdkMsgAck: "blabla", + sdkMsgAck: `{"result":"AQ=="}`, wasmInputSrcChannel: "channel-0", - wasmInputAck: "blabla", + wasmInputAck: "\\\"eyJyZXN1bHQiOiJBUT09In0=\\\"", wasmInputCoin: sdk.NewCoins(), ics20PacketSender: "", ics20PacketMemoSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", @@ -2515,9 +2515,9 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { sdkMsgSrcChannel: "channel-0", sdkMsgDestPort: "transfer", sdkMsgDestChannel: "channel-1", - sdkMsgAck: "blabla", + sdkMsgAck: `{"result":"AQ=="}`, wasmInputSrcChannel: "channel-0", - wasmInputAck: "blabla", + wasmInputAck: "\\\"eyJyZXN1bHQiOiJBUT09In0=\\\"", wasmInputCoin: sdk.NewCoins(), ics20PacketSender: "secret19e75l25r6sa6nhdf4lggjmgpw0vmpfvsw5cnpe", ics20PacketMemoSender: "secret1e8fnfznmgm67nud2uf2lrcvuy40pcdhrerph7v", @@ -2529,9 +2529,9 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { sdkMsgSrcChannel: "channel-0", sdkMsgDestPort: "transfer", sdkMsgDestChannel: "channel-1", - sdkMsgAck: "blabla", + sdkMsgAck: `{"result":"AQ=="}`, wasmInputSrcChannel: "channel-1", - wasmInputAck: "blabla", + wasmInputAck: "\\\"eyJyZXN1bHQiOiJBUT09In0=\\\"", wasmInputCoin: sdk.NewCoins(), ics20PacketSender: "", ics20PacketMemoSender: "", @@ -2543,9 +2543,9 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { sdkMsgSrcChannel: "channel-0", sdkMsgDestPort: "transfer", sdkMsgDestChannel: "channel-1", - sdkMsgAck: "blabla", + sdkMsgAck: `{"result":"AQ=="}`, wasmInputSrcChannel: "channel-0", - wasmInputAck: "blabla", + wasmInputAck: "\\\"eyJyZXN1bHQiOiJBUT09In0=\\\"", wasmInputCoin: sdk.NewCoins(sdk.NewInt64Coin("denom", 1)), ics20PacketSender: "", ics20PacketMemoSender: "", @@ -2559,7 +2559,7 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { sdkMsgDestChannel: "channel-1", sdkMsgAck: "yadayada", wasmInputSrcChannel: "channel-0", - wasmInputAck: "blabla", + wasmInputAck: "\\\"eyJyZXN1bHQiOiJBUT09In0=\\\"", wasmInputCoin: sdk.NewCoins(), ics20PacketSender: "", ics20PacketMemoSender: "", @@ -2633,7 +2633,7 @@ func TestIBCHooksOutgoingTransferAck(t *testing.T) { {Key: "contract_address", Value: contractAddress.String()}, {Key: "ibc_lifecycle_complete.ibc_ack.channel", Value: test.sdkMsgSrcChannel}, {Key: "ibc_lifecycle_complete.ibc_ack.sequence", Value: "0"}, - {Key: "ibc_lifecycle_complete.ibc_ack.ack", Value: test.sdkMsgAck}, + {Key: "ibc_lifecycle_complete.ibc_ack.ack", Value: strings.ReplaceAll(test.wasmInputAck, "\\", "")}, {Key: "ibc_lifecycle_complete.ibc_ack.success", Value: "true"}, }, }, From e9ab0555849a3331f939a082dab347e38498a9e5 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 5 Jun 2023 08:50:15 +0300 Subject: [PATCH 53/54] enclave-test.Dockerfile: Fix SGX apt pubkey error Like we did on 538ed0fc4c9e9289f05cdc1f59360d0d645cc410 for LocalSecret --- deployment/dockerfiles/tests/enclave-test.Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deployment/dockerfiles/tests/enclave-test.Dockerfile b/deployment/dockerfiles/tests/enclave-test.Dockerfile index 64fc484e9..7a58afd1c 100644 --- a/deployment/dockerfiles/tests/enclave-test.Dockerfile +++ b/deployment/dockerfiles/tests/enclave-test.Dockerfile @@ -1,6 +1,7 @@ FROM baiduxlab/sgx-rust:2004-1.1.3 -RUN apt-get update && \ +RUN add-apt-repository -r "deb https://download.01.org/intel-sgx/sgx_repo/ubuntu focal main" && \ + apt-get update && \ apt-get install -y --no-install-recommends \ #### Base utilities #### clang && \ From 8efdb858d6a30395532c12b88832c0c9e98f8128 Mon Sep 17 00:00:00 2001 From: Assaf Morami Date: Mon, 5 Jun 2023 11:43:13 +0300 Subject: [PATCH 54/54] Fix github merge issue --- app/keepers/keepers.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index cb90398cc..bc2970fbf 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -56,7 +56,6 @@ import ( icaauth "github.com/scrtlabs/SecretNetwork/x/mauth" icaauthkeeper "github.com/scrtlabs/SecretNetwork/x/mauth/keeper" icaauthtypes "github.com/scrtlabs/SecretNetwork/x/mauth/types" - icaauth "github.com/scrtlabs/SecretNetwork/x/mauth" reg "github.com/scrtlabs/SecretNetwork/x/registration" ibcpacketforward "github.com/strangelove-ventures/packet-forward-middleware/v4/router" ibcpacketforwardkeeper "github.com/strangelove-ventures/packet-forward-middleware/v4/router/keeper" @@ -68,7 +67,7 @@ import ( ibcswitch "github.com/scrtlabs/SecretNetwork/x/emergencybutton" ibcswitchtypes "github.com/scrtlabs/SecretNetwork/x/emergencybutton/types" - ibchooks "github.com/scrtlabs/SecretNetwork/x/ibc-hooks" + ibchooks "github.com/scrtlabs/SecretNetwork/x/ibc-hooks" ibchookskeeper "github.com/scrtlabs/SecretNetwork/x/ibc-hooks/keeper" ibchookstypes "github.com/scrtlabs/SecretNetwork/x/ibc-hooks/types" )