Skip to content

Require native-asset fee notes when fees are enabled - #2564

Open
Mirko-von-Leipzig wants to merge 8 commits into
mirko/deny-fee-eatersfrom
mirko/require-fee-notes
Open

Mirko-von-Leipzig wants to merge 8 commits into
mirko/deny-fee-eatersfrom
mirko/require-fee-notes

Conversation

@Mirko-von-Leipzig

@Mirko-von-Leipzig Mirko-von-Leipzig commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Standalone transactions are now rejected if they omit a TX_FEE note when the reference block's verification base fee is nonzero. Any fee notes they emit must contain only the native asset. This asset restriction will be relaxed in the future.

Transactions can omit fee notes when the reference block's verification base fee is zero. Zero-valued native fee notes are also accepted. These checks do not determine whether the amount covers the transaction cost.

User-submitted batches are exempt. They are already proven and handle their own fee collection, so their transactions do not each need to output a fee note.

Part of #2501.

Changelog

[[entry]]
scope       = "rpc"
impact      = "breaking"
description = "Require native-asset fee output notes for standalone transaction submissions when fees are enabled."

@Mirko-von-Leipzig Mirko-von-Leipzig changed the title fix(rpc): require fee notes for all transactions fix(rpc): require fee notes on all submitted transactions Sep 16, 2026
@Mirko-von-Leipzig Mirko-von-Leipzig changed the title fix(rpc): require fee notes on all submitted transactions fix(rpc): require fee notes on standalone transactions Sep 16, 2026
@Mirko-von-Leipzig Mirko-von-Leipzig changed the title fix(rpc): require fee notes on standalone transactions fix(rpc): require native-asset fee notes on standalone transactions Sep 16, 2026
@Mirko-von-Leipzig Mirko-von-Leipzig changed the title fix(rpc): require native-asset fee notes on standalone transactions Require native-asset fee notes on standalone transactions Sep 16, 2026
@Mirko-von-Leipzig
Mirko-von-Leipzig marked this pull request as ready for review September 16, 2026 13:53

@igamigo igamigo left a comment

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.

LGTM!

if note.recipient().script().root() != fee_script_root {
continue;
}
if !matches!(note.assets().as_slice(), [asset] if asset.id() == fee_asset_id) {

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 it's technically possible to create a valid fee note that has the assets, but with a quantity of 0. If so, wonder if we should check that the amount is at least > 0 (but maybe it'd be even better to have a minimum amount that a minimal transaction would cost to compare against). cc @PhilippGackstatter @mmagician to confirm

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.

I actually want to allow zero so that this same flow works on networks with a zero fee.

This technically doesn't work at the moment because some protocol procedures explicitly emit no note when fees set to zero.

It's an.. open question at the moment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think none of the standard auth components emit fee notes when fees are zero. I think the main motivation was avoiding touching most protocol tests that would now output fee notes and change the assertions. Certainly something we could revisit, but for now the node may be better off skipping the fee requirement when fees are zero.

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.

Updated in bb18069. Both standalone transaction endpoints now allow a missing fee note when the transaction reference block has a zero verification base fee. Any fee notes that are emitted must still contain only the native asset; user batches remain exempt. The batch-building PR (#2647) also skips the collector transaction when there are no fee notes, since a deployed collector cannot execute without input notes.

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.

But should transactions that create a fee note with 0 assets (or a small enough amount of tokens which you know won't cover the tx) for networks that require fees even be allowed? Technically yes because at the batch level fees may still be enough to include the transaction? I understand standards pay fees correctly but a user could decide to pay whatever amount of fees they wanted.

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.

The batch builder can decide, in theory, to sponsor or accept whatever transactions it wants.

I wanted this to be a flat:

  • never allow txs without a fee note
  • only accept fee notes with a native asset
  • only accept fee notes which pay more than their tx requires

but we can' really do that

@kkovaacs kkovaacs left a comment

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.

Looks good to me!

@Mirko-von-Leipzig Mirko-von-Leipzig changed the title Require native-asset fee notes on standalone transactions Require native-asset fee notes on every transaction Sep 17, 2026
@Mirko-von-Leipzig
Mirko-von-Leipzig removed this pull request from stack #2569 September 17, 2026 11:59
@Mirko-von-Leipzig
Mirko-von-Leipzig added this pull request to stack #2641 September 17, 2026 12:01

@PhilippGackstatter PhilippGackstatter left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good!

if note.recipient().script().root() != fee_script_root {
continue;
}
if !matches!(note.assets().as_slice(), [asset] if asset.id() == fee_asset_id) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think none of the standard auth components emit fee notes when fees are zero. I think the main motivation was avoiding touching most protocol tests that would now output fee notes and change the assertions. Certainly something we could revisit, but for now the node may be better off skipping the fee requirement when fees are zero.

@Mirko-von-Leipzig
Mirko-von-Leipzig removed this pull request from stack #2641 September 18, 2026 09:45
@Mirko-von-Leipzig
Mirko-von-Leipzig added this pull request to stack #2649 September 18, 2026 09:47
@Mirko-von-Leipzig Mirko-von-Leipzig changed the title Require native-asset fee notes on every transaction Require native-asset fee notes when fees are enabled Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants