Skip to content

2026 Release v2.9.0 dev upgrade merge - #2557

Open
benjamin202410 wants to merge 173 commits into
mainfrom
dev-upgrade
Open

benjamin202410 wants to merge 173 commits into
mainfrom
dev-upgrade

Conversation

@benjamin202410

@benjamin202410 benjamin202410 commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

Proposed changes

  • P2P packages upgrade
  • Gas Fee 2500x change

Types of changes

What types of changes does your code introduce to XDC network?
Put an in the boxes that apply

  • build: Changes that affect the build system or external dependencies
  • ci: Changes to CI configuration files and scripts
  • chore: Changes that don't change source code or tests
  • docs: Documentation only changes
  • feat: A new feature
  • fix: A bug fix
  • perf: A code change that improves performance
  • refactor: A code change that neither fixes a bug nor adds a feature
  • revert: Revert something
  • style: Changes that do not affect the meaning of the code
  • test: Adding missing tests or correcting existing tests

Impacted Components

Which parts of the codebase does this PR touch?
Put an in the boxes that apply

  • Consensus
  • Account
  • Network
  • Geth
  • Smart Contract
  • External components
  • Not sure (Please specify below)

Checklist

Put an in the boxes once you have confirmed below actions (or provide reasons on not doing so) that

  • This PR has sufficient test coverage (unit/integration test) OR I have provided reason in the PR description for not having test coverage
  • Tested on a private network from the genesis block and monitored the chain operating correctly for multiple epochs.
  • Provide an end-to-end test plan in the PR description on how to manually test it on the devnet/testnet.
  • Tested the backwards compatibility.
  • Tested with XDC nodes running this version co-exist with those running the previous version.
  • Relevant documentation has been updated as part of this PR
  • N/A

gzliudan and others added 30 commits June 11, 2026 11:13
…thereum#18963 ethereum#19131 ethereum#19433 ethereum#19593 ethereum#19661 ethereum#19749 ethereum#19963 (#2346)

Introduce p2p/enode as the generalized node representation for peer and discovery code. The new package becomes the home for node records, local nodes, URL parsing, and the node database, while the v4 identity scheme moves out of p2p/enr to decouple ENR handling from Ethereum-specific crypto.

Port discovery, peer management, node APIs, and simulations to enode.Node and enode.ID. The discovery wire protocol stays unchanged, but APIs move away from discover.Node and NodeID and now require explicit record validation. Simulation helpers now track complete nodes and the updated tests cover the new connect and network behavior.

These changes align the fork with the upstream geth enode refactor and make later p2p and discovery updates easier to carry. Existing simulation snapshots are incompatible with the new node identifier representation.
PR #2329 promoted six XDC fork settings to top-level ChainConfig fields and added validation that rejects an XDPoS genesis missing them. The puppeth wizard was not updated, so generated XDPoS genesis files failed with 'invalid chain config: missing fork switch: TRC21IssuerSMC'.

Hardcode the four system contract addresses (TRC21IssuerSMC, XDCXListingSMC, RelayerRegistrationSMC, LendingRegistrationSMC) to their canonical mainnet values, and prompt for TIPTRC21FeeBlock and Gas50xBlock via the wizard. Gas50xBlock input is validated to be greater than or equal to TIPTRC21FeeBlock, with interactive re-entry on invalid values.
…2363)

* propose solution

* add tests

* fix test

* better comment

* add todo
Guard BFT broadcast enqueue with the quit channel so Vote/Timeout/SyncInfo exit cleanly once shutdown starts.

Add a regression test to ensure Vote returns after BFT loop stop and does not hang.
Replace the fixed sleep and one-shot synchronise call with a timeout-based retry loop so the test tolerates CI scheduling variance. Add protocol manager cleanup to avoid leaking background work between test runs.
…ethereum#19362 (#2369)

This resolves a minor issue where neighbors responses containing less
than 16 nodes would bump the failure counter, removing the node. One
situation where this can happen is a private deployment where the total
number of extant nodes is less than 16.

Issue found by @Jsying.

Co-authored-by: Felix Lange <[email protected]>
This entry was an experiment, but we're moving on to the
entry-per-protocol instead.

Co-authored-by: Felix Lange <[email protected]>
…m#19799 (#2374)

Make it select from all live nodes instead of selecting the heads of
random buckets.

Co-authored-by: Felix Lange <[email protected]>
…ereum#20367 (#2382)

* p2p/discv5: add deprecation warning and remove unused code

* p2p/discv5: remove unused variables

Co-authored-by: Felix Lange <[email protected]>
)

* p2p: wait for goroutine exit, fixes ethereum#20558

* p2p: wait for all slots on exit

Co-authored-by: Felix Lange <[email protected]>
Co-authored-by: Martin Holst Swende <[email protected]>
…eum#20573 (#2385)

This is a temporary fix for a problem which started happening when the
dialer was changed to read nodes from an enode.Iterator. Before the
iterator change, discovery queries would always return within a couple
seconds even if there was no Internet access. Since the iterator won't
return unless a node is actually found, discoverTask can take much
longer. This means that the 'emergency connect' logic might not execute
in time, leading to a stuck node.

Co-authored-by: Felix Lange <[email protected]>
gzliudan and others added 19 commits August 27, 2026 15:12
Concurrent removePeer callers (BFT broadcast loops, DAO fork timers,
normal teardown, and the downloader/fetcher drop callbacks) can all pass
the Peer(id) lookup before the first caller unregisters the peer, so each
re-runs the unregister sequence and floods the logs with "peer is not
registered" warnings on every peer drop.

Mark peer removal with an atomic flag so the unregister sequence runs
exactly once, and let downloader.UnregisterPeer treat an unregistered peer
as a silent no-op. In the same race window, handle() could register a peer
in the downloader after its removal was claimed, leaving a stale entry
that blocks a reconnect of the same node id; re-check the flag after
registering and undo the registration.
… race ethereum#35096 (#2539)

Port go-ethereum PR ethereum#35096. Move journal.close() from the loop goroutine's deferred call into Stop(), guarded by tracker.mu, so the journal is deterministically closed after wg.Wait() instead of racing with concurrent Track/TrackAll access during shutdown. The load/setupWriter half was already present in Start() on dev-upgrade.
The sync status logger only fired while the downloader was inside a bulk
historical sync. Once the node is caught up, new blocks are followed
through the block fetcher / BFT announcements, so Synchronising() stays
false and the warn log appeared only once or never over hours of normal
operation instead of every 10 minutes.

The logger now emits a status line on every 10-minute cycle with a
neutral message (current / highest / behind / peers). While the downloader
is actively synchronising it seeds current and highest from the downloader's
progress (the snap block and the discovered target); otherwise it seeds
current from the local chain head. In both states the reported highest is
the maximum of the seeded value and the per-peer live high-water mark fed
by block announcements (NewBlockMsg / NewBlockHashesMsg), so the gap stays
current even when the downloader is idle. The announced numbers are only
trusted after passing the fetcher's plausibility window, exposed as
IsPlausibleAnnouncement, so a peer cannot inflate the reported gap.
…tion ethereum#28837 (#2542)

Sync() could block forever: the resetDone branch notified the sync waiter
with a non-blocking send and then unconditionally cleared it. When Sync()
had not yet reached its receive (a scheduling gap after it sent its
waiter), the notification was dropped, leaving the waiter never signaled.

Restore the blocking send used upstream geth, which cannot lose the
notification, and do the same for the loop-termination notification so a
pool closed while Sync() is pending also signals the waiter.

Add TestSyncCompletes which exercises repeated Sync() calls and would hang
under -cover if the non-blocking notification regressed.
…bmit (#2537)

A local transaction that reaches the pool through a concurrent submission
(peer gossip, wallet retry, or a parallel RPC endpoint) returns
txpool.ErrAlreadyKnown from TxPool.Add, but is not in the desired local
tracking state: the local tracker only starts on a successful admission.
If that transaction is later evicted, it has no local resubmit or journal
protection and silently disappears.

Treat ErrAlreadyKnown as the desired state on the initial admission path:
AddLocal and EthAPIBackend.SendTx still surface the error to the caller
(matching upstream go-ethereum semantics), but now also register the
transaction with the local tracker so it keeps the resubmit and journal
guarantees. The resubmit loop (TxTracker.loop -> TxTracker.recheck) already
retains already-known transactions in the tracked set, because recheck skips
transactions still present in the pool (pool.Has), so the two paths are now
consistent.
… error ethereum#35048 (#2543)

* fix(core/txpool): subscribe to head events in New to avoid loss ethereum#35048

The pool subscribed to chain head events only after its loop goroutine
started, so a head event emitted by InsertChain right after New could be
missed. The pool then reset against a stale head, keeping pending nonces
at genesis and rejecting fresh transactions as ErrNonceTooHigh (this also
caused the TestResubmit/TestJournal flakes).

Move the subscription into New so events are captured from the start, and
add TestHeadEventDeliveredAfterNew which waits for the pool to observe the
head inserted right after New.

* fix(core/txpool): release head event subscription on Init error

New subscribes to chain head events before the fallible SubPool.Init calls.
When Init fails, New returns without starting the loop, so the loop's
deferred Unsubscribe never runs and the chain feed stays subscribed to an
unconsumed, unbuffered channel; a later head publication can block until
the whole blockchain is stopped.

Unsubscribe on this error path before returning, and add
TestNewUnsubscribesOnInitError which fails if the subscription is leaked.
TestIsYourTurnConsensusV2CrossConfig was flaky in CI: the first YourTurn
call could be rounded up to the switched-to config's mine period (round
10 -> 3s) because the check compares against Unix-second granularity,
returning true and failing the assert.False. The second check also
under-slept since UpdateParams only repoints the engine's CurrentConfig,
so MinePeriod read from blockchain.Config() stayed at the pre-switch
value (2s).

Derive the effective mine period from Config(round 10), wait strictly
inside it for the first check, and comfortably past it for the second.
…ier forks (#2532)

A gas schedule fork raises the pool's minimum gas price above transactions
admitted under the previous tier. No node admits or relays them any more,
yet they stay in the pending list and keep pendingNonces past them, so
wallets reading the pending nonce keep building on top of a transaction the
network has priced out.

After a reset, compare the floor of the block pending on the head the pool
landed on with the one its previous head implied, and on a rise drop every
non-special transaction priced below the new floor from both the pending list
and the queue. The queue is swept as well because promoteExecutables does not
check price and would otherwise promote those transactions straight back into
pending. The price heap is charged once for the whole sweep rather than once
per removal, the way SetGasTip charges its own.

The scan is boundary triggered, so a reset that does not raise the floor
costs two floor lookups and one comparison, and a reorg that lowers the floor
never triggers it. Special transactions are exempt exactly as they are during
admission, being consensus critical and generated with a zero gas price.

A swept transaction does not come back. A reorg below the fork restores the
floor but not the pool, so resubmitting the transaction is accepted again
only until the chain re-crosses the fork and the next reset prices it out;
its sender has to resign at the new price for the transaction to stick.
…2541)

* fix(core/txpool/locals): drop the transaction a tracked local tx replaces

TrackAll only ever added to the tracked set, while the per-nonce SortedMap
silently overwrote the entry a replacement displaced. The replaced transaction
was therefore never returned by Forward again, stayed tracked forever, was
rewritten into the journal on every rotation and could win the nonce on the
next load, resurrecting a transaction the user had already replaced, because
rotation writes the tracked set in map order through a non-stable sort.

Decide which of the two supersedes the other the way the pool decides it.
While the pool holds one of them it is authoritative: it occupies a nonce with
at most one transaction, and AddLocal tracks a local transaction only after Add
has released the subpool lock, so two concurrent submissions can be accepted in
one order and reach TrackAll in the other. When the pool holds neither -- two
submissions it has since discarded, or a journal an older version wrote -- fall
back to the substitution rules legacypool applies in list.Add: a special
transaction always claims its nonce, a regular one must not evict a pending
special one, and otherwise a replacement has to beat the transaction it
replaces on both fee cap and tip. The price bump is deliberately not repeated
here: it is pool policy, and a transaction that beats the old one but misses
the bump behaves exactly as before, so no case gets worse.

Load now converges a journal written by an older version on the replacement
rather than on whichever entry the rotation happened to sort last, so the entry
later in the file no longer decides the nonce. That is a behaviour change for
journals left behind by an older version: the replacement survives now even
when it was written first. Equally priced transactions are not a substitution
either, so the one already tracked keeps the nonce where the previous behaviour
let the later one take it.

Build the test environment from an explicit chain config so tests can pin the
gas schedule instead of sharing the package level genesis, and price the shared
replacement pair to clear the pool's price bump, which is what makes it a
substitution rather than two transactions the pool would reject.

Cover both orders in which a replacement can reach the tracker, the concurrent
interleaving where the original is added first and tracked last, the fallback
for two transactions the pool holds neither of, the special transaction rules
in both directions, the tie between equally priced transactions, and a dearer
tracked transaction losing to the one the pool accepted.

* fix(core/txpool,core/txpool/locals): hold back local resubmits below the gas price floor

A gas schedule fork raises the floor above transactions that were admitted
under the previous tier, and the pool sweeps them out. The local tracker kept
resubmitting them every minute: recheck ignored the result of pool.Add, and the
transactions never went stale because their nonce never advanced, so they
stayed tracked and journalled forever.

Hold back any tracked transaction priced below the current floor, resolved for
the block pending on top of the head exactly as admission validation resolves
it. They stay tracked, so a reorg or a set-head rollback that lowers the floor
picks them up again on the next recheck: the pool does not bring back what it
swept, so the tracker is the only thing that can. Special transactions stay
exempt, as they are during admission.

Resolve the floor through a new TxPool.MinGasPrice, which goes through the
same pendingBlockNumber helper as admission validation and the sweep, so the
tracker and the pool cannot price the same transaction at different heights.

Report the held back transactions through txpool/local/belowfloor, since they
are still counted by txpool/local.

Pin that ErrUnderMinGasPrice is not a temporary reject: the floor only rises as
the chain advances, so retrying cannot help and AddLocal must not track the
transaction, but the error must not be used to drop a tracked one either.

Cover the floor with tests that rewind the head with SetHead across every tier
boundary and cover a head without a block number, the hold-back at exactly the
floor and one wei below it, resumption once the floor drops, and the exemption
special transactions keep.
…2549)

Target 2026-09-08 10:00 CST (02:00 UTC), derived from the devnet stats
snapshot: head 1185928 seen at 2026-09-03 19:26:54 CST with a measured
2.0s block time.

Keep genesis/devnet.json in sync with DevnetChainConfig so `XDC init
--devnet` and `XDC --devnet` schedule the same fork, and drop devnet from
the assertion that default XDC networks leave gas2500x unscheduled.
…n head, close #2533 (#2547)

Side chain blocks are written by hash without state, so a node whose head
sits below them still answers HasBlock for the whole segment; findAncestor
then resolved the ancestor above its own head and the sync resumed there,
stranding the range in between. On XDPoS this stalls the head for good:
epoch-switch header verification needs the gap block's masternode snapshot,
which is only written when the gap block imports with state.

Cap both searches at the local head. calculateRequestSpan now always asks
for two samples spaced one skipped header apart, taking its top sample from
the highest block below the remote head and clamping it down to the local
head, so the window never spends a round trip on a block the head guard
would reject; findAncestor bounds the binary search with the same limit. The
window keeps its count when 'from' is clamped up to zero, which can top it
out above the head, so usableAsAncestor still rejects those candidates and
keeps a span hit from being returned above the head. A hit on the lower
sample no longer ends the search: the true fork can sit on the skipped
block, so the hit seeds the binary search with the gap under the next
sample, clamped by the local head and by the remote height.

Covered by blocks-above-head tests in full and fast sync (stubs stored by
hash, carrying receipts in fast sync but never entering the canonical chain,
so the snap head stays pinned), span candidate rejection and the head-0 and
head-2 window clamps, the gap refinement, a remote sitting at genesis, a
binary-search fork variant, per-mode head-guard boundaries, the
write-without-state semantics the bug rests on, and the per-case request
span and window max.
…2545)

The exact error string from crypto.Ecrecover differs between the cgo
backend (invalid signature length) and the pure-Go nocgo backend
(invalid signature) for a malformed signature. Assert on the shared
substring to avoid flakiness depending on whether CGO is enabled at
build time.
Replace net.Conn.Read with io.ReadFull in TestTCPPipe and TestTCPPipeBidirections. A single TCP Read is not guaranteed to fill the buffer, so on loopback stacks that fragment the 1024-byte writes (e.g. WSL2) the test compared a partial read against the full message and failed at the same byte boundary on every run. TestNetPipe is unaffected because net.Pipe delivers each Write as one Read.
UpdateBlocksHashCache appended unconditionally, so refreshing the
cache for a block that was already cached — which the known-block
path now does when it promotes a stored block — grew the per-height
slice with duplicate hashes. Skip the append when the hash is already
tracked; distinct fork hashes at the same height are still kept.
…hs (#2551)

stats is a function-local insertStats and stats.report is only called
from the main import loop, so every stats write on a path that returns
before reaching the loop is dead and never logged:

- stats.queued += it.processed() on the first-block future path is not
  only unreachable for reporting but off by one: it.processed() returns
  it.index+1, which over-counts by one both when the whole batch is
  drained (it.index == len(chain) at exhaustion) and when the loop
  aborts on a non-exempt error (it.index points at the block that was
  never queued). Both queued counters date back to ff435e0.
- stats.queued++ in the tail future loop (which also skipped the block
  that triggered the queueing) and stats.ignored += it.remaining() on
  both future paths are written then dropped on return.
- stats.ignored += len(it.chain) in the first-block error abort has
  the same write-then-return shape.

Remove all of them. Drop the insertStats.queued field and the "queued"
log context in report() that could never fire once the counters are
gone, matching upstream geth whose insertStats no longer carries a
queued field, and remove the now-unused insertIterator helpers
processed() and remaining(). The live stats.ignored accounting (the
ErrKnownBlock skip loop that falls through to the import loop and the
InsertReceiptChain stats) is untouched.
…chain.go (#2552)

Replace direct == / != comparisons against sentinel errors
(consensus.ErrPrunedAncestor, consensus.ErrFutureBlock,
consensus.ErrUnknownAncestor, ErrKnownBlock, ErrStopPreparingBlock)
with errors.Is, which also matches wrapped errors.
)

Add regression tests asserting that header verification checks the
timestamp first and answers ErrFutureBlock for blocks too far ahead,
without requiring their parent to be resolvable. XDPoS v1/v2 (under
full verification) order the checks this way; these tests pin the
behavior the future-batch tail queueing (queueFutureTail) relies on:
children of a future block surface as ErrFutureBlock, not
ErrUnknownAncestor.

No production code is changed.
@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 343 files, which is 243 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

Usage-priced reviews support at most 300 files.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 5796becb-bbeb-477b-9401-6c6639438ffa

📥 Commits

Reviewing files that changed from the base of the PR and between 2d30685 and cdce8fc.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (343)
  • .github/workflows/ci.yml
  • .github/workflows/pr-notify-slack.yml
  • .gitignore
  • accounts/usbwallet/hub.go
  • accounts/usbwallet/wallet.go
  • build/checksums.txt
  • cicd/Dockerfile
  • cicd/devnet/README.md
  • cicd/devnet/bootnodes.list
  • cicd/devnet/start.sh
  • cicd/mainnet/bootnodes.list
  • cicd/mainnet/start.sh
  • cicd/testnet/bootnodes.list
  • cicd/testnet/start.sh
  • cmd/XDC/chaincmd.go
  • cmd/XDC/config.go
  • cmd/XDC/genesis_startup_test.go
  • cmd/XDC/main.go
  • cmd/bootnode/main.go
  • cmd/devp2p/README.md
  • cmd/devp2p/crawl.go
  • cmd/devp2p/discv4cmd.go
  • cmd/devp2p/discv5cmd.go
  • cmd/devp2p/dns_cloudflare.go
  • cmd/devp2p/dns_route53.go
  • cmd/devp2p/dns_route53_test.go
  • cmd/devp2p/dnscmd.go
  • cmd/devp2p/enrcmd.go
  • cmd/devp2p/internal/ethtest/chain.go
  • cmd/devp2p/internal/ethtest/chain_test.go
  • cmd/devp2p/internal/ethtest/conn.go
  • cmd/devp2p/internal/ethtest/conn_decode_test.go
  • cmd/devp2p/internal/ethtest/conn_test.go
  • cmd/devp2p/internal/ethtest/mkchain.sh
  • cmd/devp2p/internal/ethtest/packets.go
  • cmd/devp2p/internal/ethtest/packets_test.go
  • cmd/devp2p/internal/ethtest/protocol.go
  • cmd/devp2p/internal/ethtest/suite.go
  • cmd/devp2p/internal/ethtest/suite_registry_test.go
  • cmd/devp2p/internal/ethtest/suite_test.go
  • cmd/devp2p/internal/ethtest/testdata/accounts.json
  • cmd/devp2p/internal/ethtest/testdata/chain.rlp
  • cmd/devp2p/internal/ethtest/testdata/forkenv.json
  • cmd/devp2p/internal/ethtest/testdata/genesis.json
  • cmd/devp2p/internal/ethtest/testdata/headblock.json
  • cmd/devp2p/internal/ethtest/testdata/headfcu.json
  • cmd/devp2p/internal/ethtest/testdata/headstate.json
  • cmd/devp2p/internal/ethtest/testdata/newpayload.json
  • cmd/devp2p/internal/ethtest/testdata/txinfo.json
  • cmd/devp2p/internal/v4test/discv4tests.go
  • cmd/devp2p/internal/v4test/framework.go
  • cmd/devp2p/internal/v5test/discv5tests.go
  • cmd/devp2p/internal/v5test/framework.go
  • cmd/devp2p/keycmd.go
  • cmd/devp2p/main.go
  • cmd/devp2p/nodeset.go
  • cmd/devp2p/nodesetcmd.go
  • cmd/devp2p/rlpxcmd.go
  • cmd/devp2p/rlpxcmd_test.go
  • cmd/devp2p/runtest.go
  • cmd/p2psim/main.go
  • cmd/puppeth/genesis_deploy_test.go
  • cmd/puppeth/wizard_genesis.go
  • cmd/puppeth/wizard_genesis_reward_test.go
  • cmd/utils/cmd.go
  • cmd/utils/flags.go
  • cmd/utils/flags_legacy.go
  • cmd/utils/flags_test.go
  • common/constants.go
  • common/countdown/countdown_test.go
  • consensus/XDPoS/XDPoS.go
  • consensus/XDPoS/api.go
  • consensus/XDPoS/api_test.go
  • consensus/XDPoS/engines/engine_v1/engine.go
  • consensus/XDPoS/engines/engine_v1/utils.go
  • consensus/XDPoS/engines/engine_v1/utils_test.go
  • consensus/XDPoS/engines/engine_v1/verify_header_test.go
  • consensus/XDPoS/engines/engine_v2/engine.go
  • consensus/XDPoS/engines/engine_v2/epochSwitch.go
  • consensus/XDPoS/engines/engine_v2/snapshot.go
  • consensus/XDPoS/engines/engine_v2/snapshot_test.go
  • consensus/XDPoS/engines/engine_v2/timeout.go
  • consensus/XDPoS/engines/engine_v2/utils.go
  • consensus/XDPoS/utils/utils.go
  • consensus/misc/eip1559/eip1559.go
  • consensus/misc/eip1559/eip1559_test.go
  • consensus/tests/engine_v1_tests/helper.go
  • consensus/tests/engine_v2_tests/authorised_masternode_test.go
  • consensus/tests/engine_v2_tests/helper.go
  • consensus/tests/engine_v2_tests/sync_info_test.go
  • consensus/tests/engine_v2_tests/verify_header_test.go
  • consensus/tests/engine_v2_tests/vote_test.go
  • contracts/utils.go
  • contracts/utils_test.go
  • core/blockchain.go
  • core/blockchain_insert.go
  • core/blockchain_reader.go
  • core/blockchain_reader_test.go
  • core/blockchain_sethead_test.go
  • core/blockchain_test.go
  • core/bloombits/matcher.go
  • core/chain_config_mismatch_policy.go
  • core/chain_config_mismatch_policy_test.go
  • core/chain_indexer.go
  • core/chain_indexer_test.go
  • core/chainconfig_equal.go
  • core/chainconfig_equal_test.go
  • core/forkid/forkid.go
  • core/forkid/forkid_test.go
  • core/genesis.go
  • core/genesis_alloc_devnet.go
  • core/genesis_load.go
  • core/genesis_load_test.go
  • core/genesis_setup_test.go
  • core/genesis_test.go
  • core/headerchain.go
  • core/rawdb/accessors_chain.go
  • core/rawdb/accessors_xdc.go
  • core/state_processor_test.go
  • core/state_transition.go
  • core/txpool/legacypool/legacypool.go
  • core/txpool/legacypool/legacypool_test.go
  • core/txpool/legacypool/list.go
  • core/txpool/locals/errors.go
  • core/txpool/locals/errors_test.go
  • core/txpool/locals/journal.go
  • core/txpool/locals/tx_tracker.go
  • core/txpool/locals/tx_tracker_test.go
  • core/txpool/txpool.go
  • core/txpool/txpool_head_event_test.go
  • core/txpool/txpool_local_test.go
  • core/txpool/txpool_sync_test.go
  • core/txpool/txpool_test.go
  • core/txpool/validation.go
  • core/txpool/validation_denylist_test.go
  • core/txpool/validation_mingasprice_test.go
  • core/types/block.go
  • core/types/block_test.go
  • core/types/transaction.go
  • core/vm/eips.go
  • core/vm/evm.go
  • core/vm/instructions_test.go
  • core/vm/interpreter.go
  • core/vm/privacy/ringct_test.go
  • docs/upgrade.md
  • docs/xdc/XDPoS/XDPoS.md
  • eth/api_backend.go
  • eth/api_backend_test.go
  • eth/api_debug_test.go
  • eth/backend.go
  • eth/backend_test.go
  • eth/bft/bft_handler.go
  • eth/bft/bft_handler_test.go
  • eth/downloader/downloader.go
  • eth/downloader/downloader_test.go
  • eth/downloader/peer.go
  • eth/downloader/peer_test.go
  • eth/downloader/queue.go
  • eth/downloader/testchain_test.go
  • eth/enr_entry.go
  • eth/ethconfig/config.go
  • eth/ethconfig/gen_config.go
  • eth/fetcher/block_fetcher.go
  • eth/fetcher/block_fetcher_test.go
  • eth/fetcher/metrics.go
  • eth/fetcher/tx_fetcher.go
  • eth/fetcher/tx_fetcher_test.go
  • eth/filters/filter.go
  • eth/filters/filter_test.go
  • eth/gasprice/feehistory.go
  • eth/gasprice/gasprice.go
  • eth/handler.go
  • eth/handler_test.go
  • eth/helper_test.go
  • eth/hooks/engine_v2_hooks.go
  • eth/metrics.go
  • eth/peer.go
  • eth/peer_test.go
  • eth/protocol.go
  • eth/protocol_test.go
  • eth/sync.go
  • eth/sync_test.go
  • ethclient/ethclient.go
  • ethclient/ethclient_test.go
  • ethclient/gen_simulate_call_result.go
  • ethclient/gethclient/gethclient_test.go
  • ethstats/ethstats.go
  • genesis/devnet.json
  • genesis/mainnet.json
  • genesis/testnet.json
  • go.mod
  • internal/ethapi/api.go
  • internal/ethapi/api_test.go
  • internal/ethapi/simulate.go
  • internal/ethapi/transaction_args_test.go
  • internal/flags/categories.go
  • internal/utesting/utesting.go
  • internal/utesting/utesting_test.go
  • internal/web3ext/web3ext.go
  • miner/ordering_test.go
  • miner/worker.go
  • miner/worker_test.go
  • node/api.go
  • node/jwt_handler.go
  • p2p/dial.go
  • p2p/dial_test.go
  • p2p/discover/common.go
  • p2p/discover/database.go
  • p2p/discover/database_test.go
  • p2p/discover/lookup.go
  • p2p/discover/node.go
  • p2p/discover/node_test.go
  • p2p/discover/short_mode_test.go
  • p2p/discover/table.go
  • p2p/discover/table_test.go
  • p2p/discover/table_util_test.go
  • p2p/discover/udp.go
  • p2p/discover/udp_test.go
  • p2p/discover/v4_lookup_test.go
  • p2p/discover/v4_udp.go
  • p2p/discover/v4_udp_test.go
  • p2p/discover/v4wire/v4wire.go
  • p2p/discover/v4wire/v4wire_test.go
  • p2p/discover/v5_udp.go
  • p2p/discover/v5_udp_test.go
  • p2p/discover/v5wire/crypto.go
  • p2p/discover/v5wire/crypto_test.go
  • p2p/discover/v5wire/encoding.go
  • p2p/discover/v5wire/encoding_test.go
  • p2p/discover/v5wire/msg.go
  • p2p/discover/v5wire/session.go
  • p2p/discover/v5wire/testdata/v5.1-ping-handshake-enr.txt
  • p2p/discover/v5wire/testdata/v5.1-ping-handshake.txt
  • p2p/discover/v5wire/testdata/v5.1-ping-message.txt
  • p2p/discover/v5wire/testdata/v5.1-whoareyou.txt
  • p2p/discv5/database.go
  • p2p/discv5/database_test.go
  • p2p/discv5/metrics.go
  • p2p/discv5/net.go
  • p2p/discv5/net_test.go
  • p2p/discv5/node.go
  • p2p/discv5/node_test.go
  • p2p/discv5/nodeevent_string.go
  • p2p/discv5/ntp.go
  • p2p/discv5/sim_run_test.go
  • p2p/discv5/sim_test.go
  • p2p/discv5/table.go
  • p2p/discv5/table_test.go
  • p2p/discv5/ticket.go
  • p2p/discv5/topic.go
  • p2p/discv5/topic_test.go
  • p2p/discv5/udp.go
  • p2p/discv5/udp_test.go
  • p2p/dnsdisc/client.go
  • p2p/dnsdisc/client_test.go
  • p2p/dnsdisc/doc.go
  • p2p/dnsdisc/error.go
  • p2p/dnsdisc/sync.go
  • p2p/dnsdisc/sync_test.go
  • p2p/dnsdisc/tree.go
  • p2p/dnsdisc/tree_test.go
  • p2p/enode/idscheme.go
  • p2p/enode/idscheme_test.go
  • p2p/enode/iter.go
  • p2p/enode/iter_test.go
  • p2p/enode/localnode.go
  • p2p/enode/localnode_test.go
  • p2p/enode/node.go
  • p2p/enode/node_test.go
  • p2p/enode/nodedb.go
  • p2p/enode/nodedb_test.go
  • p2p/enode/urlv4.go
  • p2p/enode/urlv4_test.go
  • p2p/enr/enr.go
  • p2p/enr/enr_test.go
  • p2p/enr/entries.go
  • p2p/enr/idscheme.go
  • p2p/message.go
  • p2p/message_test.go
  • p2p/metrics.go
  • p2p/nat/nat.go
  • p2p/nat/nat_test.go
  • p2p/nat/natupnp.go
  • p2p/netutil/addrutil.go
  • p2p/netutil/error.go
  • p2p/netutil/error_test.go
  • p2p/netutil/iptrack.go
  • p2p/netutil/iptrack_test.go
  • p2p/peer.go
  • p2p/peer_error.go
  • p2p/peer_test.go
  • p2p/protocol.go
  • p2p/protocols/protocol.go
  • p2p/protocols/protocol_test.go
  • p2p/rlpx/rlpx.go
  • p2p/rlpx/rlpx_test.go
  • p2p/server.go
  • p2p/server_test.go
  • p2p/simulations/README.md
  • p2p/simulations/adapters/docker.go
  • p2p/simulations/adapters/exec.go
  • p2p/simulations/adapters/inproc.go
  • p2p/simulations/adapters/inproc_test.go
  • p2p/simulations/adapters/types.go
  • p2p/simulations/adapters/ws.go
  • p2p/simulations/adapters/ws_test.go
  • p2p/simulations/connect.go
  • p2p/simulations/connect_test.go
  • p2p/simulations/events.go
  • p2p/simulations/examples/ping-pong.go
  • p2p/simulations/http.go
  • p2p/simulations/http_test.go
  • p2p/simulations/mocker.go
  • p2p/simulations/mocker_test.go
  • p2p/simulations/network.go
  • p2p/simulations/network_test.go
  • p2p/simulations/pipes/pipes.go
  • p2p/simulations/simulation.go
  • p2p/simulations/test.go
  • p2p/transport.go
  • p2p/transport_test.go
  • p2p/util.go
  • p2p/util_test.go
  • params/bootnodes.go
  • params/config.go
  • params/config_backfill.go
  • params/config_backfill_fields.json
  • params/config_backfill_generated.go
  • params/config_backfill_test.go
  • params/config_compat.go
  • params/config_compat_test.go
  • params/config_forks.go
  • params/config_networks.go
  • params/config_networks_test.go
  • params/config_test.go
  • params/config_xdpos.go
  • params/config_xdpos_test.go
  • params/forks/forks.go
  • params/forks/forks_test.go
  • params/gas.go
  • params/gas_test.go
  • tests/state_test_util.go
  • version/version.go

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

gzliudan and others added 10 commits September 14, 2026 11:04
…rg, ethereum#19748 ethereum#20506 (#2555)

Port upstream go-ethereum fixes ethereum#19748 and ethereum#20506 (fixes the flaky
'Canonical section count mismatch' in TestChainIndexerWithChildren,
see upstream issue ethereum#20497):

- newHead: on reorg, revert from section (head+1)/sectionSize since the
  common ancestor head itself is still valid
- updateLoop: verify the last stored section head against the canonical
  chain before processing and after a failed processing, rolling back
  stale sections so the indexer can never get stuck with an invalid
  stored section (the root cause of the flaky 'Canonical section count
  mismatch: have 79, want 78' failure in TestChainIndexerWithChildren)
- Sections(): report an up-to-date section count via verifyLastHead
- updateLoop: guard SectionHead underflow with section == 0
- chain_indexer_test: sync reorg expectation helper with the new
  revert semantics
in order to fix fastsync snapshot err
* update reward for devnet and testnet

* fix test

* update round number again
* fix genesis bug not importing FoundationWalletAddr properly

* bump MaxProtectorNodes count

* - activate forks for local chain (to match mainnet release)
- add reward calc for protector and observer nodes
- properly apply chainconfig to puppeth

* refactor: improve readablility on reward calculation and add tests

* update localchain initial config

* fix: properly include epoch input for reward calculation

* enable gas2500x on localnet (match next mainnet release)
…reen (#2561)

Two test failures that predate the XDPoS schedule work and are unrelated to it.

core/vm/privacy/ringct_test.go asserts on the cgo secp256k1 BitCurve that
ringct.go is built on, so without cgo - the default on Windows - every test in
the file panics. Tag the file cgo so it is compiled only where that curve
exists.

ethclient/gethclient's TestGethClient leaves the XDCx database's log file open
for the lifetime of the node, which keeps t.TempDir's cleanup from removing the
directory on Windows. The test itself is platform independent, so skip it there
rather than letting the cleanup failure fail the run.
…#2562)

XDPoS_v2.chainConfig was only assigned in New and never read. The
unexported field had no readers inside or outside the package, so it is
pure dead state. Remove the field and its sole assignment; the New
parameter is kept because it still backs the nil guard and derives the
XDPoS config.
…2563)

reorg spawned the removed-logs send while the reborn logs and the canonical
logs go out synchronously. A subscriber could therefore observe the logs of
the new chain before the removals of the blocks they revert.

geth hit the same problem twice: ethereum#14865 introduced `go` for both feeds,
43631aa merged them into one goroutine that sends removals first, and
ethereum#19396 dropped the goroutine altogether. This port was left on the first
form, and worse: only the removals were asynchronous, so the two feeds did
not even agree on the delivery mode.

Send the removals synchronously too. event.Feed.Send blocks until a slow
subscriber takes the event, which is the trade-off geth accepted in order to
get a deterministic order.

TestLogReorgs subscribed on an unbuffered channel and only drained it after
the import, which now deadlocks; it starts the receiver before the import
instead, as geth's testLogReorgs does.

Tests: TestReorgDeliversRemovedLogsSynchronously stalls the subscriber on
purpose and fails if the reorg returns before the removals were delivered.
It fails with the old `go` in place and passes without it.
Use the txpool pending nonce when creating block signer transactions so retries do not collide with an existing pending nonce and trigger replacement transaction underpriced.

Co-authored-by: Daniel Liu <[email protected]>
…2223)

* feat(consensus): add RPC endpoint to query signing tx count by epoch

* Apply suggestion from @Copilot

Co-authored-by: Copilot <[email protected]>

* Apply suggestion from @Copilot

Co-authored-by: Copilot <[email protected]>

* Apply suggestion from @Copilot

Co-authored-by: Copilot <[email protected]>

* Apply suggestion from @Copilot

Co-authored-by: Copilot <[email protected]>

* fix build issue

---------

Co-authored-by: liam.lai <[email protected]>
Co-authored-by: Copilot <[email protected]>
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.

6 participants