Continuing with a series of PRs to make the Trie interface more generic, this PR moves
the RLP encoding of storage slots inside the StateTrie and light.Trie implementations,
as other types of tries don't use RLP.
Co-authored-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
In this PR, all TryXXX(e.g. TryGet) APIs of trie are renamed to XXX(e.g. Get) with an error returned.
The original XXX(e.g. Get) APIs are renamed to MustXXX(e.g. MustGet) and does not return any error -- they print a log output. A future PR will change the behaviour to panic on errorrs.
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
This change renames StateTrie methods to remove the Try* prefix.
We added the Trie methods with prefix 'Try' a long time ago, working
around the problem that most existing methods of Trie did not return the
database error. This weird naming convention has persisted until now.
Co-authored-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
- Refactor NewTransactionsByPriceAndNonce to properly filter and separate special transactions (IsSpecialTransaction)
- Remove account from txs map if it has no normal transactions left
- Update comments for clarity
This commit updates the Txs field in NewTxsEvent to use []*types.Transaction instead of types.Transactions. This ensures type consistency for event broadcasting and handling, improving reliability of transaction propagation across the network. The change also removes unnecessary goroutine usage for txFeed.Send, making event delivery synchronous and safer for downstream consumers.
This commit adds robust input validation to the SetGasPrice method and
implements comprehensive table-driven tests to ensure correct behavior.
Changes in core/txpool/txpool.go:
- Add nil gas price validation with graceful error handling
- Add validation to reject negative gas prices
- Add validation to reject gas prices exceeding 1000 GWei maximum
- Return detailed error messages for each validation failure
- Log warnings when invalid gas prices are rejected
Changes in eth/api_miner.go:
- Update MinerAPI.SetGasPrice to check error return from txPool.SetGasPrice
- Return false when validation fails (when SetGasPrice returns error)
- Return true when validation succeeds (when SetGasPrice returns nil)
New tests in core/txpool/txpool_test.go:
- Implement TestSetGasPrice using table-driven test pattern
- Test 4 invalid cases: nil, negative, exceed max+1, exceed 10000 GWei
- Test 7 valid cases: 0, 1 wei, 1 GWei, 100 GWei, 500 GWei, max-1, max
- Each test case includes expected error value for precise validation
- All 11 test cases verify both error returns and gas price state
- Tests use isolated pool instances to ensure independence
This changes the Trie interface to add the plain account address as a
parameter to all storage-related methods.
After the introduction of the TryAccount* functions, TryGet, TryUpdate and
TryDelete are now only meant to read an account's storage. In their current
form, they assume that an account storage is stored in a separate trie, and
that the hashing of the slot is independent of its account's address.
The proposed structure for a stateless storage breaks these two
assumptions: the hashing of a slot key requires the address and all slots
and accounts are stored in a single trie.
This PR therefore adds an address parameter to the interface. It is ignored
in the MPT version, so this change has no functional impact, however it
will reduce the diff size when merging verkle trees.
Co-authored-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
This commit simplifies the transaction pool's gas price validation logic while
maintaining network security through the existing minimum gas price requirement.
Changes:
- Set default PriceLimit to 0 (was 1), allowing transactions with zero tip
- Remove PriceLimit >= 1 validation in config sanitization
- Simplify Pending() method by using EffectiveGasTipIntCmp consistently
- Unify validateTxBasics() logic to use GasTipCapIntCmp for all transactions
Key Points:
1. Economic Protection: All transactions still require gasPrice >= 12.5 Gwei
(enforced by GetMinGasPrice check in validateTx), providing sufficient
protection against DoS attacks even with zero tip.
2. Miner Incentives: Since XDPoSChain includes baseFee in miner rewards
(unlike standard EIP-1559), miners still earn the full gasPrice even when
tip is 0. This maintains miner revenue while allowing greater flexibility.
3. Special Transactions: BlockSigner and Randomize contract transactions
remain exempt from gas price checks, as they are critical for consensus.
4. Code Quality: Reduces complexity by 11 lines and unifies validation logic,
making the codebase more maintainable.
Security Analysis:
- No nil pointer risks: EffectiveGasTipIntCmp has built-in nil handling
- No DoS vulnerability: 12.5 Gwei minimum ensures economic cost per transaction
- EIP-1559 compatible: Existing minGasPrice check covers all validation needs
- Backward compatible: Only relaxes restrictions, doesn't break existing behavior
This change benefits system transactions and special use cases while maintaining
all existing security guarantees through the network's minimum gas price floor.
- Fix "invalid transaction v, r, s values" error when calling debug_traceCall
on BlockSigners contract (0x89)
- Fix "nonce too low" error by respecting Message.SkipNonceChecks flag
- ApplySignTransaction now accepts *Message and uses msg.From directly
- Add fallback to signature recovery for real transactions
- Skip nonce validation when SkipNonceChecks=true (for traceCall)
- Add comprehensive unit tests for both scenarios
Root cause: BlockSigners uses special fast-path that calls
ApplySignTransaction directly, which previously attempted signature
recovery on unsigned transactions from debug_traceCall.
Fixes#1870
Since commit 845d3d49e (July 2023), MinGasPrice validation (250000000 wei /
0.25 Gwei) has been enforced for all non-special transactions in validateTx().
Later, commit 141cb75c (Dec 2025) refactored this validation logic into the
standalone ValidateTransactionWithState() function for code reusability.
However, the transaction pool test suite was never updated to comply with the
MinGasPrice requirement and continued using extremely low gas prices (1-6 wei),
causing test failures when run independently.
The root cause of this issue was that testQueueTimeLimiting() set the global
variable 'common.MinGasPrice = big.NewInt(0)' without restoring it. This global
variable modification created severe testing problems:
1. Intermittent, non-deterministic failures: The same test would randomly pass
or fail without any code changes, depending on whether testQueueTimeLimiting
had executed and set MinGasPrice=0 before other tests checked it
2. Race conditions in concurrent execution: Since tests use t.Parallel(), multiple
tests could simultaneously access the shared global MinGasPrice variable,
creating unpredictable timing-dependent behavior
3. Test order dependency: When running 'make test', if testQueueTimeLimiting
executed early and set MinGasPrice=0, other tests with low gas prices would
pass. Running the same tests individually or in a different order would fail
with 'under min gas price' errors
4. Global state pollution: The MinGasPrice modification affected ALL concurrently
running tests in the suite, violating test isolation principles and making
debugging extremely difficult
5. Masked real validation issues: The global override hid the fact that test
transactions violated MinGasPrice requirements that would be enforced in
production, reducing test effectiveness
6. No cleanup mechanism: The changed value was never restored, permanently
affecting subsequent tests and creating cascading failures
This intermittent behavior made CI/CD pipelines unreliable - tests could pass
locally but fail in CI, or pass on retry without changes, wasting developer time
investigating 'phantom' failures.
This commit systematically updates all affected test cases to use gas prices
that satisfy the MinGasPrice requirement:
- Replace transaction() helper calls with pricedTransaction() using gas prices
>= 250000000 wei (MinGasPrice)
- Update dynamicFeeTx() calls to use gasFeeCap and gasTipCap >= 250000000 wei
- Scale account balances proportionally to cover the higher transaction costs
- Maintain test logic and relative price relationships between transactions
Tests fixed (36 total):
- TestStateChangeDuringReset
- TestInvalidTransactions
- TestChainFork
- TestDoubleNonce
- TestMissingNonce
- TestNonceRecovery
- TestPostponing
- TestGapFilling
- TestQueueAccountLimiting
- TestQueueGlobalLimiting
- TestQueueGlobalLimitingNoLocals
- TestQueueTimeLimiting
- TestQueueTimeLimitingNoLocals
- TestPendingLimiting
- TestPendingGlobalLimiting
- TestAllowedTxSize
- TestCapClearsFromAll
- TestPendingMinimumAllowance
- TestRepricing
- TestRepricingDynamicFee
- TestRepricingKeepsLocals
- TestPoolUnderpricing
- TestPoolStableUnderpricing
- TestUnderpricingDynamicFee
- TestDualHeapEviction
- TestDeduplication
- TestReplacement
- TestReplacementDynamicFee
- TestJournaling
- TestJournalingNoLocals
- TestStatusCheck
- TestDropping
- TestQueue
- TestQueue2
- TestNegativeValue
- TestSlotCount
All tests now pass consistently when run with: go test ./core/txpool -count=1