diff --git a/sdk/src/masp.rs b/sdk/src/masp.rs index cb56845e8be..596a51027ec 100644 --- a/sdk/src/masp.rs +++ b/sdk/src/masp.rs @@ -1546,8 +1546,6 @@ impl ShieldedContext { // Obtain the transaction pointer at the key // If we don't discard the error message then a test fails, // however the error underlying this will go undetected - // FIXME: we could index the comet tx hash here so that we could just - // query it via a single rpc call to the /tx endpoint let indexed_tx = rpc::query_storage_value::(client, &pin_key) .await @@ -1572,29 +1570,79 @@ impl ShieldedContext { let tx = Tx::try_from(block[indexed_tx.index.0 as usize].as_ref()) .map_err(|e| Error::Other(e.to_string()))?; - let shielded = - match Transfer::try_from_slice(&tx.data().ok_or_else(|| { - Error::Other("Missing data section".to_string()) - })?) { - Ok(transfer) => tx - .get_section(&transfer.shielded.ok_or_else(|| { - Error::Other("Missing masp section hash".to_string()) - })?) - .ok_or_else(|| { - Error::Other( - "Missing masp section in transaction".to_string(), - ) - })? - .masp_tx() - .ok_or_else(|| { - Error::Other("Missing masp transaction".to_string()) - })?, - Err(_) => { - // FIXME: add support for pinned ibc masp txs, but I need to - // query tx to do this - return Err(Error::Other("IBC Masp pinned tx".to_string())); - } - }; + let tx_data = tx + .data() + .ok_or_else(|| Error::Other("Missing data section".to_string()))?; + let shielded = match Transfer::try_from_slice(&tx_data) { + Ok(transfer) => tx + .get_section(&transfer.shielded.ok_or_else(|| { + Error::Other("Missing masp section hash".to_string()) + })?) + .ok_or_else(|| { + Error::Other( + "Missing masp section in transaction".to_string(), + ) + })? + .masp_tx() + .ok_or_else(|| { + Error::Other("Missing masp transaction".to_string()) + })?, + Err(_) => { + // Try Masp over IBC + + let message = + namada_core::ledger::ibc::decode_message(&tx_data) + .map_err(|e| Error::Other(e.to_string()))?; + + let shielded_transfer = match message { + IbcMessage::ShieldedTransfer(msg) => msg.shielded_transfer, + IbcMessage::Envelope(_) => { + // Need the tx event to extract the memo + let tx_events = client + .block_results(indexed_tx.height.0 as u32) + .await + .map_err(|e| { + Error::from(QueryError::General(e.to_string())) + })? + .end_block_events + .ok_or_else(|| { + Error::Other(format!( + "Missing required ibc event at block \ + height {}", + indexed_tx.height + )) + })?; + + tx_events[indexed_tx.index.0 as usize] .attributes + .iter() + .find_map(|attribute| { + if attribute.key == "inner_tx" { + let tx_result = TxResult::from_str(&attribute.value).unwrap(); + for ibc_event in &tx_result.ibc_events { + + let event = namada_core::types::ibc::get_shielded_transfer(ibc_event).ok().flatten(); + if event.is_some() { + return event; + } + } + None + } else { + None + } + }).ok_or_else(|| Error::Other("Couldn't deserialize masp tx to ibc message envelope".to_string()))? + } + _ => { + return Err(Error::Other( + "Couldn't deserialize masp tx to a valid ibc \ + message" + .to_string(), + )); + } + }; + + shielded_transfer.masp_tx + } + }; // Accumulate the combined output note value into this Amount let mut val_acc = I128Sum::zero(); diff --git a/shared/src/vm/host_env.rs b/shared/src/vm/host_env.rs index 85fda430ea1..fb5ae3bb3b3 100644 --- a/shared/src/vm/host_env.rs +++ b/shared/src/vm/host_env.rs @@ -113,7 +113,6 @@ where pub tx: HostRef<'a, &'a Tx>, /// The transaction index is used to identify a shielded transaction's /// parent - // FIXME: still need this? pub tx_index: HostRef<'a, &'a TxIndex>, /// The verifiers whose validity predicates should be triggered. pub verifiers: MutHostRef<'a, &'a BTreeSet
>, @@ -276,7 +275,6 @@ where pub tx: HostRef<'a, &'a Tx>, /// The transaction index is used to identify a shielded transaction's /// parent - // FIXME: still need this? pub tx_index: HostRef<'a, &'a TxIndex>, /// The runner of the [`vp_eval`] function pub eval_runner: HostRef<'a, &'a EVAL>,