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
This commit removes two redundant SetGasPrice() calls in the startNode function that were causing multiple issues:
1. Overriding txpool's configured price limit with the miner's gas price setting, mixing two independent configurations:
- cfg.Eth.GasPrice (from --miner-gasprice --gasprice flag)
- cfg.TxPool.PriceLimit (from --txpool-pricelimit flag)
2. Reverting runtime gasPrice changes made via RPC. When users call miner_setGasPrice RPC method to adjust the gasPrice dynamically, the changes would be unexpectedly reverted at the next checkpoint when startNode re-applies cfg.Eth.GasPrice.
The txpool already initializes its gasPrice from config.PriceLimit during construction (core/txpool/txpool.go:333):
```go
func NewTxPool(config Config, chainconfig *params.ChainConfig, chain blockChain) *TxPool {
pool := &TxPool{
gasPrice: new(big.Int).SetUint64(config.PriceLimit),
}
```
When mining is started via RPC (miner_start), the MinerAPI.Start() method handles gasPrice propagation correctly.
This change ensures:
- The txpool respects its own configuration
- Runtime gasPrice adjustments via RPC persist across checkpoints
- No unexpected overriding of user-configured values
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
Add defer cleanup for global variables and remove t.Parallel() where
global state is modified to prevent race conditions and test pollution.
Changes:
1. tests/vm_test.go:
- Add defer to restore common.TIPXDCXCancellationFee
- Remove t.Parallel() since modifying global variable makes concurrent
execution unsafe, even with defer cleanup
- Prevents potential race conditions with other tests in the package
2. contracts/tests/Inherited_test.go:
- Add defer to restore common.TIPXDCXCancellationFee
- No t.Parallel() present, so safe with defer alone
3. contracts/trc21issuer/trc21issuer_test.go:
- Add defer to restore common.TRC21IssuerSMC (was missing)
- Fix existing bug: restore correct variable common.TRC21GasPriceBefore
instead of common.TIPTRC21Fee
- Remove unused variables: token, delay
Rationale for removing t.Parallel():
While defer ensures cleanup after test completion, during test execution
the modified global variable is visible to all concurrent tests. Even
though tests/vm_test.go is currently the only test modifying
TIPXDCXCancellationFee, removing t.Parallel() is the safer approach to
ensure complete test isolation and prevent timing-dependent behavior.
This follows the same principles as the txpool MinGasPrice fix: global
variable modifications should not occur during concurrent test execution.
Implement https://github.com/ethereum/go-ethereum/issues/32078
Parse and lookup the delegation account if EIP7702 is enabled.
---------
Signed-off-by: jsvisa <delweng@gmail.com>
Co-authored-by: Delweng <delweng@gmail.com>
* Detect non-EVM special transactions and construct a synthetic top level callFrame in OnTxStart.
* GetResult returns the virtual frame for non-EVM txs to preserve debug API compatibility.
* Add bounds checks in OnTxEnd and OnLog to avoid panics when callstack is empty.
* Add unit tests to verify the fix
* feat: GetTokenSupply API, total minted and burned
* feat: token supply API finish burned token. rename minted record functions
* fix(api): handle edge case about minus 1 for epoch in token supply
* fix: check both total minted and burned before breaking loop
* style: modify minor style
* style: modify by comment and rebase code
* chore: modify test based on statedb_utils