Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion accounts/abi/bind/v2/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
14 changes: 10 additions & 4 deletions eth/api_miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
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
}

api.e.lock.Lock()
api.e.gasPrice = (*big.Int)(&gasPrice)
api.e.gasPrice = new(big.Int).Set(tip)
api.e.lock.Unlock()

err := api.e.txPool.SetGasTip((*big.Int)(&gasPrice))
return err == nil
return true
}

// SetEtherbase sets the etherbase of the miner
Expand Down
4 changes: 4 additions & 0 deletions miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
27 changes: 25 additions & 2 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -117,8 +118,6 @@ type worker struct {
chainConfig *params.ChainConfig
engine consensus.Engine

mu sync.Mutex

// Feeds
pendingLogsFeed event.Feed

Expand All @@ -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
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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) {
Expand Down
42 changes: 42 additions & 0 deletions miner/worker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}