Skip to content
This repository has been archived by the owner on Nov 20, 2024. It is now read-only.

Commit

Permalink
refactor: Refactor error handling in AnteDecorators
Browse files Browse the repository at this point in the history
  • Loading branch information
code0xff committed Sep 13, 2024
1 parent fddae57 commit f8411cd
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 124 deletions.
27 changes: 8 additions & 19 deletions frame/cosmos/x/auth/src/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ use cosmos_sdk_proto::cosmos::tx::v1beta1::Tx;
use pallet_cosmos_types::handler::AnteDecorator;
use sp_runtime::{
traits::Get,
transaction_validity::{
InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,
},
transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction},
SaturatedConversion,
};

Expand All @@ -35,15 +33,12 @@ where
{
fn ante_handle(tx: &Tx, _simulate: bool) -> TransactionValidity {
if tx.signatures.is_empty() {
return Err(TransactionValidityError::Invalid(InvalidTransaction::BadProof));
return Err(InvalidTransaction::BadProof.into());
}
let auth_info = tx
.auth_info
.as_ref()
.ok_or(TransactionValidityError::Invalid(InvalidTransaction::BadSigner))?;
let auth_info = tx.auth_info.as_ref().ok_or(InvalidTransaction::BadSigner)?;

if auth_info.signer_infos.len() != tx.signatures.len() {
return Err(TransactionValidityError::Invalid(InvalidTransaction::BadSigner));
return Err(InvalidTransaction::BadSigner.into());
}

Ok(ValidTransaction::default())
Expand All @@ -57,16 +52,13 @@ where
T: frame_system::Config,
{
fn ante_handle(tx: &Tx, _simulate: bool) -> TransactionValidity {
let body = tx
.body
.as_ref()
.ok_or(TransactionValidityError::Invalid(InvalidTransaction::Call))?;
let body = tx.body.as_ref().ok_or(InvalidTransaction::Call)?;

if body.timeout_height > 0 &&
frame_system::Pallet::<T>::block_number().saturated_into::<u64>() >
body.timeout_height
{
return Err(TransactionValidityError::Invalid(InvalidTransaction::Stale));
return Err(InvalidTransaction::Stale.into());
}

Ok(ValidTransaction::default())
Expand All @@ -80,13 +72,10 @@ where
T: pallet_cosmos::Config,
{
fn ante_handle(tx: &Tx, _simulate: bool) -> TransactionValidity {
let body = tx
.body
.as_ref()
.ok_or(TransactionValidityError::Invalid(InvalidTransaction::Call))?;
let body = tx.body.as_ref().ok_or(InvalidTransaction::Call)?;

if body.memo.len().saturated_into::<u64>() > T::MaxMemoCharacters::get() {
return Err(TransactionValidityError::Invalid(InvalidTransaction::Call));
return Err(InvalidTransaction::Call.into());
}

Ok(ValidTransaction::default())
Expand Down
30 changes: 13 additions & 17 deletions frame/cosmos/x/auth/src/fee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use pallet_cosmos_x_auth_signing::sign_verifiable_tx::traits::SigVerifiableTx;
use sp_core::{Get, H160};
use sp_runtime::{
traits::{Convert, Zero},
transaction_validity::{TransactionValidity, TransactionValidityError, ValidTransaction},
transaction_validity::{TransactionValidity, ValidTransaction},
SaturatedConversion,
};

Expand All @@ -55,13 +55,13 @@ where
.auth_info
.as_ref()
.and_then(|auth_info| auth_info.fee.as_ref())
.ok_or(TransactionValidityError::Invalid(InvalidTransaction::Call))?;
.ok_or(InvalidTransaction::Call)?;

if !simulate &&
!frame_system::Pallet::<T>::block_number().is_zero() &&
fee.gas_limit.is_zero()
{
return Err(TransactionValidityError::Invalid(InvalidTransaction::Call));
return Err(InvalidTransaction::Call.into());
}

// TODO: Implements txFeeChecker
Expand All @@ -77,24 +77,23 @@ where
T: pallet_cosmos::Config,
{
fn check_deduct_fee(tx: &Tx) -> TransactionValidity {
let fee_payer = T::SigVerifiableTx::fee_payer(tx)
.map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::Call))?;
let fee_payer = T::SigVerifiableTx::fee_payer(tx).map_err(|_| InvalidTransaction::Call)?;

let fee = tx
.auth_info
.as_ref()
.and_then(|auth_info| auth_info.fee.as_ref())
.ok_or(TransactionValidityError::Invalid(InvalidTransaction::Call))?;
.ok_or(InvalidTransaction::Call)?;

// TODO: Fee granter not supported
if !fee.granter.is_empty() {
return Err(TransactionValidityError::Invalid(InvalidTransaction::Call));
return Err(InvalidTransaction::Call.into());
}

let (_hrp, address_raw) = acc_address_from_bech32(&fee_payer)
.map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::BadSigner))?;
let (_hrp, address_raw) =
acc_address_from_bech32(&fee_payer).map_err(|_| InvalidTransaction::BadSigner)?;
if address_raw.len() != 20 {
return Err(TransactionValidityError::Invalid(InvalidTransaction::BadSigner));
return Err(InvalidTransaction::BadSigner.into());
}
let deduct_fees_from = T::AddressMapping::into_account_id(H160::from_slice(&address_raw));

Expand All @@ -121,10 +120,7 @@ where

fn deduct_fees(acc: &T::AccountId, fee: &Fee) -> TransactionValidity {
for amt in fee.amount.iter() {
let amount = amt
.amount
.parse::<u128>()
.map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::Call))?;
let amount = amt.amount.parse::<u128>().map_err(|_| InvalidTransaction::Call)?;

if amt.denom == T::NativeDenom::get() {
let _imbalance = T::NativeAsset::withdraw(
Expand All @@ -133,12 +129,12 @@ where
WithdrawReasons::TRANSACTION_PAYMENT,
ExistenceRequirement::KeepAlive,
)
.map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::Payment))?;
.map_err(|_| InvalidTransaction::Payment)?;

// TODO: Resolve imbalance
} else {
let asset_id = T::AssetToDenom::convert(amt.denom.clone())
.map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::Call))?;
.map_err(|_| InvalidTransaction::Call)?;

let _imbalance = T::Assets::withdraw(
asset_id,
Expand All @@ -148,7 +144,7 @@ where
Preservation::Preserve,
Fortitude::Polite,
)
.map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::Payment))?;
.map_err(|_| InvalidTransaction::Payment)?;

// TODO: Resolve imbalance
}
Expand Down
11 changes: 3 additions & 8 deletions frame/cosmos/x/auth/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
use cosmos_sdk_proto::cosmos::tx::v1beta1::Tx;
use frame_support::traits::Contains;
use pallet_cosmos_types::handler::AnteDecorator;
use sp_runtime::transaction_validity::{
InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,
};
use sp_runtime::transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction};

pub struct KnownMsgDecorator<T>(core::marker::PhantomData<T>);

Expand All @@ -30,14 +28,11 @@ where
T: pallet_cosmos::Config,
{
fn ante_handle(tx: &Tx, _simulate: bool) -> TransactionValidity {
let body = tx
.body
.as_ref()
.ok_or(TransactionValidityError::Invalid(InvalidTransaction::Call))?;
let body = tx.body.as_ref().ok_or(InvalidTransaction::Call)?;

for msg in body.messages.iter() {
if !T::MsgFilter::contains(msg) {
return Err(TransactionValidityError::Invalid(InvalidTransaction::Call));
return Err(InvalidTransaction::Call.into());
}
}

Expand Down
79 changes: 30 additions & 49 deletions frame/cosmos/x/auth/src/sigverify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,51 +50,41 @@ where
{
fn ante_handle(tx: &Tx, _simulate: bool) -> TransactionValidity {
let signatures = &tx.signatures;
let signers = T::SigVerifiableTx::get_signers(tx)
.map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::BadSigner))?;
let signers =
T::SigVerifiableTx::get_signers(tx).map_err(|_| InvalidTransaction::BadSigner)?;

let auth_info = tx
.auth_info
.as_ref()
.ok_or(TransactionValidityError::Invalid(InvalidTransaction::BadSigner))?;
let auth_info = tx.auth_info.as_ref().ok_or(InvalidTransaction::BadSigner)?;
if signatures.len() != signers.len() {
return Err(TransactionValidityError::Invalid(InvalidTransaction::BadSigner));
return Err(InvalidTransaction::BadSigner.into());
}

if signatures.len() != auth_info.signer_infos.len() {
return Err(TransactionValidityError::Invalid(InvalidTransaction::BadSigner));
return Err(InvalidTransaction::BadSigner.into());
}

for (i, sig) in signatures.iter().enumerate() {
let signer = signers
.get(i)
.ok_or(TransactionValidityError::Invalid(InvalidTransaction::BadSigner))?;
let signer = signers.get(i).ok_or(InvalidTransaction::BadSigner)?;

let signer_info = auth_info
.signer_infos
.get(i)
.ok_or(TransactionValidityError::Invalid(InvalidTransaction::BadSigner))?;
let signer_info = auth_info.signer_infos.get(i).ok_or(InvalidTransaction::BadSigner)?;

let (_hrp, signer_addr_raw) = acc_address_from_bech32(signer)
.map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::BadSigner))?;
let (_hrp, signer_addr_raw) =
acc_address_from_bech32(signer).map_err(|_| InvalidTransaction::BadSigner)?;

if signer_addr_raw.len() != 20 {
return Err(TransactionValidityError::Invalid(InvalidTransaction::BadSigner));
return Err(InvalidTransaction::BadSigner.into());
}

let who = T::AddressMapping::into_account_id(H160::from_slice(&signer_addr_raw));
let sequence = frame_system::Pallet::<T>::account_nonce(&who).saturated_into();

if signer_info.sequence > sequence {
return Err(TransactionValidityError::Invalid(InvalidTransaction::Future));
return Err(InvalidTransaction::Future.into());
} else if signer_info.sequence < sequence {
return Err(TransactionValidityError::Invalid(InvalidTransaction::Stale));
return Err(InvalidTransaction::Stale.into());
}

let public_key = signer_info
.public_key
.as_ref()
.ok_or(TransactionValidityError::Invalid(InvalidTransaction::BadSigner))?;
let public_key =
signer_info.public_key.as_ref().ok_or(InvalidTransaction::BadSigner)?;
let chain_id = T::ChainId::get().to_string();
let signer_data = SignerData {
address: signer.clone(),
Expand All @@ -104,10 +94,7 @@ where
pub_key: public_key.clone(),
};

let sign_mode = signer_info
.mode_info
.as_ref()
.ok_or(TransactionValidityError::Invalid(InvalidTransaction::BadSigner))?;
let sign_mode = signer_info.mode_info.as_ref().ok_or(InvalidTransaction::BadSigner)?;

Self::verify_signature(public_key, &signer_data, sign_mode, sig, tx)?;
}
Expand All @@ -132,36 +119,36 @@ where
secp256k1::PubKey => {
let public_key =
secp256k1::PubKey::decode(&mut &*public_key.value).map_err(|_| {
TransactionValidityError::Invalid(InvalidTransaction::BadSigner)
InvalidTransaction::BadSigner
})?;
let mut hasher = ripemd::Ripemd160::new();
hasher.update(sha2_256(&public_key.key));
let address = H160::from_slice(&hasher.finalize());

let (_hrp, signer_addr_raw) =
acc_address_from_bech32(&signer_data.address).map_err(|_| {
TransactionValidityError::Invalid(InvalidTransaction::BadSigner)
InvalidTransaction::BadSigner
})?;

if signer_addr_raw.len() != 20 {
return Err(TransactionValidityError::Invalid(InvalidTransaction::BadSigner));
return Err(InvalidTransaction::BadSigner.into());
}

if H160::from_slice(&signer_addr_raw) != address {
return Err(TransactionValidityError::Invalid(InvalidTransaction::BadSigner));
return Err(InvalidTransaction::BadSigner.into());
}

let sign_bytes = T::SignModeHandler::get_sign_bytes(sign_mode, signer_data, tx)
.map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::Call))?;
.map_err(|_| InvalidTransaction::Call)?;

if !secp256k1_ecdsa_verify(signature, &sha2_256(&sign_bytes), &public_key.key) {
return Err(TransactionValidityError::Invalid(InvalidTransaction::BadProof));
return Err(InvalidTransaction::BadProof.into());
}

Ok(())
}
},
Err(TransactionValidityError::Invalid(InvalidTransaction::BadSigner))
Err(InvalidTransaction::BadSigner.into())
)
}
}
Expand All @@ -175,18 +162,13 @@ where
fn ante_handle(tx: &Tx, _simulate: bool) -> TransactionValidity {
let mut sig_count = 0u64;

let auth_info = tx
.auth_info
.as_ref()
.ok_or(TransactionValidityError::Invalid(InvalidTransaction::BadSigner))?;
let auth_info = tx.auth_info.as_ref().ok_or(InvalidTransaction::BadSigner)?;
for SignerInfo { public_key, .. } in auth_info.signer_infos.iter() {
let public_key = public_key
.as_ref()
.ok_or(TransactionValidityError::Invalid(InvalidTransaction::BadSigner))?;
let public_key = public_key.as_ref().ok_or(InvalidTransaction::BadSigner)?;
sig_count = sig_count.saturating_add(Self::count_sub_keys(public_key)?);

if sig_count > T::TxSigLimit::get() {
return Err(TransactionValidityError::Invalid(InvalidTransaction::BadProof));
return Err(InvalidTransaction::BadProof.into());
}
}

Expand All @@ -198,7 +180,7 @@ impl<T> ValidateSigCountDecorator<T> {
fn count_sub_keys(pubkey: &Any) -> Result<u64, TransactionValidityError> {
// TODO: Support legacy multi signatures.
if LegacyAminoPubKey::decode(&mut &*pubkey.value).is_ok() {
Err(TransactionValidityError::Invalid(InvalidTransaction::BadProof))
Err(InvalidTransaction::BadProof.into())
} else {
Ok(1)
}
Expand All @@ -212,13 +194,12 @@ where
T: frame_system::Config + pallet_cosmos::Config,
{
fn ante_handle(tx: &Tx, _simulate: bool) -> TransactionValidity {
let signers = T::SigVerifiableTx::get_signers(tx)
.map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::Call))?;
let signers = T::SigVerifiableTx::get_signers(tx).map_err(|_| InvalidTransaction::Call)?;
for signer in signers.iter() {
let (_hrp, address_raw) = acc_address_from_bech32(signer)
.map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::BadSigner))?;
let (_hrp, address_raw) =
acc_address_from_bech32(signer).map_err(|_| InvalidTransaction::BadSigner)?;
if address_raw.len() != 20 {
return Err(TransactionValidityError::Invalid(InvalidTransaction::BadSigner));
return Err(InvalidTransaction::BadSigner.into());
}

let account = T::AddressMapping::into_account_id(H160::from_slice(&address_raw));
Expand Down
Loading

0 comments on commit f8411cd

Please sign in to comment.