Important
Optional but highly recommended upgrade.
v2.5.1 is a hardening & maintenance release. No protocol fork is activated, and operators can upgrade in-place.
v2.5.1 carries robustness improvements across the P2P layer, block processing, the transaction pool and the public/admin APIs, together with a handful of API and SDK fixes. Most changes are internal; the user-visible ones are listed below.
What's Changed
Hardening & Robustness
These changes tighten resource bounds and failure handling throughout the node. They do not change consensus rules: every bound is sized above what a valid block can hold under the current 40M block gas limit.
- Networking: new blocks received from a peer are handed off through a per-peer mailbox instead of being processed on the peer's read loop. Transaction broadcast now uses a single bounded queue and writer per peer. Future-block cache entries are capped per peer and bound to their header. Inbound connection attempts are rate-limited per source (one per 30s for a non-LAN IPv4 address or IPv6 /64 prefix), matching go-ethereum (#1699). Internal consistency fixes in the discv5 topic table.
- Block decoding: stricter bounds while decoding block headers and bodies (header field widths, total clause count per block). The existing per-tx and per-block limits are now collected in
thor/gas_limits.goso they are sized against one definition of the block gas limit. The packer respects the same bounds and treats an exhausted clause budget as a full block. - Adaptive gas limit: the bandwidth-derived block gas-limit target, which packers use by default, is now floored at 30M (ceiling unchanged at 40M).
- Transaction pool: transactions submitted through the API are now admitted under the same caps as transactions received from peers. The previous behaviour (local tier: no max lifetime, exempt from trimming, re-announced on every wash) is available behind the new
--api-local-tx-privilegesflag, off by default. Fixed a metric double-count when the same transaction is added concurrently (#1678). - Node: the node's highest-seen block number now advances when a block is persisted rather than after BFT commit.
- API
- Responses are written in bounded chunks with a 10s stall timeout, enforced at the connection level so it covers every reply including 404/405 and CORS preflight; a client that stops reading is disconnected (#1699). WebSocket subscription writes (frames, ping, close) carry the same deadline.
- Requests that hit the API timeout now return 503 (
request timed out); requests whose client went away return 499 (client closed request) instead of 500. POST /accounts/*batch calls are capped at 2500 clauses (400 above that); anullrequest body is rejected with 400.debugtracing: a new--api-trace-data-max-sizeflag (default 2.5 MiB) bounds the call input/output data retained per trace; the clause replay and custom JS tracer result collection stop as soon as the request deadline fires or the client disconnects.- Admin API: state-changing routes (
POST/PUT/PATCH) now requireContent-Type: application/jsonand answer 415 otherwise. Update any scripts that post form-encoded bodies.
Protocol
- Legacy transaction reward alignment (#1679). For legacy (type
0x00) transactions after GALACTICA, the validator reward is now derived from the gas price the signer is charged. This is a refinement of the VIP-251 legacy fee mapping and is shipped without a fork gate.- Mainnet / testnet: no effect and no resync; results are identical for every historical transaction on both networks.
- Solo / custom networks: chains that use the default genesis
base-gas-priceand contain legacy transactions with proved work may replay with different receipts. Regenerate such chains from genesis after upgrading.
API Fixes
topicsfor LOG0 events is now[]instead ofnullin expanded blocks and subscription messages (#1682).orderin/logs/eventand/logs/transferfilters is case-insensitive; values other thanasc/descare rejected with 400 (#1684).- Event filters without an address and spanning fewer than 100,000 blocks are evaluated by a sequence-range scan instead of the topic index, which is substantially faster for narrow topic-only queries (#1693).
Observability
- New metrics:
comm_block_mailbox_overwrite_counter,api_non_json_request_body_count{name,media_type}. bandwidth updatedtrace logs are throttled to significant changes (#1691).
thorclient/bind
- Transactions default to dynamic-fee when the best block carries a base fee, with
maxFeePerGas = 2·baseFee + tip; gas is estimated by simulation;DeployContractsimulates first and does not send on revert or VM error (#1689).
CI, Build & Dependencies
- Bumped the go-ethereum fork for an RLP decoding improvement(#1697).
discobumped to 1.0.7; the two new flags are documented indocs/command_line_arguments.md(#1698).- Daily check of the release signing subkey expiry (#1677).
- Test isolation fixes and Go 1.26 idioms (#1680, #1687, #1688, #1692); CI tidy-ups (#1686, #1696).
Contributors
Full Changelog: v2.5.0...v2.5.1