Skip to content

Conversation

@MishkaRogachev
Copy link
Contributor

@MishkaRogachev MishkaRogachev commented Dec 24, 2025

Fixes NIT-4152
pulls in OffchainLabs/nitro-precompile-interfaces#25
pulls in OffchainLabs/go-ethereum#604
pulls in OffchainLabs/nitro-testnode#169

Changes:

  • Add new precompile ArbFilteredTransactionsManager to manage filtered transactions
  • Add transaction censors to ArbOs and ArbOwner to limit access to ArbFilteredTransactionsManager
  • Add an account, separated from ArbOs state, to store filtered transactions

@MishkaRogachev MishkaRogachev changed the title Add ArbCensoredTransactionsManager precompile (idle) Add ArbCensoredTransactionsManager precompile Dec 24, 2025
@MishkaRogachev MishkaRogachev force-pushed the create-arbcensoredtransactionsmanager-precompile branch from 1adc79f to 81f4e5e Compare December 24, 2025 14:55
@codecov
Copy link

codecov bot commented Dec 24, 2025

Codecov Report

❌ Patch coverage is 29.74684% with 111 lines in your changes missing coverage. Please review.
✅ Project coverage is 32.93%. Comparing base (02566fc) to head (85f6167).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4174      +/-   ##
==========================================
- Coverage   33.41%   32.93%   -0.49%     
==========================================
  Files         461      463       +2     
  Lines       55901    56029     +128     
==========================================
- Hits        18681    18453     -228     
- Misses      33921    34360     +439     
+ Partials     3299     3216      -83     

@github-actions
Copy link

github-actions bot commented Dec 24, 2025

❌ 4 Tests Failed:

Tests completed Failed Passed Skipped
4451 4 4447 0
View the top 3 failed tests by shortest run time
TestVersion30
Stack Traces | 7.100s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
=== PAUSE TestVersion30
=== CONT  TestVersion30
    precompile_inclusion_test.go:94: goroutine 610266 [running]:
        runtime/debug.Stack()
        	/opt/hostedtoolcache/go/1.25.5/x64/src/runtime/debug/stack.go:26 +0x5e
        github.com/offchainlabs/nitro/util/testhelpers.RequireImpl({0x4106190, 0xc083ac6380}, {0x40c3260, 0xc0f53eaa50}, {0x0, 0x0, 0x0})
        	/home/runner/work/nitro/nitro/util/testhelpers/testhelpers.go:29 +0x55
        github.com/offchainlabs/nitro/system_tests.Require(0xc083ac6380, {0x40c3260, 0xc0f53eaa50}, {0x0, 0x0, 0x0})
        	/home/runner/work/nitro/nitro/system_tests/common_test.go:2034 +0x5d
        github.com/offchainlabs/nitro/system_tests.testPrecompiles(0xc083ac6380, 0x1e, {0xc129fe1db0, 0x6, 0x4ce990?})
        	/home/runner/work/nitro/nitro/system_tests/precompile_inclusion_test.go:94 +0x371
        github.com/offchainlabs/nitro/system_tests.TestVersion30(0xc083ac6380?)
        	/home/runner/work/nitro/nitro/system_tests/precompile_inclusion_test.go:67 +0x798
        testing.tRunner(0xc083ac6380, 0x3d44238)
        	/opt/hostedtoolcache/go/1.25.5/x64/src/testing/testing.go:1934 +0xea
        created by testing.(*T).Run in goroutine 1
        	/opt/hostedtoolcache/go/1.25.5/x64/src/testing/testing.go:1997 +0x465
        
    precompile_inclusion_test.go:94: �[31;1m [] execution aborted (timeout = 5s) �[0;0m
--- FAIL: TestVersion30 (7.10s)
TestTimeboostAuctionResolutionDuringATie
Stack Traces | 18.720s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
DEBUG[01-05|16:54:48.239] Dereferenced trie from memory database   nodes=17   size=3.29KiB   time="35.397µs"  gcnodes=452   gcsize=83.29KiB   gctime=1.072946ms  livenodes=226   livesize=45.05KiB
DEBUG[01-05|16:54:48.239] Dereferenced trie from memory database   nodes=18   size=3.44KiB   time="165.429µs" gcnodes=470   gcsize=86.72KiB   gctime=1.238245ms  livenodes=208   livesize=41.61KiB
DEBUG[01-05|16:54:48.239] Dereferenced trie from memory database   nodes=16   size=3.18KiB   time="38.993µs"  gcnodes=486   gcsize=89.90KiB   gctime=1.277108ms  livenodes=192   livesize=38.43KiB
DEBUG[01-05|16:54:48.239] Dereferenced trie from memory database   nodes=16   size=3.22KiB   time="47.118µs"  gcnodes=502   gcsize=93.12KiB   gctime=1.324116ms  livenodes=176   livesize=35.21KiB
DEBUG[01-05|16:54:48.240] Dereferenced trie from memory database   nodes=16   size=3.19KiB   time="70.292µs"  gcnodes=518   gcsize=96.32KiB   gctime=1.394288ms  livenodes=160   livesize=32.02KiB
DEBUG[01-05|16:54:48.240] Dereferenced trie from memory database   nodes=16   size=3.18KiB   time="38.853µs"  gcnodes=534   gcsize=99.49KiB   gctime=1.433001ms  livenodes=144   livesize=28.84KiB
DEBUG[01-05|16:54:48.240] Dereferenced trie from memory database   nodes=16   size=3.18KiB   time="34.374µs"  gcnodes=550   gcsize=102.67KiB  gctime=1.467245ms  livenodes=128   livesize=25.66KiB
DEBUG[01-05|16:54:48.240] Dereferenced trie from memory database   nodes=16   size=3.22KiB   time="33.482µs"  gcnodes=566   gcsize=105.89KiB  gctime=1.500607ms  livenodes=112   livesize=22.44KiB
DEBUG[01-05|16:54:48.240] Dereferenced trie from memory database   nodes=17   size=3.29KiB   time="35.226µs"  gcnodes=583   gcsize=109.18KiB  gctime=1.535723ms  livenodes=95    livesize=19.15KiB
DEBUG[01-05|16:54:48.240] Dereferenced trie from memory database   nodes=16   size=3.22KiB   time="47.228µs"  gcnodes=599   gcsize=112.41KiB  gctime=1.582811ms  livenodes=79    livesize=15.93KiB
DEBUG[01-05|16:54:48.240] Dereferenced trie from memory database   nodes=16   size=3.22KiB   time="39.755µs"  gcnodes=615   gcsize=115.63KiB  gctime=1.622475ms  livenodes=63    livesize=12.71KiB
DEBUG[01-05|16:54:48.240] Dereferenced trie from memory database   nodes=15   size=3.08KiB   time="59.051µs"  gcnodes=630   gcsize=118.71KiB  gctime=1.681435ms  livenodes=48    livesize=9.63KiB
DEBUG[01-05|16:54:48.240] Dereferenced trie from memory database   nodes=16   size=3.21KiB   time="54.462µs"  gcnodes=646   gcsize=121.92KiB  gctime=1.735767ms  livenodes=32    livesize=6.42KiB
DEBUG[01-05|16:54:48.240] Dereferenced trie from memory database   nodes=16   size=3.21KiB   time="36.438µs"  gcnodes=662   gcsize=125.13KiB  gctime=1.772075ms  livenodes=16    livesize=3.21KiB
DEBUG[01-05|16:54:48.240] Dereferenced trie from memory database   nodes=16   size=3.21KiB   time="58.259µs"  gcnodes=678   gcsize=128.33KiB  gctime=1.830204ms  livenodes=0     livesize=0.00B
DEBUG[01-05|16:54:48.240] Dereferenced trie from memory database   nodes=0    size=0.00B     time=200ns       gcnodes=678   gcsize=128.33KiB  gctime=1.830294ms  livenodes=0     livesize=0.00B
DEBUG[01-05|16:54:48.240] Dereferenced trie from memory database   nodes=0    size=0.00B     time=190ns       gcnodes=678   gcsize=128.33KiB  gctime=1.830374ms  livenodes=0     livesize=0.00B
INFO [01-05|16:54:48.241] Blockchain stopped
TRACE[01-05|16:54:48.241] P2P networking is spinning down
--- FAIL: TestTimeboostAuctionResolutionDuringATie (18.72s)
TestTimeboostExpressLaneTransactionHandling
Stack Traces | 36.010s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
DEBUG[01-05|16:55:24.252] Dereferenced trie from memory database   nodes=16   size=3.25KiB   time="38.281µs"  gcnodes=887   gcsize=170.85KiB  gctime=2.452717ms  livenodes=192   livesize=38.68KiB
DEBUG[01-05|16:55:24.252] Dereferenced trie from memory database   nodes=16   size=3.38KiB   time="57.136µs"  gcnodes=903   gcsize=174.23KiB  gctime=2.509693ms  livenodes=176   livesize=35.30KiB
DEBUG[01-05|16:55:24.252] Dereferenced trie from memory database   nodes=17   size=3.38KiB   time="45.095µs"  gcnodes=920   gcsize=177.61KiB  gctime=2.554638ms  livenodes=159   livesize=31.92KiB
DEBUG[01-05|16:55:24.252] Dereferenced trie from memory database   nodes=16   size=3.29KiB   time="50.955µs"  gcnodes=936   gcsize=180.89KiB  gctime=2.605463ms  livenodes=143   livesize=28.63KiB
DEBUG[01-05|16:55:24.252] Dereferenced trie from memory database   nodes=24   size=4.59KiB   time="54.823µs"  gcnodes=960   gcsize=185.49KiB  gctime=2.660155ms  livenodes=119   livesize=24.04KiB
DEBUG[01-05|16:55:24.253] Dereferenced trie from memory database   nodes=18   size=3.56KiB   time="41.587µs"  gcnodes=978   gcsize=189.05KiB  gctime=2.701592ms  livenodes=101   livesize=20.48KiB
DEBUG[01-05|16:55:24.253] Dereferenced trie from memory database   nodes=18   size=3.53KiB   time="48.851µs"  gcnodes=996   gcsize=192.58KiB  gctime=2.750283ms  livenodes=83    livesize=16.95KiB
DEBUG[01-05|16:55:24.253] Dereferenced trie from memory database   nodes=17   size=3.40KiB   time="46.888µs"  gcnodes=1013  gcsize=195.97KiB  gctime=2.797031ms  livenodes=66    livesize=13.56KiB
DEBUG[01-05|16:55:24.253] Dereferenced trie from memory database   nodes=17   size=3.52KiB   time="49.332µs"  gcnodes=1030  gcsize=199.50KiB  gctime=2.846213ms  livenodes=49    livesize=10.03KiB
DEBUG[01-05|16:55:24.253] Dereferenced trie from memory database   nodes=16   size=3.24KiB   time="41.407µs"  gcnodes=1046  gcsize=202.74KiB  gctime=2.8875ms    livenodes=33    livesize=6.79KiB
DEBUG[01-05|16:55:24.253] Dereferenced trie from memory database   nodes=17   size=3.38KiB   time="38.231µs"  gcnodes=1063  gcsize=206.12KiB  gctime=2.925581ms  livenodes=16    livesize=3.41KiB
DEBUG[01-05|16:55:24.253] Dereferenced trie from memory database   nodes=16   size=3.41KiB   time="67.927µs"  gcnodes=1079  gcsize=209.53KiB  gctime=2.993367ms  livenodes=0     livesize=0.00B
DEBUG[01-05|16:55:24.253] Dereferenced trie from memory database   nodes=0    size=0.00B     time=301ns       gcnodes=1079  gcsize=209.53KiB  gctime=2.993518ms  livenodes=0     livesize=0.00B
DEBUG[01-05|16:55:24.253] Dereferenced trie from memory database   nodes=0    size=0.00B     time=180ns       gcnodes=1079  gcsize=209.53KiB  gctime=2.993588ms  livenodes=0     livesize=0.00B
INFO [01-05|16:55:24.254] Blockchain stopped
TRACE[01-05|16:55:24.249] Refreshing our lock                      id=auctioneer-f78a21c5-1767632088671865954
TRACE[01-05|16:55:24.254] P2P networking is spinning down
DEBUG[01-05|16:55:24.254] redis producer: check responses starting
DEBUG[01-05|16:55:24.254] checkResponses                           responded=0 errored=0 checked=0
--- FAIL: TestTimeboostExpressLaneTransactionHandling (36.01s)

📣 Thoughts on this report? Let Codecov know! | Powered by Codecov

@MishkaRogachev MishkaRogachev force-pushed the create-arbcensoredtransactionsmanager-precompile branch 2 times, most recently from 45fb413 to 67c13f2 Compare December 26, 2025 15:01
@MishkaRogachev MishkaRogachev changed the title Add ArbCensoredTransactionsManager precompile Add ArbFilteredTransactionsManager precompile Dec 26, 2025
@MishkaRogachev MishkaRogachev force-pushed the create-arbcensoredtransactionsmanager-precompile branch 2 times, most recently from acf9398 to 7b7a735 Compare December 26, 2025 19:18
Copy link
Member

@Tristan-Wilson Tristan-Wilson left a comment

Choose a reason for hiding this comment

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

Looks good, just a minor comment about consistency of the interface with other precompiles.

return filteredState.IsFiltered(txHash)
}

func (con ArbFilteredTransactionsManager) hasAccess(c *Context) (bool, error) {
Copy link
Member

Choose a reason for hiding this comment

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

This signature is slightly different to ArbNativeTokenManager which has

func (con ArbNativeTokenManager) hasAccess(c ctx) bool {
	manager, err := c.State.NativeTokenOwners().IsMember(c.caller)
	return manager && err == nil
}

and therefore the behavior when there is an error is slightly different in this implementation in that if there is an error, then the gas is not burned out.

Unsure if this difference is intentional or not.

@Tristan-Wilson
Copy link
Member

Tristan-Wilson commented Dec 29, 2025

We should consider making ArbFilteredTransactionsManager calls free for transaction censors, similar to how ArbOwner calls are free for chain owners. Currently, censors pay gas for AddFilteredTransaction/DeleteFilteredTransaction, but since they're trusted actors authorized by chain owners, it would make sense to follow the same pattern. This could be done by creating a CensorPrecompile wrapper (similar to OwnerPrecompile in wrapper.go) that checks TransactionCensors().IsMember(caller) and returns gasSupplied with multigas.ZeroGas() on success.

@MishkaRogachev
Copy link
Contributor Author

This could be done by creating a CensorPrecompile wrapper (similar to OwnerPrecompile in wrapper.go) that checks TransactionCensors().IsMember(caller) and returns gasSupplied with multigas.ZeroGas() on success.

@Tristan-Wilson, wdyt about going further: remove ArbNativeToken-style check and return an error right in CensorPrecompile, like in ArbOwner?

"github.com/offchainlabs/nitro/solgen/go/precompilesgen"
)

func TestManageTransactionCensors(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

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

Can you please also test that the transactions that should be free are free? You can look at TestArbNativeTokenManager and getGasUsed inside it for inspiration.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't really get how to use getGasUsed in this case, since the transaction will still cost something, only the add/delete call is free. I can suggest to use multigas like this:

	tx, err = arbFilteredTxs.AddFilteredTransaction(&censorTxOpts, txHash)
   require.NoError(t, err)
   receipt, err := builder.L2.EnsureTxSucceeded(tx)
   require.NoError(t, err)

   require.Equal(t, uint64(0), receipt.MultiGasUsed.Get(multigas.ResourceKindStorageAccess))

This somehow proves that tx did not perform any storage operations like set and clear

Copy link
Member

Choose a reason for hiding this comment

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

Could you check the censor account's balance is unchanged after adding/deleting filtered txs?

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.

3 participants