Skip to content

Commit bf609fe

Browse files
committed
Emit FMD flag ciphertext tx events
1 parent 70eaa07 commit bf609fe

File tree

6 files changed

+268
-153
lines changed

6 files changed

+268
-153
lines changed

crates/node/src/bench_utils.rs

Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ use namada_sdk::queries::{
8888
use namada_sdk::state::StorageRead;
8989
use namada_sdk::state::write_log::StorageModification;
9090
use namada_sdk::storage::{Key, KeySeg, TxIndex};
91+
use namada_sdk::tendermint::abci::Event as AbciEvent;
9192
use namada_sdk::time::DateTimeUtc;
9293
use namada_sdk::token::{
9394
self, Amount, DenominatedAmount, MaspTxData, Transfer,
@@ -96,7 +97,9 @@ use namada_sdk::tx::data::pos::Bond;
9697
use namada_sdk::tx::data::{
9798
BatchedTxResult, Fee, TxResult, VpsResult, compute_inner_tx_hash,
9899
};
99-
use namada_sdk::tx::event::{Batch, MaspEvent, MaspTxRef, new_tx_event};
100+
use namada_sdk::tx::event::{
101+
Batch, FmdSectionRef, MaspEvent, MaspTxKind, MaspTxRef, new_tx_event,
102+
};
100103
use namada_sdk::tx::{
101104
Authorization, BatchedTx, BatchedTxRef, Code, Data, IndexedTx, Section, Tx,
102105
};
@@ -1062,43 +1065,67 @@ impl Client for BenchShell {
10621065
let tx_event: Event = new_tx_event(tx, height.value())
10631066
.with(Batch(&tx_result))
10641067
.into();
1065-
// Expect a single masp tx in the batch
1066-
let masp_ref = tx.sections.iter().find_map(|section| {
1067-
if let Section::MaspTx(transaction) = section {
1068-
Some(MaspTxRef::MaspSection(transaction.txid().into()))
1069-
} else {
1070-
None
1071-
}
1072-
});
10731068

10741069
let first_inner_tx_hash = compute_inner_tx_hash(
10751070
tx.wrapper_hash().as_ref(),
10761071
Either::Right(tx.first_commitments().unwrap()),
10771072
);
1078-
let masp_event = masp_ref.map(|data| {
1079-
let masp_event: Event = MaspEvent {
1080-
tx_index: IndexedTx {
1081-
block_height: namada_sdk::chain::BlockHeight(
1082-
u64::from(height),
1083-
),
1084-
block_index: TxIndex::must_from_usize(idx),
1085-
batch_index: Some(0),
1086-
},
1087-
kind: namada_sdk::tx::event::MaspEventKind::Transfer,
1088-
data,
1089-
}
1090-
.with(TxHash(tx.header_hash()))
1091-
.with(InnerTxHash(first_inner_tx_hash))
1092-
.into();
1093-
masp_event
1094-
});
1095-
1096-
res.push(namada_sdk::tendermint::abci::Event::from(tx_event));
1073+
let wrapper_hash = tx.wrapper_hash().unwrap_or_default();
1074+
let indexed_tx = IndexedTx {
1075+
block_height: namada_sdk::chain::BlockHeight(u64::from(
1076+
height,
1077+
)),
1078+
block_index: TxIndex::must_from_usize(idx),
1079+
batch_index: Some(0),
1080+
};
10971081

1098-
if let Some(event) = masp_event {
1099-
res.push(namada_sdk::tendermint::abci::Event::from(event));
1082+
let masp_tx_event =
1083+
tx.sections.iter().find_map(|section| match section {
1084+
Section::MaspTx(transaction) => {
1085+
Some(AbciEvent::from(Event::from(
1086+
MaspEvent::ShieldedOutput {
1087+
tx_index: indexed_tx,
1088+
kind: MaspTxKind::Transfer,
1089+
data: MaspTxRef::MaspSection(
1090+
transaction.txid().into(),
1091+
),
1092+
}
1093+
.with(TxHash(wrapper_hash))
1094+
.with(InnerTxHash(first_inner_tx_hash)),
1095+
)))
1096+
}
1097+
_ => None,
1098+
});
1099+
let masp_fmd_event =
1100+
tx.sections.iter().find_map(|section| match section {
1101+
sec @ Section::Data(Data { data, .. })
1102+
if <Vec<FlagCiphertext>>::try_from_slice(data)
1103+
.is_ok() =>
1104+
{
1105+
Some(AbciEvent::from(Event::from(
1106+
MaspEvent::FlagCiphertexts {
1107+
tx_index: indexed_tx,
1108+
section: FmdSectionRef::FmdSection(
1109+
sec.get_hash(),
1110+
),
1111+
}
1112+
.with(TxHash(wrapper_hash))
1113+
.with(InnerTxHash(first_inner_tx_hash)),
1114+
)))
1115+
}
1116+
_ => None,
1117+
});
1118+
1119+
res.push(AbciEvent::from(tx_event));
1120+
1121+
if let Some((masp_tx_event, masp_fmd_event)) =
1122+
masp_tx_event.zip(masp_fmd_event)
1123+
{
1124+
res.push(masp_tx_event);
1125+
res.push(masp_fmd_event);
11001126
}
11011127
}
1128+
11021129
Some(res)
11031130
} else {
11041131
None

crates/node/src/protocol.rs

Lines changed: 95 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use namada_sdk::tx::data::{
3030
BatchedTxResult, TxResult, VpStatusFlags, VpsResult, WrapperTx,
3131
compute_inner_tx_hash,
3232
};
33-
use namada_sdk::tx::event::{MaspEvent, MaspEventKind, MaspTxRef};
33+
use namada_sdk::tx::event::{FmdSectionRef, MaspEvent, MaspTxKind, MaspTxRef};
3434
use namada_sdk::tx::{BatchedTxRef, IndexedTx, Tx, TxCommitments};
3535
use namada_sdk::validation::{
3636
EthBridgeNutVp, EthBridgePoolVp, EthBridgeVp, GovernanceVp, IbcVp, MaspVp,
@@ -395,38 +395,32 @@ where
395395
Ok(mut batched_tx_result) if batched_tx_result.is_accepted() => {
396396
// If the transaction was a masp one generate the
397397
// appropriate event
398-
if let Some(masp_ref) = get_optional_masp_ref(
398+
if let Some((masp_ref, fmd_ref)) = get_optional_masp_refs(
399399
state,
400400
cmt,
401401
Either::Right(&batched_tx_result),
402402
)
403403
.map_err(|e| Box::new(DispatchError::from(e)))?
404404
{
405-
let inner_tx_hash =
406-
compute_inner_tx_hash(wrapper_hash, Either::Right(cmt));
407-
batched_tx_result.events.insert(
408-
MaspEvent {
409-
tx_index: IndexedTx {
410-
block_height: height,
411-
block_index: tx_index,
412-
batch_index: tx
413-
.header
414-
.batch
415-
.get_index_of(cmt)
416-
.map(|idx| {
417-
TxIndex::must_from_usize(idx).into()
418-
}),
419-
},
420-
kind: MaspEventKind::Transfer,
421-
data: masp_ref,
422-
}
423-
.with(TxHashAttr(
424-
// Zero hash if the wrapper is not provided
425-
// (governance proposal)
426-
wrapper_hash.cloned().unwrap_or_default(),
427-
))
428-
.with(InnerTxHashAttr(inner_tx_hash))
429-
.into(),
405+
insert_masp_events(
406+
&mut batched_tx_result,
407+
// Zero hash if the wrapper is not provided
408+
// (governance proposal)
409+
TxHashAttr(wrapper_hash.cloned().unwrap_or_default()),
410+
InnerTxHashAttr(compute_inner_tx_hash(
411+
wrapper_hash,
412+
Either::Right(cmt),
413+
)),
414+
IndexedTx {
415+
block_height: height,
416+
block_index: tx_index,
417+
batch_index: tx.header.batch.get_index_of(cmt).map(
418+
|idx| TxIndex::must_from_usize(idx).into(),
419+
),
420+
},
421+
MaspTxKind::Transfer,
422+
masp_ref,
423+
fmd_ref,
430424
);
431425
}
432426

@@ -467,6 +461,7 @@ where
467461
pub struct MaspTxResult {
468462
tx_result: BatchedTxResult,
469463
masp_section_ref: MaspTxRef,
464+
fmd_section_ref: FmdSectionRef,
470465
}
471466

472467
/// Performs the required operation on a wrapper transaction:
@@ -526,22 +521,21 @@ where
526521
let first_commitments = tx.first_commitments().unwrap();
527522
let mut batch = TxResult::default();
528523
// Generate Masp event if needed
529-
masp_tx_result.tx_result.events.insert(
530-
MaspEvent {
531-
tx_index: IndexedTx {
532-
block_height: height,
533-
block_index: tx_index.to_owned(),
534-
batch_index: Some(0),
535-
},
536-
kind: MaspEventKind::FeePayment,
537-
data: masp_tx_result.masp_section_ref,
538-
}
539-
.with(TxHashAttr(tx.header_hash()))
540-
.with(InnerTxHashAttr(compute_inner_tx_hash(
524+
insert_masp_events(
525+
&mut masp_tx_result.tx_result,
526+
TxHashAttr(tx.header_hash()),
527+
InnerTxHashAttr(compute_inner_tx_hash(
541528
tx.wrapper_hash().as_ref(),
542529
Either::Right(first_commitments),
543-
)))
544-
.into(),
530+
)),
531+
IndexedTx {
532+
block_height: height,
533+
block_index: tx_index.to_owned(),
534+
batch_index: Some(0),
535+
},
536+
MaspTxKind::FeePayment,
537+
masp_tx_result.masp_section_ref,
538+
masp_tx_result.fmd_section_ref,
545539
);
546540

547541
batch.insert_inner_tx_result(
@@ -839,20 +833,22 @@ where
839833
// Ensure that the transaction is actually a masp one, otherwise
840834
// reject
841835
if is_masp_transfer && result.is_accepted() {
842-
let masp_section_ref = get_optional_masp_ref(
843-
*state,
844-
first_tx.cmt,
845-
Either::Left(true),
846-
)?
847-
.ok_or_else(|| {
848-
Error::FeeError(
849-
"Missing expected masp section reference"
850-
.to_string(),
851-
)
852-
})?;
836+
let (masp_section_ref, fmd_section_ref) =
837+
get_optional_masp_refs(
838+
*state,
839+
first_tx.cmt,
840+
Either::Left(true),
841+
)?
842+
.ok_or_else(|| {
843+
Error::FeeError(
844+
"Missing expected masp section reference"
845+
.to_string(),
846+
)
847+
})?;
853848
MaspTxResult {
854849
tx_result: result,
855850
masp_section_ref,
851+
fmd_section_ref,
856852
}
857853
} else {
858854
state.write_log_mut().drop_tx();
@@ -893,11 +889,11 @@ where
893889
// messing up with indexers/clients. Also a transaction can only be of one of
894890
// the two types, not both at the same time (the MASP VP accepts a single
895891
// Transaction)
896-
fn get_optional_masp_ref<S: Read<Err = state::Error>>(
892+
fn get_optional_masp_refs<S: Read<Err = state::Error>>(
897893
state: &S,
898894
cmt: &TxCommitments,
899895
is_masp_tx: Either<bool, &BatchedTxResult>,
900-
) -> Result<Option<MaspTxRef>> {
896+
) -> Result<Option<(MaspTxRef, FmdSectionRef)>> {
901897
// Always check that the transaction was indeed a MASP one by looking at the
902898
// changed keys. A malicious tx could push a MASP Action without touching
903899
// any storage keys associated with the shielded pool
@@ -912,14 +908,27 @@ fn get_optional_masp_ref<S: Read<Err = state::Error>>(
912908
let masp_ref = if action::is_ibc_shielding_transfer(state)
913909
.map_err(Error::StateError)?
914910
{
915-
Some(MaspTxRef::IbcData(cmt.data_sechash().to_owned()))
911+
let ibc_data = cmt.data_sechash().to_owned();
912+
913+
Some((
914+
MaspTxRef::IbcData(ibc_data),
915+
FmdSectionRef::IbcData(ibc_data),
916+
))
916917
} else {
917918
let actions = state.read_actions().map_err(Error::StateError)?;
918-
action::get_masp_section_ref(&actions)
919+
920+
let masp_tx = action::get_masp_section_ref(&actions)
921+
.map_err(|msg| {
922+
Error::StateError(state::Error::new_alloc(msg.to_string()))
923+
})?
924+
.map(MaspTxRef::MaspSection);
925+
let fmd_sechash = action::get_fmd_flag_ciphertexts_ref(&actions)
919926
.map_err(|msg| {
920927
Error::StateError(state::Error::new_alloc(msg.to_string()))
921928
})?
922-
.map(MaspTxRef::MaspSection)
929+
.map(FmdSectionRef::FmdSection);
930+
931+
masp_tx.zip(fmd_sechash)
923932
};
924933

925934
Ok(masp_ref)
@@ -1499,6 +1508,35 @@ fn merge_vp_results(
14991508
))
15001509
}
15011510

1511+
/// Insert MASP event data into the provided [`BatchedTxResult`].
1512+
fn insert_masp_events(
1513+
batched_tx_result: &mut BatchedTxResult,
1514+
wrapper_tx_hash: TxHashAttr,
1515+
inner_tx_hash: InnerTxHashAttr,
1516+
tx_index: IndexedTx,
1517+
masp_tx_kind: MaspTxKind,
1518+
masp_tx_ref: MaspTxRef,
1519+
fmd_ref: FmdSectionRef,
1520+
) {
1521+
batched_tx_result.events.extend([
1522+
MaspEvent::ShieldedOutput {
1523+
tx_index,
1524+
kind: masp_tx_kind,
1525+
data: masp_tx_ref,
1526+
}
1527+
.with(TxHashAttr(wrapper_tx_hash.0))
1528+
.with(InnerTxHashAttr(inner_tx_hash.0))
1529+
.into(),
1530+
MaspEvent::FlagCiphertexts {
1531+
tx_index,
1532+
section: fmd_ref,
1533+
}
1534+
.with(TxHashAttr(wrapper_tx_hash.0))
1535+
.with(InnerTxHashAttr(inner_tx_hash.0))
1536+
.into(),
1537+
]);
1538+
}
1539+
15021540
#[cfg(test)]
15031541
mod tests {
15041542
use eyre::Result;

crates/sdk/src/masp.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use namada_ibc::{IbcMessage, decode_message, extract_masp_tx_from_envelope};
1919
use namada_io::client::Client;
2020
use namada_token::masp::shielded_wallet::ShieldedQueries;
2121
pub use namada_token::masp::{utils, *};
22-
use namada_tx::event::{MaspEvent, MaspEventKind, MaspTxRef};
22+
use namada_tx::event::{MaspTxEvent, MaspTxKind, MaspTxRef};
2323
use namada_tx::{IndexedTx, Tx};
2424
pub use utilities::{IndexerMaspClient, LedgerMaspClient};
2525

@@ -92,10 +92,10 @@ fn extract_masp_tx(
9292
}
9393

9494
// Retrieves all the masp events at the specified height.
95-
async fn get_indexed_masp_events_at_height<C: Client + Sync>(
95+
async fn get_indexed_masp_txs_at_height<C: Client + Sync>(
9696
client: &C,
9797
height: BlockHeight,
98-
) -> Result<Vec<MaspEvent>, Error> {
98+
) -> Result<Vec<MaspTxEvent>, Error> {
9999
let maybe_masp_events: Result<Vec<_>, Error> = client
100100
.block_results(height.0)
101101
.await
@@ -111,9 +111,9 @@ async fn get_indexed_masp_events_at_height<C: Client + Sync>(
111111
};
112112

113113
let kind = if kind == namada_tx::event::masp_types::TRANSFER {
114-
MaspEventKind::Transfer
114+
MaspTxKind::Transfer
115115
} else if kind == namada_tx::event::masp_types::FEE_PAYMENT {
116-
MaspEventKind::FeePayment
116+
MaspTxKind::FeePayment
117117
} else {
118118
return Ok(None);
119119
};
@@ -125,7 +125,7 @@ async fn get_indexed_masp_events_at_height<C: Client + Sync>(
125125
let tx_index =
126126
IndexedTx::read_from_event_attributes(&event.attributes)?;
127127

128-
Ok(Some(MaspEvent {
128+
Ok(Some(MaspTxEvent {
129129
tx_index,
130130
kind,
131131
data,

0 commit comments

Comments
 (0)