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 23.40426% with 72 lines in your changes missing coverage. Please review.
✅ Project coverage is 34.90%. Comparing base (9e434ee) to head (ea8efef).
⚠️ Report is 7 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4174      +/-   ##
==========================================
+ Coverage   33.05%   34.90%   +1.85%     
==========================================
  Files         459      463       +4     
  Lines       55830    55992     +162     
==========================================
+ Hits        18453    19543    +1090     
+ Misses      34159    32984    -1175     
- Partials     3218     3465     +247     

@github-actions
Copy link

github-actions bot commented Dec 24, 2025

❌ 7 Tests Failed:

Tests completed Failed Passed Skipped
4454 7 4447 0
View the top 3 failed tests by shortest run time
TestSetLatestSnapshotUrl
Stack Traces | 0.140s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
    init_test.go:300: running test case latest file with http url
INFO [12-31|10:22:42.169] Set latest snapshot url                  url=http://some.domain.com/arb1/2024/21/archive.tar.gz
    init_test.go:300: running test case latest file with https url
INFO [12-31|10:22:42.172] Set latest snapshot url                  url=https://some.domain.com/arb1/2024/21/archive.tar.gz
    init_test.go:300: running test case chain and contents with upper case
INFO [12-31|10:22:42.173] Set latest snapshot url                  url=http://127.0.0.1:39263/arb1/2024/21/archive.tar.gz
    init_test.go:353: goroutine 87 [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({0x2e5fdf0, 0xc0004a7500}, {0x2e32ac0, 0x41b6460}, {0xc000906000, 0x1, 0x1})
        	/home/runner/work/nitro/nitro/util/testhelpers/testhelpers.go:29 +0x55
        github.com/offchainlabs/nitro/cmd/nitro.Require(0xc0004a7500, {0x2e32ac0, 0x41b6460}, {0xc000906000, 0x1, 0x1})
        	/home/runner/work/nitro/nitro/cmd/nitro/config_test.go:304 +0x5d
        github.com/offchainlabs/nitro/cmd/nitro.startFileServer.func2()
        	/home/runner/work/nitro/nitro/cmd/nitro/init_test.go:353 +0xa5
        created by github.com/offchainlabs/nitro/cmd/nitro.startFileServer in goroutine 13
        	/home/runner/work/nitro/nitro/cmd/nitro/init_test.go:350 +0x285
        
    init_test.go:353: �[31;1m [failed to shutdown server] context canceled �[0;0m
--- FAIL: TestSetLatestSnapshotUrl (0.14s)
TestDataStreaming_PositiveScenario/Many_senders,_long_messages
Stack Traces | 0.210s run time
=== RUN   TestDataStreaming_PositiveScenario/Many_senders,_long_messages
WARN [12-31|10:21:28.380] Served datastreaming_start               conn=127.0.0.1:38402 reqid=8 duration=12.216437ms err="we have already seen this request; aborting replayed protocol"
INFO [12-31|10:21:28.419] rpc response                             method=datastreaming_start logId=8 err="we have already seen this request; aborting replayed protocol" result={} attempt=0 args="[\"0x6954f928\", \"0x32\", \"0xd9\", \"0x2a10\", \"0xa\", \"0xd199966a5b9702afdd1aa022571641f80c7eceec61b47be2336e83f25a4fc44f07489b11d3497e0ff31e88e3b17924bc50ee2d5b78277218dd173ffac6b589f300\"]" errorData=null
    protocol_test.go:230: goroutine 252 [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({0x1568e90, 0xc000225340}, {0x154f940, 0xc000a03d40}, {0x0, 0x0, 0x0})
        	/home/runner/work/nitro/nitro/util/testhelpers/testhelpers.go:29 +0x55
        github.com/offchainlabs/nitro/daprovider/data_streaming.testBasic.func1()
        	/home/runner/work/nitro/nitro/daprovider/data_streaming/protocol_test.go:230 +0x14f
        created by github.com/offchainlabs/nitro/daprovider/data_streaming.testBasic in goroutine 245
        	/home/runner/work/nitro/nitro/daprovider/data_streaming/protocol_test.go:223 +0x85
        
    protocol_test.go:230: �[31;1m [] we have already seen this request; aborting replayed protocol �[0;0m
--- FAIL: TestDataStreaming_PositiveScenario/Many_senders,_long_messages (0.21s)
TestDataStreaming_PositiveScenario
Stack Traces | 0.240s run time
=== RUN   TestDataStreaming_PositiveScenario
--- FAIL: TestDataStreaming_PositiveScenario (0.24s)

📣 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