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

Fix transfer triggered vps #3804

Merged
merged 26 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
fbc328f
Transfers trigger internal vps of destinations
grarco Sep 10, 2024
a62a2bc
Account for gas errors in pgf vp
grarco Sep 10, 2024
ccbb457
Multitoken vp ensures internal addresses verify the transaction
grarco Sep 10, 2024
fc39308
Adds clippy lint to avoid `unwrap_or_default` on `Result`s
grarco Sep 10, 2024
cd3f5a1
Multitoken vp ensures debited accounts' vps are triggered
grarco Sep 10, 2024
77ad90e
Fixes broken ibc unit test
grarco Sep 10, 2024
f8cfe7b
Requests verification from both transfer's source and destination
grarco Sep 11, 2024
6e52f37
Fixes unit tests
grarco Sep 11, 2024
07035e0
Updates gas limit and fixes masp tests
grarco Sep 12, 2024
664ee16
Extracts receiver from ibc envelope and requests verification
grarco Sep 12, 2024
439a3a6
IBC verifiers also for failed acks and timeouts
grarco Sep 12, 2024
c82a4fd
Adds some timeouts in ibc e2e test
grarco Sep 12, 2024
578eb0e
Extracts ibc envelope verifiers to a separate function
grarco Sep 12, 2024
8799b26
Refactors IBC envelope verifier
grarco Sep 12, 2024
c74695c
Inserts verifier before executing IBC enevelope and does not fail on …
grarco Sep 12, 2024
1651cad
Unit tests verifiers in multitoken vp
grarco Sep 13, 2024
2fb578d
MASP VP evaluates its balance. Adds unit test
grarco Sep 13, 2024
160f8b5
Improves ibc e2e test
grarco Sep 13, 2024
1ae3919
Removes useless timeouts in ibc test
grarco Sep 13, 2024
902b06a
Removes system cross dep
grarco Sep 13, 2024
5c19027
Updates lock files for wasm
grarco Sep 13, 2024
e597347
add a test for masp balance key
tzemanovic Sep 14, 2024
b634d91
Changelog #3804
grarco Sep 13, 2024
5d5e9db
Fixes doc lint
grarco Sep 15, 2024
b11c556
check gaia balance
yito88 Sep 16, 2024
41583eb
Fixes wrong error type for ibc envelope
grarco Sep 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- The multitoken vp now checks that the involved parties
validate the transaction. Improved tests and transfer code.
([\#3804](https://github.com/anoma/namada/pull/3804))
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ disallowed-methods = [
{ path = "chrono::Utc::now", reason = "Do not use current date/time in code that must be deterministic" },
{ path = "namada_core::time::DateTimeUtc::now", reason = "Do not use current date/time in code that must be deterministic" },
{ path = "wasmtimer::std::Instant", reason = "Do not use current date/time in code that must be deterministic" },
{ path = "std::result::Result::unwrap_or_default", reason = "Do not silently ignore an error that could be caused by gas" },
]
allow-dbg-in-tests = true
allow-print-in-tests = true
1 change: 1 addition & 0 deletions crates/apps_lib/src/client/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,7 @@ pub async fn sign_genesis_tx(
if let Some(output_path) = output.as_ref() {
// If the output path contains existing signed txs, we append
// the newly signed txs to the file
#[allow(clippy::disallowed_methods)]
let mut prev_txs =
genesis::templates::read_transactions(output_path)
.unwrap_or_default();
Expand Down
1 change: 1 addition & 0 deletions crates/governance/src/finalize_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ where
if vote.is_validator() {
let vote_data = vote.data.clone();

#[allow(clippy::disallowed_methods)]
tzemanovic marked this conversation as resolved.
Show resolved Hide resolved
let validator_stake = PoS::read_validator_stake::<crate::Store<_>>(
storage, validator, epoch,
)
Expand Down
1 change: 1 addition & 0 deletions crates/governance/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ impl ProposalResult {
/// Return true if at least 2/3 of the total voting power voted and at least
/// two third of the non-abstained voting power voted nay.
/// Returns `false` if any arithmetic fails.
#[allow(clippy::disallowed_methods)]
pub fn two_thirds_nay_over_two_thirds_total(&self) -> bool {
(|| {
let two_thirds_power =
Expand Down
11 changes: 3 additions & 8 deletions crates/governance/src/vp/pgf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,10 @@ where
match key_type {
KeyType::Stewards(steward_address) => {
let stewards_have_increased = {
// TODO(namada#3238): we should check errors here, which
// could be out-of-gas related
let total_stewards_pre = pgf_storage::stewards_handle()
.len(&ctx.pre())
.unwrap_or_default();
let total_stewards_pre =
pgf_storage::stewards_handle().len(&ctx.pre())?;
let total_stewards_post =
pgf_storage::stewards_handle()
.len(&ctx.post())
.unwrap_or_default();
pgf_storage::stewards_handle().len(&ctx.post())?;

total_stewards_pre < total_stewards_post
};
Expand Down
110 changes: 109 additions & 1 deletion crates/ibc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use std::collections::BTreeSet;
use std::fmt::Debug;
use std::marker::PhantomData;
use std::rc::Rc;
use std::str::FromStr;

pub use actions::transfer_over_ibc;
use apps::transfer::types::packet::PacketData;
Expand All @@ -54,13 +55,16 @@ use ibc::apps::nft_transfer::types::msgs::transfer::MsgTransfer as IbcMsgNftTran
use ibc::apps::nft_transfer::types::{
ack_success_b64, is_receiver_chain_source as is_nft_receiver_chain_source,
PrefixedClassId, TokenId, TracePrefix as NftTracePrefix,
PORT_ID_STR as NFT_PORT_ID_STR,
};
use ibc::apps::transfer::handler::{
send_transfer_execute, send_transfer_validate,
};
use ibc::apps::transfer::types::error::TokenTransferError;
use ibc::apps::transfer::types::msgs::transfer::MsgTransfer as IbcMsgTransfer;
use ibc::apps::transfer::types::{is_receiver_chain_source, TracePrefix};
use ibc::apps::transfer::types::{
is_receiver_chain_source, TracePrefix, PORT_ID_STR as FT_PORT_ID_STR,
};
use ibc::core::channel::types::acknowledgement::AcknowledgementStatus;
use ibc::core::channel::types::commitment::compute_ack_commitment;
use ibc::core::channel::types::msgs::{
Expand Down Expand Up @@ -139,6 +143,8 @@ pub enum Error {
ChainId(IdentifierError),
#[error("Verifier insertion error: {0}")]
Verifier(StorageError),
#[error("IBC error: {0}")]
Other(String),
}

impl From<Error> for StorageError {
Expand Down Expand Up @@ -612,6 +618,18 @@ where
self.ctx.inner.clone(),
self.verifiers.clone(),
);
// Add the source to the set of verifiers
self.verifiers.borrow_mut().insert(
Address::from_str(msg.message.packet_data.sender.as_ref())
.map_err(|_| {
Error::TokenTransfer(TokenTransferError::Other(
format!(
"Cannot convert the sender address {}",
msg.message.packet_data.sender
),
))
})?,
);
self.insert_verifiers()?;
if msg.transfer.is_some() {
token_transfer_ctx.enable_shielded_transfer();
Expand All @@ -630,6 +648,19 @@ where
if msg.transfer.is_some() {
nft_transfer_ctx.enable_shielded_transfer();
}
// Add the source to the set of verifiers
self.verifiers.borrow_mut().insert(
Address::from_str(msg.message.packet_data.sender.as_ref())
.map_err(|_| {
Error::NftTransfer(NftTransferError::Other(
format!(
"Cannot convert the sender address {}",
msg.message.packet_data.sender
),
))
})?,
);
self.insert_verifiers()?;
send_nft_transfer_execute(
&mut self.ctx,
&mut nft_transfer_ctx,
Expand All @@ -639,8 +670,21 @@ where
Ok((msg.transfer, None))
}
IbcMessage::Envelope(envelope) => {
if let Some(verifier) = get_envelope_verifier(envelope.as_ref())
{
self.verifiers.borrow_mut().insert(
Address::from_str(verifier.as_ref()).map_err(|_| {
Error::Other(format!(
"Cannot convert the address {}",
verifier,
))
})?,
);
self.insert_verifiers()?;
}
execute(&mut self.ctx, &mut self.router, *envelope.clone())
.map_err(|e| Error::Context(Box::new(e)))?;

// Extract MASP tx from the memo in the packet if needed
let masp_tx = match &*envelope {
MsgEnvelope::Packet(PacketMsg::Recv(msg))
Expand Down Expand Up @@ -734,6 +778,70 @@ where
}
}

// Extract the involved namada address from the packet (either sender or
// receiver) to trigger its vp. Returns None if an address could not be found
grarco marked this conversation as resolved.
Show resolved Hide resolved
fn get_envelope_verifier(
envelope: &MsgEnvelope,
) -> Option<ibc::primitives::Signer> {
match envelope {
MsgEnvelope::Packet(PacketMsg::Recv(msg)) => {
match msg.packet.port_id_on_b.as_str() {
FT_PORT_ID_STR => {
serde_json::from_slice::<PacketData>(&msg.packet.data)
.ok()
.map(|packet_data| packet_data.receiver)
}
NFT_PORT_ID_STR => {
serde_json::from_slice::<NftPacketData>(&msg.packet.data)
.ok()
.map(|packet_data| packet_data.receiver)
}
_ => None,
}
}
MsgEnvelope::Packet(PacketMsg::Ack(msg)) => serde_json::from_slice::<
AcknowledgementStatus,
>(
msg.acknowledgement.as_ref(),
)
.map_or(None, |ack| {
if ack.is_successful() {
None
} else {
match msg.packet.port_id_on_a.as_str() {
FT_PORT_ID_STR => {
serde_json::from_slice::<PacketData>(&msg.packet.data)
.ok()
.map(|packet_data| packet_data.sender)
}
NFT_PORT_ID_STR => serde_json::from_slice::<NftPacketData>(
&msg.packet.data,
)
.ok()
.map(|packet_data| packet_data.sender),
_ => None,
}
}
}),
MsgEnvelope::Packet(PacketMsg::Timeout(msg)) => {
match msg.packet.port_id_on_a.as_str() {
FT_PORT_ID_STR => {
serde_json::from_slice::<PacketData>(&msg.packet.data)
.ok()
.map(|packet_data| packet_data.sender)
}
NFT_PORT_ID_STR => {
serde_json::from_slice::<NftPacketData>(&msg.packet.data)
.ok()
.map(|packet_data| packet_data.sender)
}
_ => None,
}
}
_ => None,
}
}

/// Tries to decode transaction data to an `IbcMessage`
pub fn decode_message<Transfer: BorshDeserialize>(
tx_data: &[u8],
Expand Down
1 change: 1 addition & 0 deletions crates/node/src/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@ where
};

if let Some(schedule_migration) = scheduled_migration.as_ref() {
#[allow(clippy::disallowed_methods)]
let current = state.get_block_height().unwrap_or_default();
if schedule_migration.height < current {
panic!(
Expand Down
1 change: 1 addition & 0 deletions crates/node/src/shell/snapshots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ impl Shell<storage::PersistentDB, Sha256Hasher> {
}
match self.syncing.as_ref() {
None => {
#[allow(clippy::disallowed_methods)]
if self.state.get_block_height().unwrap_or_default().0
< u64::from(req.snapshot.height)
{
Expand Down
1 change: 1 addition & 0 deletions crates/node/src/shell/testing/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ impl MockNode {
}

pub fn block_height(&self) -> BlockHeight {
#[allow(clippy::disallowed_methods)]
self.shell
.lock()
.unwrap()
Expand Down
1 change: 1 addition & 0 deletions crates/node/src/shims/abcipp_shim_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ pub mod shim {
let header = req.header;
FinalizeBlock {
header: BlockHeader {
#[allow(clippy::disallowed_methods)]
hash: Hash::try_from(header.app_hash.as_bytes())
.unwrap_or_default(),
time: DateTimeUtc::try_from(header.time).unwrap(),
Expand Down
4 changes: 3 additions & 1 deletion crates/proof_of_stake/src/rewards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,14 @@ where

// Ensure TM stake updates properly with a debug_assert
if cfg!(debug_assertions) {
#[allow(clippy::disallowed_methods)]
let validator_vp = i64::try_from(validator_vp).unwrap_or_default();
debug_assert_eq!(
into_tm_voting_power(
params.tm_votes_per_token,
stake_from_deltas,
),
i64::try_from(validator_vp).unwrap_or_default(),
validator_vp
);
}

Expand Down
1 change: 1 addition & 0 deletions crates/proof_of_stake/src/tests/test_pos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,7 @@ fn test_unslashed_bond_amount_aux(validators: Vec<GenesisValidator>) {
Epoch(0),
current_epoch + params.pipeline_len,
) {
#[allow(clippy::disallowed_methods)]
let amount = bond_amount(
&storage,
&BondId {
Expand Down
2 changes: 2 additions & 0 deletions crates/proof_of_stake/src/tests/test_slash_and_redel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1638,6 +1638,7 @@ fn test_slashed_bond_amount_aux(validators: Vec<GenesisValidator>) {

let pipeline_epoch = current_epoch + params.pipeline_len;

#[allow(clippy::disallowed_methods)]
let del_bond_amount = bond_amount(
&storage,
&BondId {
Expand All @@ -1648,6 +1649,7 @@ fn test_slashed_bond_amount_aux(validators: Vec<GenesisValidator>) {
)
.unwrap_or_default();

#[allow(clippy::disallowed_methods)]
let self_bond_amount = bond_amount(
&storage,
&BondId {
Expand Down
2 changes: 1 addition & 1 deletion crates/sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub use {namada_io as io, namada_wallet as wallet};
use crate::masp::ShieldedContext;

/// Default gas-limit
pub const DEFAULT_GAS_LIMIT: u64 = 200_000;
pub const DEFAULT_GAS_LIMIT: u64 = 250_000;

/// An interface for high-level interaction with the Namada SDK
#[cfg_attr(feature = "async-send", async_trait::async_trait)]
Expand Down
2 changes: 2 additions & 0 deletions crates/sdk/src/queries/vp/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ pub mod client_only_methods {
let balance = if response.data.is_empty() {
token::Amount::zero()
} else {
#[allow(clippy::disallowed_methods)]
token::Amount::try_from_slice(&response.data)
.unwrap_or_default()
};
Expand All @@ -107,6 +108,7 @@ pub mod client_only_methods {
let tokens = if response.data.is_empty() {
token::Amount::zero()
} else {
#[allow(clippy::disallowed_methods)]
token::Amount::try_from_slice(&response.data)
.unwrap_or_default()
};
Expand Down
4 changes: 4 additions & 0 deletions crates/sdk/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -984,10 +984,12 @@ pub async fn query_proposal_result<C: namada_io::Client + Sync>(

let is_author_pgf_steward =
is_steward(client, &proposal.author).await;
#[allow(clippy::disallowed_methods)]
let votes = query_proposal_votes(client, proposal_id)
.await
.unwrap_or_default();
let tally_type = proposal.get_tally_type(is_author_pgf_steward);
#[allow(clippy::disallowed_methods)]
let total_active_voting_power =
get_total_active_voting_power(client, tally_epoch)
.await
Expand All @@ -998,6 +1000,7 @@ pub async fn query_proposal_result<C: namada_io::Client + Sync>(
for vote in votes {
match vote.is_validator() {
true => {
#[allow(clippy::disallowed_methods)]
let voting_power = get_validator_stake(
client,
tally_epoch,
Expand All @@ -1013,6 +1016,7 @@ pub async fn query_proposal_result<C: namada_io::Client + Sync>(
);
}
false => {
#[allow(clippy::disallowed_methods)]
let voting_power = get_bond_amount_at(
client,
&vote.delegator,
Expand Down
1 change: 1 addition & 0 deletions crates/sdk/src/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ pub async fn validate_transparent_fee<N: Namada>(
let fee_payer_address = Address::from(fee_payer);

let balance_key = balance_key(&args.fee_token, &fee_payer_address);
#[allow(clippy::disallowed_methods)]
let balance = rpc::query_storage_value::<_, token::Amount>(
context.client(),
&balance_key,
Expand Down
2 changes: 2 additions & 0 deletions crates/sdk/src/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3151,6 +3151,7 @@ async fn get_masp_fee_payment_amount<N: Namada>(
) -> Result<Option<MaspFeeData>> {
let fee_payer_address = Address::from(fee_payer);
let balance_key = balance_key(&args.fee_token, &fee_payer_address);
#[allow(clippy::disallowed_methods)]
let balance = rpc::query_storage_value::<_, token::Amount>(
context.client(),
&balance_key,
Expand Down Expand Up @@ -3492,6 +3493,7 @@ async fn construct_shielded_parts<N: Namada>(

// Get the decoded asset types used in the transaction to give offline
// wallet users more information
#[allow(clippy::disallowed_methods)]
let asset_types = used_asset_types(context, &shielded_parts.builder)
.await
.unwrap_or_default();
Expand Down
Loading
Loading