Skip to content

Conversation

@MishkaRogachev
Copy link
Contributor

@MishkaRogachev MishkaRogachev commented Dec 24, 2025

Fixes NIT-4152 and NIT-4253
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
  • Limit filtered transactions feature with ArbCensoredTransactionManagerFromTime

@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 28.83436% with 116 lines in your changes missing coverage. Please review.
✅ Project coverage is 32.89%. Comparing base (02566fc) to head (ce49b11).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4174      +/-   ##
==========================================
- Coverage   33.41%   32.89%   -0.53%     
==========================================
  Files         461      463       +2     
  Lines       55901    56034     +133     
==========================================
- Hits        18681    18431     -250     
- Misses      33921    34387     +466     
+ Partials     3299     3216      -83     

@github-actions
Copy link

github-actions bot commented Dec 24, 2025

❌ 8 Tests Failed:

Tests completed Failed Passed Skipped
4449 8 4441 0
View the top 3 failed tests by shortest run time
TestEndToEnd_ManyEvilValidators
Stack Traces | -0.000s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
created by github.com/offchainlabs/nitro/bold/challenge/tracker.(*Tracker).Act in goroutine 256930
	/home/runner/work/nitro/nitro/bold/challenge/tracker/tracker.go:357 +0x10bf

goroutine 269950 [select]:
github.com/offchainlabs/nitro/bold/containers/events.(*Subscription[...]).Next(0x1fc42e0, {0x1fc42e0?, 0xc005ea4500?})
	/home/runner/work/nitro/nitro/bold/containers/events/producer.go:131 +0xd0
github.com/offchainlabs/nitro/bold/challenge/tracker.(*Tracker).Spawn(0xc009914500, {0x1fc42e0, 0xc005ea4500})
	/home/runner/work/nitro/nitro/bold/challenge/tracker/tracker.go:205 +0x235
created by github.com/offchainlabs/nitro/bold/challenge/tracker.(*Tracker).Act in goroutine 256398
	/home/runner/work/nitro/nitro/bold/challenge/tracker/tracker.go:358 +0x1125

goroutine 3956877 [select]:
github.com/offchainlabs/nitro/bold/assertions.(*Manager).keepTryingAssertionConfirmation(0xc001a03080, {0x1fc42e0, 0xc00197d770}, {{0xb7, 0xb5, 0xf7, 0x21, 0x22, 0xb9, 0xb3, ...}})
	/home/runner/work/nitro/nitro/bold/assertions/confirmation.go:72 +0x7b3
github.com/offchainlabs/nitro/bold/assertions.(*Manager).queueCanonicalAssertionsForConfirmation.func1({0x1fc42e0?, 0xc00197d770?})
	/home/runner/work/nitro/nitro/bold/assertions/confirmation.go:30 +0x4c
github.com/offchainlabs/nitro/util/stopwaiter.(*StopWaiterSafe).LaunchThreadSafe.func1()
	/home/runner/work/nitro/nitro/util/stopwaiter/stopwaiter.go:163 +0x38
created by github.com/offchainlabs/nitro/util/stopwaiter.(*StopWaiterSafe).LaunchThreadSafe in goroutine 198004
	/home/runner/work/nitro/nitro/util/stopwaiter/stopwaiter.go:162 +0x125
TestEndToEnd_ManyEvilValidators/honest_essential_edges_confirmed_by_challenge_win
Stack Traces | -0.000s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
created by github.com/offchainlabs/nitro/bold/challenge/tracker.(*Tracker).Act in goroutine 256930
	/home/runner/work/nitro/nitro/bold/challenge/tracker/tracker.go:357 +0x10bf

goroutine 269950 [select]:
github.com/offchainlabs/nitro/bold/containers/events.(*Subscription[...]).Next(0x1fc42e0, {0x1fc42e0?, 0xc005ea4500?})
	/home/runner/work/nitro/nitro/bold/containers/events/producer.go:131 +0xd0
github.com/offchainlabs/nitro/bold/challenge/tracker.(*Tracker).Spawn(0xc009914500, {0x1fc42e0, 0xc005ea4500})
	/home/runner/work/nitro/nitro/bold/challenge/tracker/tracker.go:205 +0x235
created by github.com/offchainlabs/nitro/bold/challenge/tracker.(*Tracker).Act in goroutine 256398
	/home/runner/work/nitro/nitro/bold/challenge/tracker/tracker.go:358 +0x1125

goroutine 3956877 [select]:
github.com/offchainlabs/nitro/bold/assertions.(*Manager).keepTryingAssertionConfirmation(0xc001a03080, {0x1fc42e0, 0xc00197d770}, {{0xb7, 0xb5, 0xf7, 0x21, 0x22, 0xb9, 0xb3, ...}})
	/home/runner/work/nitro/nitro/bold/assertions/confirmation.go:72 +0x7b3
github.com/offchainlabs/nitro/bold/assertions.(*Manager).queueCanonicalAssertionsForConfirmation.func1({0x1fc42e0?, 0xc00197d770?})
	/home/runner/work/nitro/nitro/bold/assertions/confirmation.go:30 +0x4c
github.com/offchainlabs/nitro/util/stopwaiter.(*StopWaiterSafe).LaunchThreadSafe.func1()
	/home/runner/work/nitro/nitro/util/stopwaiter/stopwaiter.go:163 +0x38
created by github.com/offchainlabs/nitro/util/stopwaiter.(*StopWaiterSafe).LaunchThreadSafe in goroutine 198004
	/home/runner/work/nitro/nitro/util/stopwaiter/stopwaiter.go:162 +0x125
TestOutOfGasInStorageCacheFlush
Stack Traces | 4.019s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
    common_test.go:711: BuildL1 deployConfig: DeployBold=false, DeployReferenceDAContracts=false
    program_test.go:2834: goroutine 839371 [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({0x4107610, 0xc068873880}, {0x40c4260, 0xc12fc585c0}, {0x0, 0x0, 0x0})
        	/home/runner/work/nitro/nitro/util/testhelpers/testhelpers.go:29 +0x55
        github.com/offchainlabs/nitro/system_tests.Require(0xc068873880, {0x40c4260, 0xc12fc585c0}, {0x0, 0x0, 0x0})
        	/home/runner/work/nitro/nitro/system_tests/common_test.go:2034 +0x5d
        github.com/offchainlabs/nitro/system_tests.TestOutOfGasInStorageCacheFlush(0xc068873880)
        	/home/runner/work/nitro/nitro/system_tests/program_test.go:2834 +0x1006
        testing.tRunner(0xc068873880, 0x3d45110)
        	/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
        
    program_test.go:2834: �[31;1m [] failed calculating position for validation: batch not found on L1 yet �[0;0m
�[90mTime to activate storage: 155.628439ms�[0;0m
INFO [01-07|16:18:10.725] HTTP server stopped                      endpoint=127.0.0.1:45235
TRACE[01-07|16:18:10.725] P2P networking is spinning down
--- FAIL: TestOutOfGasInStorageCacheFlush (4.02s)

📣 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