Skip to content

Commit 283478e

Browse files
committed
Added event that states the wasm name of each inner tx
1 parent 80eb56e commit 283478e

File tree

3 files changed

+179
-24
lines changed

3 files changed

+179
-24
lines changed

crates/events/src/extend.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,20 @@ impl EventAttributeEntry<'static> for Height {
493493
}
494494
}
495495

496+
/// Extend an [`Event`] with the name of the wasm code.
497+
pub struct CodeName(pub String);
498+
499+
impl EventAttributeEntry<'static> for CodeName {
500+
type Value = String;
501+
type ValueOwned = Self::Value;
502+
503+
const KEY: &'static str = "code-name";
504+
505+
fn into_value(self) -> Self::Value {
506+
self.0
507+
}
508+
}
509+
496510
/// Extend an [`Event`] with transaction hash information.
497511
pub struct TxHash(pub Hash);
498512

crates/node/src/shell/finalize_block.rs

Lines changed: 141 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ use namada_sdk::state::{
2121
use namada_sdk::storage::{BlockHeader, BlockResults, Epoch};
2222
use namada_sdk::tx::data::protocol::ProtocolTxType;
2323
use namada_sdk::tx::data::{VpStatusFlags, compute_inner_tx_hash};
24-
use namada_sdk::tx::event::{Batch, Code};
25-
use namada_sdk::tx::new_tx_event;
24+
use namada_sdk::tx::event::{Batch, Code, TxWasmEvent};
25+
use namada_sdk::tx::{TxCommitments, new_tx_event};
2626
use namada_sdk::{ibc, proof_of_stake};
2727
use namada_vote_ext::ethereum_events::MultiSignedEthEvent;
2828
use namada_vote_ext::ethereum_tx_data_variants;
@@ -363,12 +363,18 @@ where
363363
tx_data.tx.wrapper_hash().as_ref(),
364364
Either::Right(cmt),
365365
);
366+
self.emit_wasm_name_event(
367+
&tx_data,
368+
cmt,
369+
inner_tx_hash,
370+
response,
371+
);
366372
if let Some(Ok(batched_result)) =
367373
tx_result.get_mut(&inner_tx_hash)
368374
{
369375
if batched_result.is_accepted() {
370376
// Take the events from the batch result to
371-
// avoid emitting them again after the exection
377+
// avoid emitting them again after the execution
372378
// of the entire batch
373379
response.events.emit_many(
374380
std::mem::take(&mut batched_result.events)
@@ -470,6 +476,38 @@ where
470476
None
471477
}
472478

479+
fn emit_wasm_name_event(
480+
&self,
481+
tx_data: &TxData<'_>,
482+
cmt: &TxCommitments,
483+
inner_tx_hash: Hash,
484+
response: &mut shim::response::FinalizeBlock,
485+
) {
486+
// emit an event that gives the human readable name
487+
// of the wasm payload.
488+
let code_name = match tx_data
489+
.tx
490+
.get_section(&cmt.code_hash)
491+
.unwrap()
492+
.code_sec()
493+
.map(|c| c.code.hash())
494+
{
495+
None => "none".to_string(),
496+
Some(hash) => self
497+
.state
498+
.read(&Key::wasm_code_name(&hash))
499+
.ok()
500+
.flatten()
501+
.unwrap_or("unknown".to_string()),
502+
};
503+
504+
let code_name_event = TxWasmEvent {
505+
inner_tx_hash,
506+
name: code_name,
507+
};
508+
response.events.emit(code_name_event);
509+
}
510+
473511
// Evaluate the results of all the transactions of the batch. Commit or drop
474512
// the storage changes, update stats and event, manage replay protection.
475513
fn handle_inner_tx_results(
@@ -1302,7 +1340,7 @@ mod test_finalize_block {
13021340
};
13031341
use namada_sdk::ethereum_events::{EthAddress, Uint as ethUint};
13041342
use namada_sdk::events::Event;
1305-
use namada_sdk::events::extend::Log;
1343+
use namada_sdk::events::extend::{CodeName, Log};
13061344
use namada_sdk::gas::VpGasMeter;
13071345
use namada_sdk::governance::storage::keys::get_proposal_execution_key;
13081346
use namada_sdk::governance::storage::proposal::ProposalType;
@@ -1519,6 +1557,7 @@ mod test_finalize_block {
15191557
})
15201558
.expect("Test failed")
15211559
.iter()
1560+
.filter(|e| e.read_attribute::<CodeName>().is_err())
15221561
{
15231562
assert_eq!(*event.kind(), APPLIED_TX);
15241563
let hash = event.read_attribute::<TxHash>().expect("Test failed");
@@ -3166,7 +3205,10 @@ mod test_finalize_block {
31663205
txs: vec![processed_tx],
31673206
..Default::default()
31683207
})
3169-
.expect("Test failed")[0];
3208+
.expect("Test failed")
3209+
.into_iter()
3210+
.filter(|e| e.read_attribute::<CodeName>().is_err())
3211+
.collect::<Vec<_>>()[0];
31703212
assert_eq!(*event.kind(), APPLIED_TX);
31713213
let code = event.read_attribute::<CodeAttr>().expect("Test failed");
31723214
assert_eq!(code, ResultCode::Ok);
@@ -3325,7 +3367,10 @@ mod test_finalize_block {
33253367
txs: processed_txs,
33263368
..Default::default()
33273369
})
3328-
.expect("Test failed");
3370+
.expect("Test failed")
3371+
.into_iter()
3372+
.filter(|e| e.read_attribute::<CodeName>().is_err())
3373+
.collect::<Vec<_>>();
33293374

33303375
// the merkle tree root should not change after finalize_block
33313376
let root_post = shell.shell.state.in_mem().block.tree.root();
@@ -3453,7 +3498,10 @@ mod test_finalize_block {
34533498
txs: processed_txs,
34543499
..Default::default()
34553500
})
3456-
.expect("Test failed");
3501+
.expect("Test failed")
3502+
.into_iter()
3503+
.filter(|e| e.read_attribute::<CodeName>().is_err())
3504+
.collect::<Vec<_>>();
34573505

34583506
// the merkle tree root should not change after finalize_block
34593507
let root_post = shell.shell.state.in_mem().block.tree.root();
@@ -3582,7 +3630,10 @@ mod test_finalize_block {
35823630
txs: processed_txs,
35833631
..Default::default()
35843632
})
3585-
.expect("Test failed");
3633+
.expect("Test failed")
3634+
.into_iter()
3635+
.filter(|e| e.read_attribute::<CodeName>().is_err())
3636+
.collect::<Vec<_>>();
35863637

35873638
// the merkle tree root should not change after finalize_block
35883639
let root_post = shell.shell.state.in_mem().block.tree.root();
@@ -3814,7 +3865,10 @@ mod test_finalize_block {
38143865
txs: vec![processed_tx],
38153866
..Default::default()
38163867
})
3817-
.expect("Test failed")[0];
3868+
.expect("Test failed")
3869+
.into_iter()
3870+
.filter(|e| e.read_attribute::<CodeName>().is_err())
3871+
.collect::<Vec<_>>()[0];
38183872

38193873
// Check balance of fee payer
38203874
assert_eq!(*event.kind(), APPLIED_TX);
@@ -3974,7 +4028,10 @@ mod test_finalize_block {
39744028
txs: vec![processed_tx],
39754029
..Default::default()
39764030
})
3977-
.expect("Test failed")[0];
4031+
.expect("Test failed")
4032+
.into_iter()
4033+
.filter(|e| e.read_attribute::<CodeName>().is_err())
4034+
.collect::<Vec<_>>()[0];
39784035

39794036
// Check fee payment
39804037
assert_eq!(*event.kind(), APPLIED_TX);
@@ -4059,7 +4116,10 @@ mod test_finalize_block {
40594116
proposer_address,
40604117
..Default::default()
40614118
})
4062-
.expect("Test failed")[0];
4119+
.expect("Test failed")
4120+
.into_iter()
4121+
.filter(|e| e.read_attribute::<CodeName>().is_err())
4122+
.collect::<Vec<_>>()[0];
40634123

40644124
// Check fee payment
40654125
assert_eq!(*event.kind(), APPLIED_TX);
@@ -5791,7 +5851,10 @@ mod test_finalize_block {
57915851
txs: vec![processed_tx],
57925852
..Default::default()
57935853
})
5794-
.expect("Test failed");
5854+
.expect("Test failed")
5855+
.into_iter()
5856+
.filter(|e| e.read_attribute::<CodeName>().is_err())
5857+
.collect::<Vec<_>>();
57955858

57965859
let code = event[0].read_attribute::<CodeAttr>().unwrap();
57975860
assert_eq!(code, ResultCode::Ok);
@@ -5839,7 +5902,10 @@ mod test_finalize_block {
58395902
txs: vec![processed_tx],
58405903
..Default::default()
58415904
})
5842-
.expect("Test failed");
5905+
.expect("Test failed")
5906+
.into_iter()
5907+
.filter(|e| e.read_attribute::<CodeName>().is_err())
5908+
.collect::<Vec<_>>();
58435909

58445910
let code = event[0].read_attribute::<CodeAttr>().unwrap();
58455911
assert_eq!(code, ResultCode::WasmRuntimeError);
@@ -5898,7 +5964,10 @@ mod test_finalize_block {
58985964
txs: vec![processed_tx],
58995965
..Default::default()
59005966
})
5901-
.expect("Test failed");
5967+
.expect("Test failed")
5968+
.into_iter()
5969+
.filter(|e| e.read_attribute::<CodeName>().is_err())
5970+
.collect::<Vec<_>>();
59025971

59035972
let code = event[0].read_attribute::<CodeAttr>().unwrap();
59045973
assert_eq!(code, ResultCode::Ok);
@@ -5975,7 +6044,10 @@ mod test_finalize_block {
59756044
txs: vec![processed_tx],
59766045
..Default::default()
59776046
})
5978-
.expect("Test failed");
6047+
.expect("Test failed")
6048+
.into_iter()
6049+
.filter(|e| e.read_attribute::<CodeName>().is_err())
6050+
.collect::<Vec<_>>();
59796051

59806052
let code = event[0].read_attribute::<CodeAttr>().unwrap();
59816053
assert_eq!(code, ResultCode::WasmRuntimeError);
@@ -6028,12 +6100,15 @@ mod test_finalize_block {
60286100
let (batch, processed_tx) =
60296101
mk_tx_batch(&shell, &sk, false, false, true);
60306102

6031-
let event = &shell
6103+
let event = shell
60326104
.finalize_block(FinalizeBlock {
60336105
txs: vec![processed_tx],
60346106
..Default::default()
60356107
})
6036-
.expect("Test failed");
6108+
.expect("Test failed")
6109+
.into_iter()
6110+
.filter(|e| e.read_attribute::<CodeName>().is_err())
6111+
.collect::<Vec<_>>();
60376112

60386113
let code = event[0].read_attribute::<CodeAttr>().unwrap();
60396114
assert_eq!(code, ResultCode::WasmRuntimeError);
@@ -6121,7 +6196,27 @@ mod test_finalize_block {
61216196

61226197
batch
61236198
};
6199+
let commitments = batch_tx.commitments().first().expect("Test failed");
61246200

6201+
shell
6202+
.state
6203+
.write(
6204+
&Key::wasm_code_name(
6205+
&batch_tx
6206+
.get_section(&commitments.code_hash)
6207+
.unwrap()
6208+
.code_sec()
6209+
.map(|c| c.code.hash())
6210+
.unwrap(),
6211+
),
6212+
TestWasms::TxNoOpEvent
6213+
.path()
6214+
.file_name()
6215+
.unwrap()
6216+
.to_string_lossy()
6217+
.to_string(),
6218+
)
6219+
.expect("Test failed");
61256220
let processed_txs = vec![ProcessedTx {
61266221
tx: batch_tx.to_bytes().into(),
61276222
result: TxResult {
@@ -6136,14 +6231,19 @@ mod test_finalize_block {
61366231
..Default::default()
61376232
})
61386233
.expect("Test failed");
6139-
6140-
// three top level events
6141-
assert_eq!(events.len(), 3);
6234+
// five top level events
6235+
assert_eq!(events.len(), 5);
61426236

61436237
// tx events. Check that they are present and in the correct order
61446238
// TODO(namada#3856): right now we lose events ordering in a batch
61456239
// because of the BTreeSet we use in BatchedTxResult so we can only
61466240
// check the presence of the events but not the order
6241+
let event = events.remove(0);
6242+
let code_name = event.read_attribute::<CodeName>().unwrap();
6243+
assert_eq!(code_name, "tx_no_op_event.wasm");
6244+
let event = events.remove(0);
6245+
let code_name = event.read_attribute::<CodeName>().unwrap();
6246+
assert_eq!(code_name, "tx_no_op_event.wasm");
61476247
let mut unordered_events = vec![];
61486248
let event = events.remove(0);
61496249
let msg = event.read_attribute::<Log>().unwrap();
@@ -6220,14 +6320,20 @@ mod test_finalize_block {
62206320
.expect("Test failed");
62216321

62226322
// three top level events
6223-
assert_eq!(events.len(), 3);
6323+
assert_eq!(events.len(), 5);
62246324

62256325
// tx events. Check that they are both present even if they are
62266326
// identical. This is important because some inner txs of a single batch
62276327
// may correctly emit identical events and we don't want them to
62286328
// overshadow each other which could deceive external tools like
62296329
// indexers
62306330
let event = events.remove(0);
6331+
let code_name = event.read_attribute::<CodeName>().unwrap();
6332+
assert_eq!(code_name, "unknown");
6333+
let event = events.remove(0);
6334+
let code_name = event.read_attribute::<CodeName>().unwrap();
6335+
assert_eq!(code_name, "unknown");
6336+
let event = events.remove(0);
62316337
let msg = event.read_attribute::<Log>().unwrap();
62326338
assert_eq!(&msg, EVENT_MSG);
62336339

@@ -6297,11 +6403,17 @@ mod test_finalize_block {
62976403
.expect("Test failed");
62986404

62996405
// two top level events
6300-
assert_eq!(events.len(), 2);
6406+
assert_eq!(events.len(), 4);
63016407

63026408
// tx events. Check the expected ones are present and in the correct
63036409
// order
63046410
let event = events.remove(0);
6411+
let code_name = event.read_attribute::<CodeName>().unwrap();
6412+
assert_eq!(code_name, "unknown");
6413+
let event = events.remove(0);
6414+
let code_name = event.read_attribute::<CodeName>().unwrap();
6415+
assert_eq!(code_name, "unknown");
6416+
let event = events.remove(0);
63056417
let msg = event.read_attribute::<Log>().unwrap();
63066418
assert_eq!(&msg, "bing");
63076419

@@ -6368,9 +6480,15 @@ mod test_finalize_block {
63686480
.expect("Test failed");
63696481

63706482
// one top level event (no tx events, only tx result)
6371-
assert_eq!(events.len(), 1);
6483+
assert_eq!(events.len(), 3);
63726484

63736485
// multiple tx results (2)
6486+
let event = events.remove(0);
6487+
let code_name = event.read_attribute::<CodeName>().unwrap();
6488+
assert_eq!(code_name, "unknown");
6489+
let event = events.remove(0);
6490+
let code_name = event.read_attribute::<CodeName>().unwrap();
6491+
assert_eq!(code_name, "unknown");
63746492
let tx_event = events.remove(0);
63756493
let tx_results = tx_event.read_attribute::<Batch<'_>>().unwrap();
63766494
assert_eq!(tx_results.len(), 2);

0 commit comments

Comments
 (0)