Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cosmrs: refactor into submodules #303

Merged
merged 1 commit into from Nov 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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};