Skip to content

Commit

Permalink
cosmrs: refactor into submodules (#303)
Browse files Browse the repository at this point in the history
Factors code out of toplevel modules (which map 1:1 to the Go modules)
into type-specific submodules.

This makes it easier to locate the definition of a specific type by
filename, and generally makes it easier to peruse the codebase.
  • Loading branch information
tony-iqlusion committed Nov 8, 2022
1 parent 918d78f commit 3d05c50
Show file tree
Hide file tree
Showing 49 changed files with 2,599 additions and 2,434 deletions.
130 changes: 7 additions & 123 deletions cosmrs/src/abci.rs
@@ -1,128 +1,12 @@
//! Abci-related functionality
//! Application/BlockChain Interface (ABCI)-related functionality.

use crate::{
proto::{self, traits::Message},
tx::Msg,
ErrorReport, Gas, Result,
mod gas_info;
mod msg_data;

pub use self::{
gas_info::GasInfo,
msg_data::{MsgData, TxMsgData},
};
use serde::{Deserialize, Serialize};

/// Transaction data.
pub type Data = Vec<u8>;

/// MsgData defines the data returned in a Result object during message execution.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct MsgData {
/// Incoming message type that emitted this result data, for example `"/cosmos.bank.v1beta1.MsgSend"`.
pub msg_type: String,

/// Binary data emitted by this message.
// Do note that usually the data has to be decoded into the corresponding protobuf `Response` type.
// For example, if the data was emitted as a result of a `MsgSend`, i.e. `msg.msg_type == "/cosmos.bank.v1beta1.MsgSend"`,
// then you should decode it into `"/cosmos.bank.v1beta1.MsgSendResponse"
pub data: Vec<u8>,
}

impl MsgData {
/// Attempts to decode the `data` field of this result into the specified `Msg` type.
pub fn try_decode_as<M: Msg>(&self) -> Result<M> {
M::Proto::decode(&*self.data)?.try_into()
}
}

impl Msg for MsgData {
type Proto = proto::cosmos::base::abci::v1beta1::MsgData;
}

impl TryFrom<proto::cosmos::base::abci::v1beta1::MsgData> for MsgData {
type Error = ErrorReport;

fn try_from(proto: proto::cosmos::base::abci::v1beta1::MsgData) -> Result<MsgData> {
Ok(MsgData {
msg_type: proto.msg_type,
data: proto.data,
})
}
}

impl From<MsgData> for proto::cosmos::base::abci::v1beta1::MsgData {
fn from(msg_data: MsgData) -> Self {
proto::cosmos::base::abci::v1beta1::MsgData {
msg_type: msg_data.msg_type,
data: msg_data.data,
}
}
}

/// TxMsgData defines a list of MsgData. A transaction will have a MsgData object for each message.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
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<Any>
pub data: Vec<MsgData>,
}

impl TryFrom<Data> for TxMsgData {
type Error = ErrorReport;

fn try_from(data: Data) -> Result<TxMsgData> {
proto::cosmos::base::abci::v1beta1::TxMsgData::decode(data.as_ref())?.try_into()
}
}

impl Msg for TxMsgData {
type Proto = proto::cosmos::base::abci::v1beta1::TxMsgData;
}

impl TryFrom<proto::cosmos::base::abci::v1beta1::TxMsgData> for TxMsgData {
type Error = ErrorReport;

fn try_from(proto: proto::cosmos::base::abci::v1beta1::TxMsgData) -> Result<TxMsgData> {
Ok(TxMsgData {
data: proto
.data
.into_iter()
.map(TryFrom::try_from)
.collect::<Result<_, _>>()?,
})
}
}

impl From<TxMsgData> 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(),
}
}
}

/// GasInfo defines tx execution gas context.
#[derive(Copy, Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
pub struct GasInfo {
/// GasWanted is the maximum units of work we allow this tx to perform.
pub gas_wanted: Gas,

/// GasUsed is the amount of gas actually consumed.
pub gas_used: Gas,
}

impl TryFrom<proto::cosmos::base::abci::v1beta1::GasInfo> for GasInfo {
type Error = ErrorReport;

fn try_from(proto: proto::cosmos::base::abci::v1beta1::GasInfo) -> Result<GasInfo> {
Ok(GasInfo {
gas_wanted: proto.gas_wanted,
gas_used: proto.gas_used,
})
}
}

impl From<GasInfo> for proto::cosmos::base::abci::v1beta1::GasInfo {
fn from(info: GasInfo) -> Self {
proto::cosmos::base::abci::v1beta1::GasInfo {
gas_wanted: info.gas_wanted,
gas_used: info.gas_wanted,
}
}
}
33 changes: 33 additions & 0 deletions cosmrs/src/abci/gas_info.rs
@@ -0,0 +1,33 @@
use crate::{proto, ErrorReport, Gas, Result};
use serde::{Deserialize, Serialize};

/// [`GasInfo`] defines constraints for how much gas to use to execute a
/// transaction.
#[derive(Copy, Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
pub struct GasInfo {
/// GasWanted is the maximum units of work we allow this tx to perform.
pub gas_wanted: Gas,

/// GasUsed is the amount of gas actually consumed.
pub gas_used: Gas,
}

impl TryFrom<proto::cosmos::base::abci::v1beta1::GasInfo> for GasInfo {
type Error = ErrorReport;

fn try_from(proto: proto::cosmos::base::abci::v1beta1::GasInfo) -> Result<GasInfo> {
Ok(GasInfo {
gas_wanted: proto.gas_wanted,
gas_used: proto.gas_used,
})
}
}

impl From<GasInfo> for proto::cosmos::base::abci::v1beta1::GasInfo {
fn from(info: GasInfo) -> Self {
proto::cosmos::base::abci::v1beta1::GasInfo {
gas_wanted: info.gas_wanted,
gas_used: info.gas_wanted,
}
}
}
93 changes: 93 additions & 0 deletions cosmrs/src/abci/msg_data.rs
@@ -0,0 +1,93 @@
use super::Data;
use crate::{
proto::{self, traits::Message},
tx::Msg,
ErrorReport, Result,
};

/// MsgData defines the data returned in a Result object during message execution.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct MsgData {
/// Incoming message type that emitted this result data, for example `"/cosmos.bank.v1beta1.MsgSend"`.
pub msg_type: String,

/// Binary data emitted by this message.
// Do note that usually the data has to be decoded into the corresponding protobuf `Response` type.
// For example, if the data was emitted as a result of a `MsgSend`, i.e. `msg.msg_type == "/cosmos.bank.v1beta1.MsgSend"`,
// then you should decode it into `"/cosmos.bank.v1beta1.MsgSendResponse"
pub data: Vec<u8>,
}

impl MsgData {
/// Attempts to decode the `data` field of this result into the specified `Msg` type.
pub fn try_decode_as<M: Msg>(&self) -> Result<M> {
M::Proto::decode(&*self.data)?.try_into()
}
}

impl Msg for MsgData {
type Proto = proto::cosmos::base::abci::v1beta1::MsgData;
}

impl TryFrom<proto::cosmos::base::abci::v1beta1::MsgData> for MsgData {
type Error = ErrorReport;

fn try_from(proto: proto::cosmos::base::abci::v1beta1::MsgData) -> Result<MsgData> {
Ok(MsgData {
msg_type: proto.msg_type,
data: proto.data,
})
}
}

impl From<MsgData> for proto::cosmos::base::abci::v1beta1::MsgData {
fn from(msg_data: MsgData) -> Self {
proto::cosmos::base::abci::v1beta1::MsgData {
msg_type: msg_data.msg_type,
data: msg_data.data,
}
}
}

/// TxMsgData defines a list of MsgData. A transaction will have a MsgData object for each message.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
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<Any>
pub data: Vec<MsgData>,
}

impl TryFrom<Data> for TxMsgData {
type Error = ErrorReport;

fn try_from(data: Data) -> Result<TxMsgData> {
proto::cosmos::base::abci::v1beta1::TxMsgData::decode(data.as_ref())?.try_into()
}
}

impl Msg for TxMsgData {
type Proto = proto::cosmos::base::abci::v1beta1::TxMsgData;
}

impl TryFrom<proto::cosmos::base::abci::v1beta1::TxMsgData> for TxMsgData {
type Error = ErrorReport;

fn try_from(proto: proto::cosmos::base::abci::v1beta1::TxMsgData) -> Result<TxMsgData> {
Ok(TxMsgData {
data: proto
.data
.into_iter()
.map(TryFrom::try_from)
.collect::<Result<_, _>>()?,
})
}
}

impl From<TxMsgData> 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(),
}
}
}
86 changes: 4 additions & 82 deletions cosmrs/src/auth.rs
@@ -1,84 +1,6 @@
//! Auth functionality.
//! Authentication module: AuthN-related functionality.

use crate::crypto::PublicKey;
use crate::tx::{AccountNumber, SequenceNumber};
use crate::Result;
use crate::{proto, AccountId, ErrorReport};
mod base_account;
mod module_account;

/// BaseAccount defines a base account type. It contains all the necessary fields
/// for basic account functionality. Any custom account type should extend this
/// type for additional functionality (e.g. vesting).
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct BaseAccount {
/// Bech32 [`AccountId`] of this account.
pub address: AccountId,

/// Optional [`PublicKey`] associated with this account.
pub pubkey: Option<PublicKey>,

/// `account_number` is the account number of the account in state
pub account_number: AccountNumber,

/// Sequence of the account, which describes the number of committed transactions signed by a
/// given address.
pub sequence: SequenceNumber,
}

impl TryFrom<proto::cosmos::auth::v1beta1::BaseAccount> for BaseAccount {
type Error = ErrorReport;

fn try_from(proto: proto::cosmos::auth::v1beta1::BaseAccount) -> Result<BaseAccount> {
Ok(BaseAccount {
address: proto.address.parse()?,
pubkey: proto.pub_key.map(PublicKey::try_from).transpose()?,
account_number: proto.account_number,
sequence: proto.sequence,
})
}
}

impl From<BaseAccount> for proto::cosmos::auth::v1beta1::BaseAccount {
fn from(account: BaseAccount) -> proto::cosmos::auth::v1beta1::BaseAccount {
proto::cosmos::auth::v1beta1::BaseAccount {
address: account.address.to_string(),
pub_key: account.pubkey.map(Into::into),
account_number: account.account_number,
sequence: account.sequence,
}
}
}

/// ModuleAccount defines an account for modules that holds coins on a pool.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ModuleAccount {
/// [`BaseAccount`] specification of this module account.
pub base_account: Option<BaseAccount>,

/// Name of the module.
pub name: String,

/// Permissions associated with this module account.
pub permissions: Vec<String>,
}

impl TryFrom<proto::cosmos::auth::v1beta1::ModuleAccount> for ModuleAccount {
type Error = ErrorReport;

fn try_from(proto: proto::cosmos::auth::v1beta1::ModuleAccount) -> Result<ModuleAccount> {
Ok(ModuleAccount {
base_account: proto.base_account.map(TryFrom::try_from).transpose()?,
name: proto.name,
permissions: proto.permissions,
})
}
}

impl From<ModuleAccount> for proto::cosmos::auth::v1beta1::ModuleAccount {
fn from(account: ModuleAccount) -> proto::cosmos::auth::v1beta1::ModuleAccount {
proto::cosmos::auth::v1beta1::ModuleAccount {
base_account: account.base_account.map(Into::into),
name: account.name,
permissions: account.permissions,
}
}
}
pub use self::{base_account::BaseAccount, module_account::ModuleAccount};

0 comments on commit 3d05c50

Please sign in to comment.