mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 13:21:37 +00:00
Synchronize miner gas tip updates across subsystems when RPC updates gas price. - update eth miner API to apply gas tip changes to both txpool and miner - add miner/worker SetGasTip path and initialize worker tip from config - adjust bind util test to use params.GWei over base fee Ref: #28933
This commit is contained in:
parent
de142957b3
commit
338d1b4632
5 changed files with 83 additions and 8 deletions
|
|
@ -69,7 +69,7 @@ func TestWaitDeployed(t *testing.T) {
|
|||
|
||||
// Create the transaction
|
||||
head, _ := backend.Client().HeaderByNumber(context.Background(), nil) // Should be child's, good enough
|
||||
gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
|
||||
gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(params.GWei))
|
||||
|
||||
tx := types.NewContractCreation(0, big.NewInt(0), test.gas, gasPrice, common.FromHex(test.code))
|
||||
tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||
|
|
|
|||
|
|
@ -94,12 +94,18 @@ func (api *MinerAPI) SetExtra(extra string) (bool, error) {
|
|||
|
||||
// SetGasPrice sets the minimum accepted gas price for the miner.
|
||||
func (api *MinerAPI) SetGasPrice(gasPrice hexutil.Big) bool {
|
||||
api.e.lock.Lock()
|
||||
api.e.gasPrice = (*big.Int)(&gasPrice)
|
||||
api.e.lock.Unlock()
|
||||
tip := (*big.Int)(&gasPrice)
|
||||
if err := api.e.txPool.SetGasTip(tip); err != nil {
|
||||
return false
|
||||
}
|
||||
if err := api.e.Miner().SetGasTip(tip); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
err := api.e.txPool.SetGasTip((*big.Int)(&gasPrice))
|
||||
return err == nil
|
||||
api.e.lock.Lock()
|
||||
api.e.gasPrice = new(big.Int).Set(tip)
|
||||
api.e.lock.Unlock()
|
||||
return true
|
||||
}
|
||||
|
||||
// SetEtherbase sets the etherbase of the miner
|
||||
|
|
|
|||
|
|
@ -173,6 +173,10 @@ func (m *Miner) SetExtra(extra []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (miner *Miner) SetGasTip(tip *big.Int) error {
|
||||
return miner.worker.setGasTip(tip)
|
||||
}
|
||||
|
||||
// Pending returns the currently pending block and associated state.
|
||||
func (m *Miner) Pending() (*types.Block, *state.StateDB) {
|
||||
return m.worker.pending()
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ var (
|
|||
blockCommitTimer = metrics.NewRegisteredTimer("miner/time/commit", nil)
|
||||
blockFinalizeTimer = metrics.NewRegisteredTimer("miner/time/finalize", nil)
|
||||
blockTotalTimer = metrics.NewRegisteredTimer("miner/time/total", nil)
|
||||
maxGasTip = big.NewInt(1000 * params.GWei)
|
||||
)
|
||||
|
||||
// Agent can register themself with the worker
|
||||
|
|
@ -117,8 +118,6 @@ type worker struct {
|
|||
chainConfig *params.ChainConfig
|
||||
engine consensus.Engine
|
||||
|
||||
mu sync.Mutex
|
||||
|
||||
// Feeds
|
||||
pendingLogsFeed event.Feed
|
||||
|
||||
|
|
@ -142,8 +141,10 @@ type worker struct {
|
|||
proc core.Validator
|
||||
chainDb ethdb.Database
|
||||
|
||||
mu sync.Mutex
|
||||
coinbase common.Address
|
||||
extra []byte
|
||||
tip *big.Int // Minimum tip needed for non-local transaction to include them
|
||||
|
||||
snapshotMu sync.RWMutex // The lock used to protect the block snapshot and state snapshot
|
||||
snapshotBlock *types.Block
|
||||
|
|
@ -174,6 +175,7 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus
|
|||
mux: mux,
|
||||
coinbase: config.Etherbase,
|
||||
extra: config.ExtraData,
|
||||
tip: config.GasPrice,
|
||||
txsCh: make(chan core.NewTxsEvent, txChanSize),
|
||||
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
|
||||
chainSideCh: make(chan core.ChainSideEvent, chainSideChanSize),
|
||||
|
|
@ -214,6 +216,27 @@ func (w *worker) setExtra(extra []byte) {
|
|||
w.extra = extra
|
||||
}
|
||||
|
||||
// setGasTip sets the minimum miner tip needed to include a non-local transaction.
|
||||
func (w *worker) setGasTip(tip *big.Int) error {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
|
||||
if tip == nil {
|
||||
return errors.New("reject nil gas tip")
|
||||
}
|
||||
if tip.Sign() < 0 {
|
||||
return fmt.Errorf("reject negative gas tip: %v", tip)
|
||||
}
|
||||
if tip.Cmp(maxGasTip) > 0 {
|
||||
return fmt.Errorf("reject too high gas tip: %v, maximum: %v", tip, maxGasTip)
|
||||
}
|
||||
|
||||
// Copy the value to avoid external mutation through shared pointers.
|
||||
w.tip = new(big.Int).Set(tip)
|
||||
log.Info("Worker tip updated", "tip", w.tip)
|
||||
return nil
|
||||
}
|
||||
|
||||
// pending returns the pending state and corresponding block. The returned
|
||||
// values can be nil in case the pending block is not initialized.
|
||||
func (w *worker) pending() (*types.Block, *state.StateDB) {
|
||||
|
|
|
|||
|
|
@ -130,3 +130,45 @@ func TestWorkerCheckPreCommitXDPoSMismatch(t *testing.T) {
|
|||
t.Fatalf("expected genesis parent, got number %v", parent.Number())
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorkerSetGasTipValidation(t *testing.T) {
|
||||
w := &worker{tip: big.NewInt(1)}
|
||||
old := new(big.Int).Set(w.tip)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
tip *big.Int
|
||||
}{
|
||||
{name: "nil", tip: nil},
|
||||
{name: "negative", tip: big.NewInt(-1)},
|
||||
{name: "too high", tip: new(big.Int).Add(maxGasTip, big.NewInt(1))},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if err := w.setGasTip(tc.tip); err == nil {
|
||||
t.Fatalf("expected error for %s tip", tc.name)
|
||||
}
|
||||
if w.tip.Cmp(old) != 0 {
|
||||
t.Fatalf("tip changed on invalid input: have %v want %v", w.tip, old)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorkerSetGasTipCopiesValue(t *testing.T) {
|
||||
w := &worker{}
|
||||
input := big.NewInt(2 * params.GWei)
|
||||
|
||||
if err := w.setGasTip(input); err != nil {
|
||||
t.Fatalf("setGasTip failed: %v", err)
|
||||
}
|
||||
if w.tip == input {
|
||||
t.Fatal("worker tip shares pointer with input")
|
||||
}
|
||||
|
||||
input.Add(input, big.NewInt(1))
|
||||
if w.tip.Cmp(big.NewInt(2*params.GWei)) != 0 {
|
||||
t.Fatalf("worker tip mutated via input pointer: have %v", w.tip)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue