Skip to content

Add ErrAddressFiltered error type to store filtered records#4642

Draft
MishkaRogachev wants to merge 11 commits intomasterfrom
prechecker-calls-cmdfiltering-report-to-report-that-a
Draft

Add ErrAddressFiltered error type to store filtered records#4642
MishkaRogachev wants to merge 11 commits intomasterfrom
prechecker-calls-cmdfiltering-report-to-report-that-a

Conversation

@MishkaRogachev
Copy link
Copy Markdown
Contributor

@MishkaRogachev MishkaRogachev commented Apr 15, 2026

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 15, 2026

Codecov Report

❌ Patch coverage is 17.39130% with 418 lines in your changes missing coverage. Please review.
✅ Project coverage is 35.49%. Comparing base (57d9bf1) to head (3dfbbc9).
⚠️ Report is 109 commits behind head on add-report-filtered-txn-api-2.

Additional details and impacted files
@@                        Coverage Diff                        @@
##           add-report-filtered-txn-api-2    #4642      +/-   ##
=================================================================
+ Coverage                          33.90%   35.49%   +1.59%     
=================================================================
  Files                                498      501       +3     
  Lines                              59879    60253     +374     
=================================================================
+ Hits                               20303    21389    +1086     
+ Misses                             36022    35067     -955     
- Partials                            3554     3797     +243     

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 15, 2026

❌ 7 Tests Failed:

Tests completed Failed Passed Skipped
5014 7 5007 0
View the top 3 failed tests by shortest run time
TestMultigasStylus_StorageWrite/out_of_gas
Stack Traces | 0.010s run time
=== RUN   TestMultigasStylus_StorageWrite/out_of_gas
INFO [04-16|17:17:59.766] Imported new potential chain segment     number=47   hash=7106aa..d37b52 blocks=1  txs=1  mgas=0.021  elapsed=1.618ms      mgasps=12.975   triediffs=222.48KiB  triedirty=0.00B
INFO [04-16|17:17:59.767] Chain head was updated                   number=47   hash=7106aa..d37b52 root=85c3db..f7e6bf elapsed="68.082µs"
INFO [04-16|17:17:59.767] Starting work on payload                 id=0x03a6f13d2ea9bd21
INFO [04-16|17:17:59.767] Starting work on payload                 id=0x03bc300bc49255f0
INFO [04-16|17:17:59.767] Starting work on payload                 id=0x03e61e3af3ce7ec0
INFO [04-16|17:17:59.771] Submitted transaction                    hash=0x8623191123773f72a9c0f6dbe25407504d9ac9404f04b5ed6e79e04160f1bc31 from=0x26E554a8acF9003b83495c7f45F06edCB803d4e3 nonce=4    recipient=0x3a0a61C11D96F5B8c1492bEaA5bDAedefFff15E8 value=0
INFO [04-16|17:17:59.771] Starting work on payload                 id=0x039136742e039dc3
INFO [04-16|17:17:59.766] Submitted contract creation              hash=0x18e9b9da9aaf7dc9ab70f819e1d0f43b2a64bddc6129c9fb254d9537e59969ac from=0x57Ff0F473737a1c161bfF9efDF016F7991585088 nonce=8    contract=0x64a43e36cC9cE3126a39d5B8034195B308940273 value=0
    multigas_stylus_program_test.go:380: 
        	Error Trace:	/home/runner/work/nitro/nitro/system_tests/multigas_stylus_program_test.go:380
        	Error:      	An error is expected but got nil.
        	Test:       	TestMultigasStylus_StorageWrite/out_of_gas
INFO [04-16|17:17:59.773] Updated payload                          id=0x039136742e039dc3 number=45   hash=fa24b7..8b9c38 txs=1  withdrawals=0 gas=145,746    fees=7.2873e-06     root=712602..fe8c6d elapsed=1.160ms
INFO [04-16|17:17:59.773] Updated payload                          id=0x03e61e3af3ce7ec0 number=40   hash=11b7e0..ff1f86 txs=1  withdrawals=0 gas=21000      fees=0.00208206294  root=b5d302..c65a42 elapsed=1.583ms
--- FAIL: TestMultigasStylus_StorageWrite/out_of_gas (0.01s)
TestMultigasStylus_StorageWrite
Stack Traces | 1.530s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
INFO [04-16|17:17:59.837] Imported new potential chain segment     number=156  hash=e18858..f2a091 blocks=1  txs=1  mgas=0.021  elapsed=3.034ms      mgasps=6.921    triediffs=791.72KiB  triedirty=49.96KiB
INFO [04-16|17:17:59.838] Chain head was updated                   number=156  hash=e18858..f2a091 root=1e0965..47ae53 elapsed="55.713µs"
INFO [04-16|17:17:59.838] Updated payload                          id=0x039203bcd38008f5 number=44   hash=caa0d2..5b261e txs=0  withdrawals=0 gas=0          fees=0              root=fd62b0..d06b1e elapsed="585.558µs"
INFO [04-16|17:17:59.838] Stopping work on payload                 id=0x039203bcd38008f5 reason=delivery
INFO [04-16|17:17:59.838] Starting work on payload                 id=0x034c52c99fc8246a
INFO [04-16|17:17:59.837] First reconnection attempt, skipping backoff url=ws://localhost:42997/feed
INFO [04-16|17:17:59.839] connecting to arbitrum inbox message broadcaster url=ws://localhost:42997/feed
INFO [04-16|17:17:59.840] Stopping work on payload                 id=0x03fcfd156da1ef38 reason=delivery
INFO [04-16|17:17:59.837] Starting work on payload                 id=0x032a55c6670dec28
INFO [04-16|17:17:59.843] Updated payload                          id=0x032a55c6670dec28 number=51   hash=0cb899..4e7d44 txs=1  withdrawals=0 gas=21000      fees=0.002095862245 root=c44759..62e532 elapsed=1.380ms
INFO [04-16|17:17:59.844] Imported new potential chain segment     number=15   hash=f1cc47..0b5d8d blocks=1  txs=1  mgas=1.691  elapsed=6.293ms      mgasps=268.714  triediffs=50.65KiB   triedirty=0.00B
INFO [04-16|17:17:59.844] Submitted transaction                    hash=0xc3c32dfc9327c99c5b1fd3de83ff1fab239be7bebceb0fb3081f20288b5d9da1 from=0xaF24Ca6c2831f4d4F629418b50C227DF0885613A nonce=9    recipient=0xaF24Ca6c2831f4d4F629418b50C227DF0885613A value=1,000,000,000,000
INFO [04-16|17:17:59.845] Chain head was updated                   number=15   hash=f1cc47..0b5d8d root=ca0ecc..8f04cb elapsed="317.056µs"
INFO [04-16|17:17:59.845] Stopping work on payload                 id=0x032a55c6670dec28 reason=delivery
INFO [04-16|17:17:59.846] Imported new potential chain segment     number=51   hash=0cb899..4e7d44 blocks=1  txs=1  mgas=0.021  elapsed=2.860ms      mgasps=7.340    triediffs=239.01KiB  triedirty=0.00B
INFO [04-16|17:17:59.846] Chain head was updated                   number=51   hash=0cb899..4e7d44 root=c44759..62e532 elapsed="74.332µs"
--- FAIL: TestMultigasStylus_StorageWrite (1.53s)
INFO [04-16|17:17:59.846] Starting work on payload                 id=0x0329394af5b74520
INFO [04-16|17:17:59.847] Batch overflow: compressed size limit exceeded compressedSize=247 limit=186 isHeader=false
INFO [04-16|17:17:59.846] Submitted transaction                    hash=0x6a1cf092c6d6afdf876d7804bb459aa4f7c1329a31bd5ecaa42b24236e5b0921 from=0xaF24Ca6c2831f4d4F629418b50C227DF0885613A nonce=8    recipient=0xaF24Ca6c2831f4d4F629418b50C227DF0885613A value=1,000,000,000,000
TestInboxReaderBlobFailureWithDelayedMessage
Stack Traces | 9.510s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
INFO [04-16|17:19:56.009] Chain head was updated                   number=23  hash=bb6aa7..151a2a root=2475fc..22fe24 elapsed="116.518µs"
INFO [04-16|17:19:56.010] Submitted contract creation              hash=0x759e8c841596b766fc24b768819a373686827440c789178fd7da88942e952d45 from=0x57Ff0F473737a1c161bfF9efDF016F7991585088 nonce=20  contract=0x454Df6179dEbE92aC81Bfb974a4ad731Cd7dB628 value=0
INFO [04-16|17:19:56.010] Submitted transaction                    hash=0x9349503ebfa05942d95c9c85b7872edc2eb012d041775ebe6ffe55e7d11b1f3d from=0xaF24Ca6c2831f4d4F629418b50C227DF0885613A nonce=15  recipient=0xaF24Ca6c2831f4d4F629418b50C227DF0885613A value=1,000,000,000,000
INFO [04-16|17:19:56.012] Starting work on payload                 id=0x03c95fb315f4d7aa
INFO [04-16|17:19:56.015] Starting work on payload                 id=0x031b46b335653201
INFO [04-16|17:19:56.016] Updated payload                          id=0x03c95fb315f4d7aa number=24  hash=2e0aaa..88ad79 txs=1   withdrawals=0 gas=3,767,892  fees=3.767892e-06   root=475410..52ffa3 elapsed=2.907ms
INFO [04-16|17:19:56.019] Stopping work on payload                 id=0x03c95fb315f4d7aa reason=delivery
INFO [04-16|17:19:56.019] Submitted transaction                    hash=0x270ade2ec1a345d2c812250b0a957f130dcf8c5651d98f1bb9d73983c011ee2d from=0xaF24Ca6c2831f4d4F629418b50C227DF0885613A nonce=203 recipient=0xaF24Ca6c2831f4d4F629418b50C227DF0885613A value=1
INFO [04-16|17:19:56.022] Imported new potential chain segment     number=24  hash=2e0aaa..88ad79 blocks=1  txs=1   mgas=3.768  elapsed=5.768ms     mgasps=653.174  triediffs=86.02KiB  triedirty=0.00B
INFO [04-16|17:19:56.023] Chain head was updated                   number=24  hash=2e0aaa..88ad79 root=475410..52ffa3 elapsed="443.971µs"
INFO [04-16|17:19:56.025] Starting work on payload                 id=0x037e745051d89123
INFO [04-16|17:19:56.026] Updated payload                          id=0x037e745051d89123 number=25  hash=d485af..10ecc7 txs=0   withdrawals=0 gas=0          fees=0              root=15ac31..9d21ed elapsed="862.633µs"
INFO [04-16|17:19:56.027] Stopping work on payload                 id=0x037e745051d89123 reason=delivery
INFO [04-16|17:19:56.027] Imported new potential chain segment     number=25  hash=d485af..10ecc7 blocks=1  txs=0   mgas=0.000  elapsed=1.072ms     mgasps=0.000    triediffs=88.92KiB  triedirty=0.00B
INFO [04-16|17:19:56.028] Chain head was updated                   number=25  hash=d485af..10ecc7 root=15ac31..9d21ed elapsed="41.487µs"
INFO [04-16|17:19:56.031] Persisted dirty state to disk            size=287.98KiB elapsed=23.156ms
INFO [04-16|17:19:56.032] Blockchain stopped
INFO [04-16|17:19:56.034] Updated payload                          id=0x031b46b335653201 number=51  hash=d9ac72..215b84 txs=1   withdrawals=0 gas=21000      fees=0.002095857636 root=01a1ae..d8fd9b elapsed=18.989ms
WARN [04-16|17:19:56.035] Served eth_getTransactionReceipt         reqid=5  duration="22.502µs"   err="transaction indexing is in progress" errdata="\"transaction indexing is in progress\""
--- FAIL: TestInboxReaderBlobFailureWithDelayedMessage (9.51s)

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

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds end-to-end reporting of address-filtered transactions from TxPreChecker to an external “filtering-report” JSON-RPC service, along with a system test to validate the reporting behavior (Fixes NIT-4645).

Changes:

  • Add a FilteringReportRPCClient hook to TxPreChecker and send a FilteredTxReport when a transaction is rejected due to address filtering.
  • Extend txFilterer to capture and expose filtered address records for inclusion in the report payload.
  • Add a system test that spins up a local JSON-RPC server to collect and assert reported filtering events.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
system_tests/prechecker_filter_test.go Adds a JSON-RPC test server and a new system test asserting reports are emitted for filtered txs
execution/gethexec/tx_pre_checker.go Adds filtering-report client wiring and report generation on ErrArbTxFilter
execution/gethexec/tx_filterer.go Captures filtered address records from StateDB.IsAddressFiltered() for reporting
execution/gethexec/node.go Wires an optional FilteringReportRPCClient into the TxPreChecker
changelog/mrogachev-nit-4645.md Documents the new filtered-transaction reporting behavior

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread system_tests/prechecker_filter_test.go Outdated
go httpServer.Serve(listener) //nolint:errcheck
go func() {
<-ctx.Done()
httpServer.Shutdown(context.Background()) //nolint:errcheck
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

httpServer.Shutdown(context.Background()) can block indefinitely if connections don’t close. In tests this can hang the suite; use a context with timeout (e.g., context.WithTimeout) for shutdown.

Suggested change
httpServer.Shutdown(context.Background()) //nolint:errcheck
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
httpServer.Shutdown(shutdownCtx) //nolint:errcheck

Copilot uses AI. Check for mistakes.
Comment on lines 18 to 22
type txFilterer struct {
execEngine *ExecutionEngine
eventFilter *eventfilter.EventFilter
execEngine *ExecutionEngine
eventFilter *eventfilter.EventFilter
filteredRecords []filter.FilteredAddressRecord
}
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

txFilterer now stores filteredRecords on the struct, but the same txFilterer instance is created once in execution/gethexec/node.go and used by the backend for RPC calls. This introduces a potential data race and cross-request contamination when concurrent calls (e.g., eth_call / estimateGas / precheck) invoke CheckFiltered/FilteredRecords. Prefer returning the filtered records via an error value (e.g., a typed ErrAddressFiltered carrying records) or storing them in request-local state instead of mutating shared struct fields.

Copilot uses AI. Check for mistakes.
Comment on lines +357 to +358
report := addressfilter.FilteredTxReport{
ID: uuid.Must(uuid.NewV7()).String(),
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

uuid.Must(uuid.NewV7()) will panic if UUID generation fails (e.g., entropy/rand read failure). Panicking inside TxPreChecker can crash the node; generate the UUID and return/log the error instead of using Must.

Suggested change
report := addressfilter.FilteredTxReport{
ID: uuid.Must(uuid.NewV7()).String(),
reportID, err := uuid.NewV7()
if err != nil {
return fmt.Errorf("failed to generate filtered tx report id: %w", err)
}
report := addressfilter.FilteredTxReport{
ID: reportID.String(),

Copilot uses AI. Check for mistakes.
Comment thread execution/gethexec/tx_pre_checker.go Outdated
Comment on lines +369 to +370
// Non-blocking: ReportFilteredTransactions uses LaunchPromiseThread internally.
c.filteringReportRPCClient.ReportFilteredTransactions([]addressfilter.FilteredTxReport{report})
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

ReportFilteredTransactions returns a Promise containing the RPC call error, but the result is currently ignored. This makes report delivery failures silent and also makes the log message above misleading (it only catches build-time errors). Consider awaiting the promise in a background goroutine (similar to executionengine.go’s pattern) and logging any RPC error.

Suggested change
// Non-blocking: ReportFilteredTransactions uses LaunchPromiseThread internally.
c.filteringReportRPCClient.ReportFilteredTransactions([]addressfilter.FilteredTxReport{report})
// Non-blocking: await the async RPC result in a background goroutine so
// report delivery failures are not silently ignored.
promise := c.filteringReportRPCClient.ReportFilteredTransactions([]addressfilter.FilteredTxReport{report})
go func(txHash common.Hash) {
if err := promise.Await(); err != nil {
log.Error("failed to deliver filtered tx report", "txHash", txHash, "err", err)
}
}(tx.Hash())

Copilot uses AI. Check for mistakes.
Comment thread execution/gethexec/tx_pre_checker.go Outdated
Comment on lines +335 to +338
var filteredAddresses []filter.FilteredAddressRecord
if tf, ok := c.backend.TxFilter().(*txFilterer); ok {
filteredAddresses = tf.FilteredRecords()
}
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

This code path depends on c.backend.TxFilter() being the concrete *txFilterer to retrieve filtered address records. Besides coupling TxPreChecker to a specific backend implementation, this also relies on shared mutable state inside txFilterer (see tx_filterer.go) which can be overwritten by concurrent requests. Prefer extracting filtered records from the filtering error itself (errors.As on a typed error carrying records) or another request-local mechanism.

Copilot uses AI. Check for mistakes.
@MishkaRogachev MishkaRogachev changed the base branch from add-report-filtered-txn-api-2 to master April 17, 2026 11:09
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