Skip to content

Fix masp events#4449

Closed
grarco wants to merge 14 commits intomainfrom
grarco/fix-masp-events
Closed

Fix masp events#4449
grarco wants to merge 14 commits intomainfrom
grarco/fix-masp-events

Conversation

@grarco
Copy link
Copy Markdown
Collaborator

@grarco grarco commented Mar 5, 2025

Describe your changes

Partially addresses #3824 (removes ExtendedTxResult).
Partially addresses #3827 as we take events out of BatchedTxResult in case of masp fee payment.

Ensures that events for masp fee payment txs are emitted as soon as the storage changes are committed

Checklist before merging

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 5, 2025

Codecov Report

Attention: Patch coverage is 82.46206% with 104 lines in your changes missing coverage. Please review.

Project coverage is 74.51%. Comparing base (f3cc9da) to head (4d9efbd).
Report is 36 commits behind head on main.

Files with missing lines Patch % Lines
crates/sdk/src/masp/utilities.rs 35.84% 34 Missing ⚠️
crates/sdk/src/masp.rs 56.92% 28 Missing ⚠️
crates/node/src/dry_run_tx.rs 39.02% 25 Missing ⚠️
...tes/shielded_token/src/masp/shielded_sync/utils.rs 89.76% 13 Missing ⚠️
crates/tx/src/event.rs 92.85% 2 Missing ⚠️
crates/node/src/shell/finalize_block.rs 97.50% 1 Missing ⚠️
crates/shielded_token/src/masp/test_utils.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4449      +/-   ##
==========================================
+ Coverage   74.48%   74.51%   +0.03%     
==========================================
  Files         339      339              
  Lines      110643   110865     +222     
==========================================
+ Hits        82412    82612     +200     
- Misses      28231    28253      +22     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions github-actions bot added the breaking:api public API breaking change label Mar 5, 2025
CA: 'static + WasmCacheAccess + Sync,
{
for cmt in get_batch_txs_to_execute(tx, &extended_tx_result.masp_tx_refs) {
let ran_masp_fee_payment = !tx_result.is_empty();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line seems bug prone. Took me forever to confirm this works

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can check if a masp event is in the values, no?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could but there's also another issue #3827 with duplicated events. If we were to ever fix that I believe we won't have those events in here anymore (unless we also implement your suggestion to postpone pushing the events) and we could fail here.

Should we just pass a flag to this function to signal that the first tx already ran to pay fees?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got your point, will work on a fix to avoid relying on the tx result

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a tentative fix in a0b94a5

// Emit the events of the fee-paying inner tx. This tx has
// just been committed so we need to ensure the relative
// events are emitted
let events = tx_result.0.first_key_value().map_or_else(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I find this assumption dangerous. Maybe we can soup up the type to keep thses events under a separate field

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can but we need to handle the case of a failing atomic batch for which the fee paying tx should be committed anyway (and the relative events should be emitted). My reason to emit the events here is that in the line above we commit the storage changes and I wanted to emit the events at the same time.

Also, by emitting the events here, the masp events are already sorted in the block results (without the need to look at the masp fee payment attribute), so that clients don't need to reorder them.

for MaspEvent {
tx_index,
masp_refs,
kind: _,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cant tell where this field is used

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is used in the event itself (which could be of type masp/transfer or masp/fee-payment), and after 837d480 it is also used when fetching txs from the indexer since when we cache them we need to be able to sort them correctly (as suggested by @sug0) and we need the tx kind for that since fee payment txs need to be move ahead of the queue

Copy link
Copy Markdown
Collaborator

@sug0 sug0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couple of suggestions. let's not merge this until we thoroughly test integration with the associated masp indexer pr.

Comment on lines +435 to +439
// Stop the execution of an atomic batch at the
// first failed transaction
return Err(DispatchError {
error: Error::FailingAtomicBatch(cmt.get_hash()),
tx_result: Some(tx_result),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we drop the batch later?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we do that in handle_batch_error (exception made for the masp fee paying tx that would be committed even in case of a failing atomic batch)

Comment on lines +357 to +358
// Emit the events of all the inner txs that have been
// successfully executed when handling the wrapper. These
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this imply that we do not emit the events of failing txs? hm. I was thinking what would happen with IBC ack failures, but I guess those are still successful tx executions (despite of the failure semantics).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct, I asked this question to @yito88 a few days ago, it seemed ok to me but maybe we can discuss it more in depth

Comment on lines 40 to 46
// NOTE: It is possible to have two identical references in a same batch:
// this is because, some types of MASP data packet can be correctly executed
// more than once (output descriptions). We have to make sure we account for
// this by using collections that allow for duplicates (both in the args
// and in the returned type): if the same reference shows up multiple
// times in the input we must process it the same number of times to
// ensure we contruct the correct state
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this comment doesn't make sense anymore, we're returning a single Transaction (rather than a Vec of them)

Copy link
Copy Markdown
Collaborator Author

@grarco grarco Mar 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 053eb19 👍🏻

Comment on lines +114 to +139
// Check if the event is a Masp one
let Ok(kind) = namada_events::EventType::from_str(&event.kind)
else {
return Ok(None);
};

let kind = if kind == namada_tx::event::masp_types::TRANSFER {
MaspEventKind::Transfer
} else if kind == namada_tx::event::masp_types::FEE_PAYMENT {
MaspEventKind::FeePayment
} else {
return Ok(None);
};

// Extract the data from the event's attributes, propagate errors if
// the masp event does not follow the expected format
let data =
MaspTxRef::read_from_event_attributes(&event.attributes)?;
let tx_index =
IndexedTx::read_from_event_attributes(&event.attributes)?;

Ok(Some(MaspEvent {
tx_index,
kind,
data,
}))
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

impl a TryFrom<Event> for MaspEvent

Comment on lines +31 to +32
/// The masp tx kind, fee-payment or transfer
pub kind: MaspEventKind,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it feels like code duplication, but it might be better to have a separate type for the kind of masp indexed tx. we might want to introduce other masp event kinds that have nothing to do with the way we intend to sort masp indexed txs.

Copy link
Copy Markdown
Collaborator Author

@grarco grarco Mar 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 4d9efbd

use namada_tx::{IndexedTx, IndexedTxRange};
use serde::{Deserialize, Serialize};

/// An indexed masp tx carrying information on wether it was a fee paying tx or
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// An indexed masp tx carrying information on wether it was a fee paying tx or
/// An indexed masp tx carrying information on whether it was a fee paying tx or

.map(|(masp_indexed_tx, transaction)| {
(masp_indexed_tx.indexed_tx, transaction)
})
.collect::<BTreeMap<_, _>>()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not collect a new BTreeMap here. The contains_height method is supposed to be relatively cheap. We can modify IndexedTxRange to refer to a MaspIndexedTxRange instead. Lmk if you need help with this.

Copy link
Copy Markdown
Collaborator Author

@grarco grarco Mar 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've created a new MaspIndexedTxRange type for this purpose in 7df026f. I've also left IndexedTxRange untouched as I feel it could come in handy in the future or to current sdk users

@grarco grarco added the ledger label Mar 11, 2025
grarco added a commit that referenced this pull request Mar 17, 2025
@grarco grarco mentioned this pull request Mar 18, 2025
3 tasks
@grarco
Copy link
Copy Markdown
Collaborator Author

grarco commented Mar 18, 2025

@tzemanovic, @sug0, @batconjurer, @murisi I'm closing this in favor of #4475 which is the rebased version of this branch of top of main where I've removed the changes brought in by #4442

@grarco grarco closed this Mar 18, 2025
grarco added a commit that referenced this pull request Mar 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking:api public API breaking change ledger

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants