diff --git a/cosmrs/.idea/workspace.xml b/cosmrs/.idea/workspace.xml
new file mode 100644
index 00000000..5f0fccb3
--- /dev/null
+++ b/cosmrs/.idea/workspace.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ "associatedIndex": 7
+}
+
+
+
+
+
+ {
+ "keyToString": {
+ "RunOnceActivity.ShowReadmeOnStart": "true",
+ "RunOnceActivity.rust.reset.selective.auto.import": "true",
+ "last_opened_file_path": "/Users/jedrzej/workspace/cosmos-rust-fork/cosmos-rust/cosmrs",
+ "node.js.detected.package.eslint": "true",
+ "node.js.selected.package.eslint": "(autodetect)",
+ "nodejs_package_manager_path": "npm",
+ "org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
+ "org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "",
+ "org.rust.first.attach.projects": "true",
+ "settings.editor.selected.configurable": "language.rust.cargo.check"
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+ 1718192228740
+
+
+ 1718192228740
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cosmrs/src/abci.rs b/cosmrs/src/abci.rs
index c26daa32..7bb967a5 100644
--- a/cosmrs/src/abci.rs
+++ b/cosmrs/src/abci.rs
@@ -5,7 +5,7 @@ mod msg_data;
pub use self::{
gas_info::GasInfo,
- msg_data::{MsgData, TxMsgData},
+ msg_data::{MsgData, TxMsgData, MsgResponse},
};
/// Transaction data.
diff --git a/cosmrs/src/abci/msg_data.rs b/cosmrs/src/abci/msg_data.rs
index 22706546..17f4f1a2 100644
--- a/cosmrs/src/abci/msg_data.rs
+++ b/cosmrs/src/abci/msg_data.rs
@@ -1,13 +1,14 @@
use super::Data;
use crate::{
- proto::{self, traits::Message},
+ proto::{self, traits::Message, Any},
tx::Msg,
ErrorReport, Result,
};
use eyre::eyre;
+use serde::{Deserialize, Serialize};
/// MsgData defines the data returned in a Result object during message execution.
-#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
+#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct MsgData {
/// Incoming message type that emitted this result data, for example `"/cosmos.bank.v1beta1.MsgSend"`.
pub msg_type: String,
@@ -50,13 +51,52 @@ impl From for proto::cosmos::base::abci::v1beta1::MsgData {
}
}
+/// The messages responses of the TxMsgData. Corresponds to `Any`
+#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
+pub struct MsgResponse {
+ /// Response message type that emitted this result data, for example `"/cosmwasm.wasm.v1.MsgExecuteContractResponse"`.
+ pub type_url: String,
+
+ /// Binary data emitted by this response.
+ pub value: Vec,
+}
+
+impl MsgResponse {
+ /// Attempts to decode the `data` field of this result into the specified `Msg` type.
+ pub fn try_decode_as(&self) -> Result {
+ M::Proto::decode(&*self.value)?.try_into()
+ }
+}
+
+impl From for MsgResponse {
+ fn from(any: Any) -> Self {
+ MsgResponse {
+ type_url: any.type_url,
+ value: any.value,
+ }
+ }
+}
+
+impl From for Any {
+ fn from(msg_response: MsgResponse) -> Self {
+ Any {
+ type_url: msg_response.type_url,
+ value: msg_response.value,
+ }
+ }
+}
+
/// TxMsgData defines a list of MsgData. A transaction will have a MsgData object for each message.
-#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
+#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct TxMsgData {
/// Data emitted by the messages in a particular transaction.
// Note: this field will be deprecated and not populated as of cosmos-sdk 0.46.
// It will be superseded by `msg_responses` field of type Vec
pub data: Vec,
+
+ /// This field contains the Msg handler responses packed into Anys.
+ // Note: this field is an empty vec for chains running cosmos-sdk < 0.46.
+ pub msg_responses: Vec,
}
impl TryFrom for TxMsgData {
@@ -76,9 +116,11 @@ impl TryFrom for TxMsgData {
#[allow(deprecated)]
fn try_from(proto: proto::cosmos::base::abci::v1beta1::TxMsgData) -> Result {
- // TODO(tarcieri): parse `msg_responses`
- if !proto.msg_responses.is_empty() {
- return Err(eyre!("TxMsgData::msg_responses unsupported"));
+ // this case should be impossible as with the switch in cosmos-sdk 0.46 only one of those should contain any data
+ if !proto.msg_responses.is_empty() && !proto.data.is_empty() {
+ return Err(eyre!(
+ "TxMsgData: both msg_responses and data fields are populated"
+ ));
}
Ok(TxMsgData {
@@ -87,6 +129,7 @@ impl TryFrom for TxMsgData {
.into_iter()
.map(TryFrom::try_from)
.collect::>()?,
+ msg_responses: proto.msg_responses.into_iter().map(Into::into).collect(),
})
}
}
@@ -96,7 +139,11 @@ impl From for proto::cosmos::base::abci::v1beta1::TxMsgData {
fn from(tx_msg_data: TxMsgData) -> Self {
proto::cosmos::base::abci::v1beta1::TxMsgData {
data: tx_msg_data.data.into_iter().map(Into::into).collect(),
- msg_responses: vec![], // TODO(tarcieri): serialize responses
+ msg_responses: tx_msg_data
+ .msg_responses
+ .into_iter()
+ .map(Into::into)
+ .collect(),
}
}
}