From aa88078dd199958d963f6a3fc061c9a224d2034e Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Wed, 12 Jun 2024 15:18:02 +0800 Subject: [PATCH 01/10] core/types: convert status type from uint to uint64 (#16784) --- consensus/XDPoS/XDPoS.go | 2 +- core/types/gen_receipt_json.go | 8 ++++---- core/types/receipt.go | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/consensus/XDPoS/XDPoS.go b/consensus/XDPoS/XDPoS.go index fc7b3418946d..951fe99a7d84 100644 --- a/consensus/XDPoS/XDPoS.go +++ b/consensus/XDPoS/XDPoS.go @@ -508,7 +508,7 @@ func (x *XDPoS) CacheNoneTIPSigningTxs(header *types.Header, txs []*types.Transa signTxs := []*types.Transaction{} for _, tx := range txs { if tx.IsSigningTransaction() { - var b uint + var b uint64 for _, r := range receipts { if r.TxHash == tx.Hash() { if len(r.PostState) > 0 { diff --git a/core/types/gen_receipt_json.go b/core/types/gen_receipt_json.go index b72ef0270d3d..89379a823a16 100644 --- a/core/types/gen_receipt_json.go +++ b/core/types/gen_receipt_json.go @@ -18,7 +18,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) { type Receipt struct { Type hexutil.Uint64 `json:"type,omitempty"` PostState hexutil.Bytes `json:"root"` - Status hexutil.Uint `json:"status"` + Status hexutil.Uint64 `json:"status"` CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"` @@ -32,7 +32,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) { var enc Receipt enc.Type = hexutil.Uint64(r.Type) enc.PostState = r.PostState - enc.Status = hexutil.Uint(r.Status) + enc.Status = hexutil.Uint64(r.Status) enc.CumulativeGasUsed = hexutil.Uint64(r.CumulativeGasUsed) enc.Bloom = r.Bloom enc.Logs = r.Logs @@ -50,7 +50,7 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { type Receipt struct { Type *hexutil.Uint64 `json:"type,omitempty"` PostState *hexutil.Bytes `json:"root"` - Status *hexutil.Uint `json:"status"` + Status *hexutil.Uint64 `json:"status"` CumulativeGasUsed *hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom *Bloom `json:"logsBloom" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"` @@ -72,7 +72,7 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { r.PostState = *dec.PostState } if dec.Status != nil { - r.Status = uint(*dec.Status) + r.Status = uint64(*dec.Status) } if dec.CumulativeGasUsed == nil { return errors.New("missing required field 'cumulativeGasUsed' for Receipt") diff --git a/core/types/receipt.go b/core/types/receipt.go index d1b3cc46bf37..9600ad1d794e 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -41,10 +41,10 @@ var errEmptyTypedReceipt = errors.New("empty typed receipt bytes") const ( // ReceiptStatusFailed is the status code of a transaction if execution failed. - ReceiptStatusFailed = uint(0) + ReceiptStatusFailed = uint64(0) // ReceiptStatusSuccessful is the status code of a transaction if execution succeeded. - ReceiptStatusSuccessful = uint(1) + ReceiptStatusSuccessful = uint64(1) ) // Receipt represents the results of a transaction. @@ -52,7 +52,7 @@ type Receipt struct { // Consensus fields: These fields are defined by the Yellow Paper Type uint8 `json:"type,omitempty"` PostState []byte `json:"root"` - Status uint `json:"status"` + Status uint64 `json:"status"` CumulativeGasUsed uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"` @@ -73,7 +73,7 @@ type Receipt struct { type receiptMarshaling struct { Type hexutil.Uint64 PostState hexutil.Bytes - Status hexutil.Uint + Status hexutil.Uint64 CumulativeGasUsed hexutil.Uint64 GasUsed hexutil.Uint64 BlockNumber *hexutil.Big From 0063c14ed39349c38cc96a473ed1f3ce21755734 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 13 Jun 2024 11:26:12 +0800 Subject: [PATCH 02/10] cmd, eth, internal, les: add gasprice cap (#21212) --- cmd/XDC/main.go | 1 + cmd/XDC/usage.go | 1 + cmd/utils/flags.go | 8 ++++++++ eth/api_backend.go | 4 ++++ eth/config.go | 5 +++++ eth/gen_config.go | 6 ++++++ internal/ethapi/api.go | 8 ++++++++ internal/ethapi/backend.go | 1 + les/api_backend.go | 4 ++++ 9 files changed, 38 insertions(+) diff --git a/cmd/XDC/main.go b/cmd/XDC/main.go index 419978ba6e09..cf21779c6d7e 100644 --- a/cmd/XDC/main.go +++ b/cmd/XDC/main.go @@ -148,6 +148,7 @@ var ( utils.WSAllowedOriginsFlag, utils.IPCDisabledFlag, utils.IPCPathFlag, + utils.RPCGlobalTxFeeCap, } whisperFlags = []cli.Flag{ diff --git a/cmd/XDC/usage.go b/cmd/XDC/usage.go index e6b2fc961f8f..0bea6301db29 100644 --- a/cmd/XDC/usage.go +++ b/cmd/XDC/usage.go @@ -156,6 +156,7 @@ var AppHelpFlagGroups = []flagGroup{ utils.IPCPathFlag, utils.RPCCORSDomainFlag, utils.RPCVirtualHostsFlag, + utils.RPCGlobalTxFeeCap, utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index a9fd25c4922a..f981cce29b39 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -363,6 +363,11 @@ var ( Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)", Value: eth.DefaultConfig.RPCGasCap, } + RPCGlobalTxFeeCap = cli.Float64Flag{ + Name: "rpc.txfeecap", + Usage: "Sets a cap on transaction fee (in ether) that can be sent via the RPC APIs (0 = no cap)", + Value: eth.DefaultConfig.RPCTxFeeCap, + } // Logging and debug settings EthStatsURLFlag = cli.StringFlag{ Name: "ethstats", @@ -1171,6 +1176,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { if ctx.GlobalIsSet(DocRootFlag.Name) { cfg.DocRoot = ctx.GlobalString(DocRootFlag.Name) } + if ctx.GlobalIsSet(RPCGlobalTxFeeCap.Name) { + cfg.RPCTxFeeCap = ctx.GlobalFloat64(RPCGlobalTxFeeCap.Name) + } if ctx.GlobalIsSet(ExtraDataFlag.Name) { cfg.ExtraData = []byte(ctx.GlobalString(ExtraDataFlag.Name)) } diff --git a/eth/api_backend.go b/eth/api_backend.go index c087ec2d3804..161ee5ddfb4f 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -356,6 +356,10 @@ func (b *EthApiBackend) AccountManager() *accounts.Manager { return b.eth.AccountManager() } +func (b *EthApiBackend) RPCTxFeeCap() float64 { + return b.eth.config.RPCTxFeeCap +} + func (b *EthApiBackend) BloomStatus() (uint64, uint64) { sections, _, _ := b.eth.bloomIndexer.Sections() return params.BloomBitsBlocks, sections diff --git a/eth/config.go b/eth/config.go index 73a95aa6756f..79fb0220a5b2 100644 --- a/eth/config.go +++ b/eth/config.go @@ -56,6 +56,7 @@ var DefaultConfig = Config{ Blocks: 20, Percentile: 60, }, + RPCTxFeeCap: 1, // 1 ether } func init() { @@ -118,6 +119,10 @@ type Config struct { // RPCGasCap is the global gas cap for eth-call variants. RPCGasCap uint64 + + // RPCTxFeeCap is the global transaction fee(price * gaslimit) cap for + // send-transction variants. The unit is ether. + RPCTxFeeCap float64 } type configMarshaling struct { diff --git a/eth/gen_config.go b/eth/gen_config.go index 1959ee559d53..abfed29e3547 100644 --- a/eth/gen_config.go +++ b/eth/gen_config.go @@ -37,6 +37,7 @@ func (c Config) MarshalTOML() (interface{}, error) { EnablePreimageRecording bool DocRoot string `toml:"-"` RPCGasCap uint64 + RPCTxFeeCap float64 } var enc Config enc.Genesis = c.Genesis @@ -60,6 +61,7 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.EnablePreimageRecording = c.EnablePreimageRecording enc.DocRoot = c.DocRoot enc.RPCGasCap = c.RPCGasCap + enc.RPCTxFeeCap = c.RPCTxFeeCap return &enc, nil } @@ -87,6 +89,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { EnablePreimageRecording *bool DocRoot *string `toml:"-"` RPCGasCap *uint64 + RPCTxFeeCap *float64 } var dec Config if err := unmarshal(&dec); err != nil { @@ -155,5 +158,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.RPCGasCap != nil { c.RPCGasCap = *dec.RPCGasCap } + if dec.RPCTxFeeCap != nil { + c.RPCTxFeeCap = *dec.RPCTxFeeCap + } return nil } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 650135e06752..d94ec30f34b5 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -2372,6 +2372,14 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c if tx.To() != nil && tx.IsSpecialTransaction() { return common.Hash{}, errors.New("Dont allow transaction sent to BlockSigners & RandomizeSMC smart contract via API") } + + // If the transaction fee cap is already specified, ensure the + // fee of the given transaction is _reasonable_. + feeEth := new(big.Float).Quo(new(big.Float).SetInt(new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas()))), new(big.Float).SetInt(big.NewInt(params.Ether))) + feeFloat, _ := feeEth.Float64() + if b.RPCTxFeeCap() != 0 && feeFloat > b.RPCTxFeeCap() { + return common.Hash{}, fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, b.RPCTxFeeCap()) + } if err := b.SendTx(ctx, tx); err != nil { return common.Hash{}, err } diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 00a9aea8acf9..d862977d2c5f 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -52,6 +52,7 @@ type Backend interface { EventMux() *event.TypeMux AccountManager() *accounts.Manager RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection + RPCTxFeeCap() float64 // global tx fee cap for all transaction related APIs XDCxService() *XDCx.XDCX LendingService() *XDCxlending.Lending diff --git a/les/api_backend.go b/les/api_backend.go index abdd952a6ebf..3e93efe9601f 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -273,6 +273,10 @@ func (b *LesApiBackend) RPCGasCap() uint64 { return b.eth.config.RPCGasCap } +func (b *LesApiBackend) RPCTxFeeCap() float64 { + return b.eth.config.RPCTxFeeCap +} + func (b *LesApiBackend) BloomStatus() (uint64, uint64) { if b.eth.bloomIndexer == nil { return 0, 0 From 56591d37e1c82549eb61fa3ca648296ba8f92e0d Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 20 May 2024 14:00:18 +0800 Subject: [PATCH 03/10] eth/gasprice: lighter gas price oracle for light client (#20409) --- cmd/utils/flags.go | 10 +++- eth/config.go | 21 +++++-- eth/gasprice/gasprice.go | 121 ++++++++++++++++++++++----------------- params/denomination.go | 1 + 4 files changed, 94 insertions(+), 59 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index f981cce29b39..373ff5cc0a2a 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -978,7 +978,13 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) { } } -func setGPO(ctx *cli.Context, cfg *gasprice.Config) { +func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) { + // If we are running the light client, apply another group + // settings for gas oracle. + if light { + cfg.Blocks = eth.DefaultLightGPOConfig.Blocks + cfg.Percentile = eth.DefaultLightGPOConfig.Percentile + } if ctx.GlobalIsSet(GpoBlocksFlag.Name) { cfg.Blocks = ctx.GlobalInt(GpoBlocksFlag.Name) } @@ -1135,7 +1141,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) setEtherbase(ctx, ks, cfg) - setGPO(ctx, &cfg.GPO) + setGPO(ctx, &cfg.GPO, ctx.GlobalString(SyncModeFlag.Name) == "light") setTxPool(ctx, &cfg.TxPool) setEthash(ctx, cfg) diff --git a/eth/config.go b/eth/config.go index 79fb0220a5b2..78ff01855a7f 100644 --- a/eth/config.go +++ b/eth/config.go @@ -33,6 +33,18 @@ import ( "github.com/XinFinOrg/XDPoSChain/params" ) +// DefaultFullGPOConfig contains default gasprice oracle settings for full node. +var DefaultFullGPOConfig = gasprice.Config{ + Blocks: 20, + Percentile: 60, +} + +// DefaultLightGPOConfig contains default gasprice oracle settings for light client. +var DefaultLightGPOConfig = gasprice.Config{ + Blocks: 2, + Percentile: 60, +} + // DefaultConfig contains default settings for use on the Ethereum main net. var DefaultConfig = Config{ SyncMode: downloader.FullSync, @@ -50,12 +62,9 @@ var DefaultConfig = Config{ TrieTimeout: 5 * time.Minute, GasPrice: big.NewInt(0.25 * params.Shannon), - TxPool: core.DefaultTxPoolConfig, - RPCGasCap: 25000000, - GPO: gasprice.Config{ - Blocks: 20, - Percentile: 60, - }, + TxPool: core.DefaultTxPoolConfig, + RPCGasCap: 25000000, + GPO: DefaultFullGPOConfig, RPCTxFeeCap: 1, // 1 ether } diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index 54492790371b..af010efb0d5f 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -24,12 +24,13 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/types" - "github.com/XinFinOrg/XDPoSChain/internal/ethapi" "github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/rpc" ) -var maxPrice = big.NewInt(500 * params.Shannon) +const sampleNumber = 3 // Number of transactions sampled in a block + +var maxPrice = big.NewInt(500 * params.GWei) type Config struct { Blocks int @@ -37,21 +38,29 @@ type Config struct { Default *big.Int `toml:",omitempty"` } +// OracleBackend includes all necessary background APIs for oracle. +type OracleBackend interface { + HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) + BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) + ChainConfig() *params.ChainConfig +} + // Oracle recommends gas prices based on the content of recent // blocks. Suitable for both light and full clients. type Oracle struct { - backend ethapi.Backend + backend OracleBackend lastHead common.Hash lastPrice *big.Int cacheLock sync.RWMutex fetchLock sync.Mutex - checkBlocks, maxEmpty, maxBlocks int - percentile int + checkBlocks int + percentile int } -// NewOracle returns a new oracle. -func NewOracle(backend ethapi.Backend, params Config) *Oracle { +// NewOracle returns a new gasprice oracle which can recommend suitable +// gasprice for newly created transaction. +func NewOracle(backend OracleBackend, params Config) *Oracle { blocks := params.Blocks if blocks < 1 { blocks = 1 @@ -67,74 +76,74 @@ func NewOracle(backend ethapi.Backend, params Config) *Oracle { backend: backend, lastPrice: params.Default, checkBlocks: blocks, - maxEmpty: blocks / 2, - maxBlocks: blocks * 5, percentile: percent, } } // SuggestPrice returns the recommended gas price. func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) { - gpo.cacheLock.RLock() - lastHead := gpo.lastHead - lastPrice := gpo.lastPrice - gpo.cacheLock.RUnlock() - head, _ := gpo.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber) headHash := head.Hash() + + // If the latest gasprice is still available, return it. + gpo.cacheLock.RLock() + lastHead, lastPrice := gpo.lastHead, gpo.lastPrice + gpo.cacheLock.RUnlock() if headHash == lastHead { return lastPrice, nil } - gpo.fetchLock.Lock() defer gpo.fetchLock.Unlock() - // try checking the cache again, maybe the last fetch fetched what we need + // Try checking the cache again, maybe the last fetch fetched what we need gpo.cacheLock.RLock() - lastHead = gpo.lastHead - lastPrice = gpo.lastPrice + lastHead, lastPrice = gpo.lastHead, gpo.lastPrice gpo.cacheLock.RUnlock() if headHash == lastHead { return lastPrice, nil } - - blockNum := head.Number.Uint64() - ch := make(chan getBlockPricesResult, gpo.checkBlocks) - sent := 0 - exp := 0 - var blockPrices []*big.Int - for sent < gpo.checkBlocks && blockNum > 0 { - go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(blockNum))), blockNum, ch) + var ( + sent, exp int + number = head.Number.Uint64() + result = make(chan getBlockPricesResult, gpo.checkBlocks) + quit = make(chan struct{}) + txPrices []*big.Int + ) + for sent < gpo.checkBlocks && number > 0 { + go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, result, quit) sent++ exp++ - blockNum-- + number-- } - maxEmpty := gpo.maxEmpty for exp > 0 { - res := <-ch + res := <-result if res.err != nil { + close(quit) return lastPrice, res.err } exp-- - if res.price != nil { - blockPrices = append(blockPrices, res.price) - continue - } - if maxEmpty > 0 { - maxEmpty-- - continue + // Nothing returned. There are two special cases here: + // - The block is empty + // - All the transactions included are sent by the miner itself. + // In these cases, use the latest calculated price for samping. + if len(res.prices) == 0 { + res.prices = []*big.Int{lastPrice} } - if blockNum > 0 && sent < gpo.maxBlocks { - go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(blockNum))), blockNum, ch) + // Besides, in order to collect enough data for sampling, if nothing + // meaningful returned, try to query more blocks. But the maximum + // is 2*checkBlocks. + if len(res.prices) == 1 && len(txPrices)+1+exp < gpo.checkBlocks*2 && number > 0 { + go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, result, quit) sent++ exp++ - blockNum-- + number-- } + txPrices = append(txPrices, res.prices...) } price := lastPrice - if len(blockPrices) > 0 { - sort.Sort(bigIntArray(blockPrices)) - price = blockPrices[(len(blockPrices)-1)*gpo.percentile/100] + if len(txPrices) > 0 { + sort.Sort(bigIntArray(txPrices)) + price = txPrices[(len(txPrices)-1)*gpo.percentile/100] } if price.Cmp(maxPrice) > 0 { price = new(big.Int).Set(maxPrice) @@ -154,8 +163,8 @@ func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) { } type getBlockPricesResult struct { - price *big.Int - err error + prices []*big.Int + err error } type transactionsByGasPrice []*types.Transaction @@ -165,27 +174,37 @@ func (t transactionsByGasPrice) Swap(i, j int) { t[i], t[j] = t[j], t[i] } func (t transactionsByGasPrice) Less(i, j int) bool { return t[i].GasPriceCmp(t[j]) < 0 } // getBlockPrices calculates the lowest transaction gas price in a given block -// and sends it to the result channel. If the block is empty, price is nil. -func (gpo *Oracle) getBlockPrices(ctx context.Context, signer types.Signer, blockNum uint64, ch chan getBlockPricesResult) { +// and sends it to the result channel. If the block is empty or all transactions +// are sent by the miner itself(it doesn't make any sense to include this kind of +// transaction prices for sampling), nil gasprice is returned. +func (gpo *Oracle) getBlockPrices(ctx context.Context, signer types.Signer, blockNum uint64, limit int, result chan getBlockPricesResult, quit chan struct{}) { block, err := gpo.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNum)) if block == nil { - ch <- getBlockPricesResult{nil, err} + select { + case result <- getBlockPricesResult{nil, err}: + case <-quit: + } return } - blockTxs := block.Transactions() txs := make([]*types.Transaction, len(blockTxs)) copy(txs, blockTxs) sort.Sort(transactionsByGasPrice(txs)) + var prices []*big.Int for _, tx := range txs { sender, err := types.Sender(signer, tx) if err == nil && sender != block.Coinbase() { - ch <- getBlockPricesResult{tx.GasPrice(), nil} - return + prices = append(prices, tx.GasPrice()) + if len(prices) >= limit { + break + } } } - ch <- getBlockPricesResult{nil, nil} + select { + case result <- getBlockPricesResult{prices, nil}: + case <-quit: + } } type bigIntArray []*big.Int diff --git a/params/denomination.go b/params/denomination.go index 9e1b52506f47..471a045007e1 100644 --- a/params/denomination.go +++ b/params/denomination.go @@ -25,6 +25,7 @@ const ( Wei = 1 Ada = 1e3 Babbage = 1e6 + GWei = 1e9 Shannon = 1e9 Szabo = 1e12 Finney = 1e15 From 341ca00b16dce10b12195ee7b4fa89d4827dcd75 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 13 Jun 2024 12:28:33 +0800 Subject: [PATCH 04/10] internal/ethapi: cap txfee for SignTransaction and Resend (#21231) --- internal/ethapi/api.go | 57 ++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index d94ec30f34b5..fad8f0cb513c 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -412,6 +412,10 @@ func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args SendTxArgs if args.Nonce == nil { return nil, errors.New("nonce not specified") } + // Before actually sign the transaction, ensure the transaction fee is reasonable. + if err := checkTxFee(args.GasPrice.ToInt(), uint64(*args.Gas), s.b.RPCTxFeeCap()); err != nil { + return nil, err + } signed, err := s.signTransaction(ctx, args, passwd) if err != nil { log.Warn("Failed transaction sign attempt", "from", args.From, "to", args.To, "value", args.Value.ToInt(), "err", err) @@ -2375,10 +2379,8 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c // If the transaction fee cap is already specified, ensure the // fee of the given transaction is _reasonable_. - feeEth := new(big.Float).Quo(new(big.Float).SetInt(new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas()))), new(big.Float).SetInt(big.NewInt(params.Ether))) - feeFloat, _ := feeEth.Float64() - if b.RPCTxFeeCap() != 0 && feeFloat > b.RPCTxFeeCap() { - return common.Hash{}, fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, b.RPCTxFeeCap()) + if err := checkTxFee(tx.GasPrice(), tx.Gas(), b.RPCTxFeeCap()); err != nil { + return common.Hash{}, err } if err := b.SendTx(ctx, tx); err != nil { return common.Hash{}, err @@ -3367,6 +3369,10 @@ func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args Sen if err := args.setDefaults(ctx, s.b); err != nil { return nil, err } + // Before actually sign the transaction, ensure the transaction fee is reasonable. + if err := checkTxFee(args.GasPrice.ToInt(), uint64(*args.Gas), s.b.RPCTxFeeCap()); err != nil { + return nil, err + } tx, err := s.sign(args.From, args.toTransaction()) if err != nil { return nil, err @@ -3412,6 +3418,19 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxAr } matchTx := sendArgs.toTransaction() + // Before replacing the old transaction, ensure the _new_ transaction fee is reasonable. + var price = matchTx.GasPrice() + if gasPrice != nil { + price = gasPrice.ToInt() + } + var gas = matchTx.Gas() + if gasLimit != nil { + gas = uint64(*gasLimit) + } + if err := checkTxFee(price, gas, s.b.RPCTxFeeCap()); err != nil { + return common.Hash{}, err + } + // Iterate the pending list for replacement pending, err := s.b.GetPoolTransactions() if err != nil { @@ -3561,6 +3580,21 @@ func (s *PublicNetAPI) Version() string { return fmt.Sprintf("%d", s.networkVersion) } +// checkTxFee is an internal function used to check whether the fee of +// the given transaction is _reasonable_(under the cap). +func checkTxFee(gasPrice *big.Int, gas uint64, cap float64) error { + // Short circuit if there is no cap for transaction fee at all. + if cap == 0 { + return nil + } + feeEth := new(big.Float).Quo(new(big.Float).SetInt(new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(gas))), new(big.Float).SetInt(big.NewInt(params.Ether))) + feeFloat, _ := feeEth.Float64() + if feeFloat > cap { + return fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, cap) + } + return nil +} + func GetSignersFromBlocks(b Backend, blockNumber uint64, blockHash common.Hash, masternodes []common.Address) ([]common.Address, error) { var addrs []common.Address mapMN := map[common.Address]bool{} @@ -3661,18 +3695,3 @@ func (s *PublicBlockChainAPI) GetStakerROIMasternode(masternode common.Address) return 100.0 / float64(totalCap.Div(totalCap, voterRewardAYear).Uint64()) } - -// checkTxFee is an internal function used to check whether the fee of -// the given transaction is _reasonable_(under the cap). -func checkTxFee(gasPrice *big.Int, gas uint64, cap float64) error { - // Short circuit if there is no cap for transaction fee at all. - if cap == 0 { - return nil - } - feeEth := new(big.Float).Quo(new(big.Float).SetInt(new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(gas))), new(big.Float).SetInt(big.NewInt(params.Ether))) - feeFloat, _ := feeEth.Float64() - if feeFloat > cap { - return fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, cap) - } - return nil -} From 3e9bd359df1451e6f47e1d23f242a8d399ac56ec Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 28 May 2024 12:43:52 +0800 Subject: [PATCH 05/10] ethclient: serialize negative block number as "pending" (#21177) --- core/types/gen_log_json.go | 20 ++++++++++---------- core/types/log.go | 4 ++-- ethclient/ethclient.go | 5 +++++ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/core/types/gen_log_json.go b/core/types/gen_log_json.go index cb0071938dce..c9bdff5b3801 100644 --- a/core/types/gen_log_json.go +++ b/core/types/gen_log_json.go @@ -12,6 +12,7 @@ import ( var _ = (*logMarshaling)(nil) +// MarshalJSON marshals as JSON. func (l Log) MarshalJSON() ([]byte, error) { type Log struct { Address common.Address `json:"address" gencodec:"required"` @@ -19,9 +20,9 @@ func (l Log) MarshalJSON() ([]byte, error) { Data hexutil.Bytes `json:"data" gencodec:"required"` BlockNumber hexutil.Uint64 `json:"blockNumber"` TxHash common.Hash `json:"transactionHash" gencodec:"required"` - TxIndex hexutil.Uint `json:"transactionIndex" gencodec:"required"` + TxIndex hexutil.Uint `json:"transactionIndex"` BlockHash common.Hash `json:"blockHash"` - Index hexutil.Uint `json:"logIndex" gencodec:"required"` + Index hexutil.Uint `json:"logIndex"` Removed bool `json:"removed"` } var enc Log @@ -37,6 +38,7 @@ func (l Log) MarshalJSON() ([]byte, error) { return json.Marshal(&enc) } +// UnmarshalJSON unmarshals from JSON. func (l *Log) UnmarshalJSON(input []byte) error { type Log struct { Address *common.Address `json:"address" gencodec:"required"` @@ -44,9 +46,9 @@ func (l *Log) UnmarshalJSON(input []byte) error { Data *hexutil.Bytes `json:"data" gencodec:"required"` BlockNumber *hexutil.Uint64 `json:"blockNumber"` TxHash *common.Hash `json:"transactionHash" gencodec:"required"` - TxIndex *hexutil.Uint `json:"transactionIndex" gencodec:"required"` + TxIndex *hexutil.Uint `json:"transactionIndex"` BlockHash *common.Hash `json:"blockHash"` - Index *hexutil.Uint `json:"logIndex" gencodec:"required"` + Index *hexutil.Uint `json:"logIndex"` Removed *bool `json:"removed"` } var dec Log @@ -72,17 +74,15 @@ func (l *Log) UnmarshalJSON(input []byte) error { return errors.New("missing required field 'transactionHash' for Log") } l.TxHash = *dec.TxHash - if dec.TxIndex == nil { - return errors.New("missing required field 'transactionIndex' for Log") + if dec.TxIndex != nil { + l.TxIndex = uint(*dec.TxIndex) } - l.TxIndex = uint(*dec.TxIndex) if dec.BlockHash != nil { l.BlockHash = *dec.BlockHash } - if dec.Index == nil { - return errors.New("missing required field 'logIndex' for Log") + if dec.Index != nil { + l.Index = uint(*dec.Index) } - l.Index = uint(*dec.Index) if dec.Removed != nil { l.Removed = *dec.Removed } diff --git a/core/types/log.go b/core/types/log.go index d459d2892f61..cf1dbc4ecb58 100644 --- a/core/types/log.go +++ b/core/types/log.go @@ -45,11 +45,11 @@ type Log struct { // hash of the transaction TxHash common.Hash `json:"transactionHash" gencodec:"required"` // index of the transaction in the block - TxIndex uint `json:"transactionIndex" gencodec:"required"` + TxIndex uint `json:"transactionIndex"` // hash of the block in which the transaction was included BlockHash common.Hash `json:"blockHash"` // index of the log in the receipt - Index uint `json:"logIndex" gencodec:"required"` + Index uint `json:"logIndex"` // The Removed field is true if this log was reverted due to a chain reorganisation. // You must pay attention to this field if you receive logs through a filter query. diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 592b7db35696..7e3a43932752 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -273,10 +273,15 @@ func (ec *Client) GetTransactionReceiptResult(ctx context.Context, txHash common } return r, result, err } + func toBlockNumArg(number *big.Int) string { if number == nil { return "latest" } + pending := big.NewInt(-1) + if number.Cmp(pending) == 0 { + return "pending" + } return hexutil.EncodeBig(number) } From 2125a1afaa5c7511dd2b5c001d8e99c5557dd3ab Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 20 May 2024 14:11:29 +0800 Subject: [PATCH 06/10] eth/gasprice: offer maxprice flag for overwritting price cap (#21531) --- cmd/XDC/main.go | 1 + cmd/XDC/usage.go | 1 + cmd/utils/flags.go | 8 ++++++++ eth/config.go | 2 ++ eth/gasprice/gasprice.go | 18 +++++++++++++++--- 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/cmd/XDC/main.go b/cmd/XDC/main.go index cf21779c6d7e..4a5c7507f980 100644 --- a/cmd/XDC/main.go +++ b/cmd/XDC/main.go @@ -127,6 +127,7 @@ var ( //utils.NoCompactionFlag, //utils.GpoBlocksFlag, //utils.GpoPercentileFlag, + utils.GpoMaxGasPriceFlag, //utils.ExtraDataFlag, configFileFlag, utils.AnnounceTxsFlag, diff --git a/cmd/XDC/usage.go b/cmd/XDC/usage.go index 0bea6301db29..5269418fe590 100644 --- a/cmd/XDC/usage.go +++ b/cmd/XDC/usage.go @@ -195,6 +195,7 @@ var AppHelpFlagGroups = []flagGroup{ // Flags: []cli.Flag{ // utils.GpoBlocksFlag, // utils.GpoPercentileFlag, + // utils.GpoMaxGasPriceFlag, // }, //}, //{ diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 373ff5cc0a2a..a0c5722d8917 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -555,6 +555,11 @@ var ( Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices", Value: eth.DefaultConfig.GPO.Percentile, } + GpoMaxGasPriceFlag = cli.Int64Flag{ + Name: "gpo.maxprice", + Usage: "Maximum gas price will be recommended by gpo", + Value: eth.DefaultConfig.GPO.MaxPrice.Int64(), + } WhisperEnabledFlag = cli.BoolFlag{ Name: "shh", Usage: "Enable Whisper", @@ -991,6 +996,9 @@ func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) { if ctx.GlobalIsSet(GpoPercentileFlag.Name) { cfg.Percentile = ctx.GlobalInt(GpoPercentileFlag.Name) } + if ctx.GlobalIsSet(GpoMaxGasPriceFlag.Name) { + cfg.MaxPrice = big.NewInt(ctx.GlobalInt64(GpoMaxGasPriceFlag.Name)) + } } func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { diff --git a/eth/config.go b/eth/config.go index 78ff01855a7f..102166891348 100644 --- a/eth/config.go +++ b/eth/config.go @@ -37,12 +37,14 @@ import ( var DefaultFullGPOConfig = gasprice.Config{ Blocks: 20, Percentile: 60, + MaxPrice: gasprice.DefaultMaxPrice, } // DefaultLightGPOConfig contains default gasprice oracle settings for light client. var DefaultLightGPOConfig = gasprice.Config{ Blocks: 2, Percentile: 60, + MaxPrice: gasprice.DefaultMaxPrice, } // DefaultConfig contains default settings for use on the Ethereum main net. diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index af010efb0d5f..8ffd90723149 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -24,18 +24,20 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/types" + "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/rpc" ) const sampleNumber = 3 // Number of transactions sampled in a block -var maxPrice = big.NewInt(500 * params.GWei) +var DefaultMaxPrice = big.NewInt(500 * params.GWei) type Config struct { Blocks int Percentile int Default *big.Int `toml:",omitempty"` + MaxPrice *big.Int `toml:",omitempty"` } // OracleBackend includes all necessary background APIs for oracle. @@ -51,6 +53,7 @@ type Oracle struct { backend OracleBackend lastHead common.Hash lastPrice *big.Int + maxPrice *big.Int cacheLock sync.RWMutex fetchLock sync.Mutex @@ -64,17 +67,26 @@ func NewOracle(backend OracleBackend, params Config) *Oracle { blocks := params.Blocks if blocks < 1 { blocks = 1 + log.Warn("Sanitizing invalid gasprice oracle sample blocks", "provided", params.Blocks, "updated", blocks) } percent := params.Percentile if percent < 0 { percent = 0 + log.Warn("Sanitizing invalid gasprice oracle sample percentile", "provided", params.Percentile, "updated", percent) } if percent > 100 { percent = 100 + log.Warn("Sanitizing invalid gasprice oracle sample percentile", "provided", params.Percentile, "updated", percent) + } + maxPrice := params.MaxPrice + if maxPrice == nil || maxPrice.Int64() <= 0 { + maxPrice = DefaultMaxPrice + log.Warn("Sanitizing invalid gasprice oracle price cap", "provided", params.MaxPrice, "updated", maxPrice) } return &Oracle{ backend: backend, lastPrice: params.Default, + maxPrice: maxPrice, checkBlocks: blocks, percentile: percent, } @@ -145,8 +157,8 @@ func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) { sort.Sort(bigIntArray(txPrices)) price = txPrices[(len(txPrices)-1)*gpo.percentile/100] } - if price.Cmp(maxPrice) > 0 { - price = new(big.Int).Set(maxPrice) + if price.Cmp(gpo.maxPrice) > 0 { + price = new(big.Int).Set(gpo.maxPrice) } // Check gas price min. From e72f6dedb377a76a83e9da8fb7c4d2e21c01b9c2 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 30 May 2024 17:07:16 +0800 Subject: [PATCH 07/10] accounts/abi/bind: allow to specify signer on transactOpts (#21356) --- accounts/abi/bind/auth.go | 80 ++++++++++++++++++++++++- accounts/abi/bind/backends/simulated.go | 1 + accounts/abi/bind/base.go | 4 +- accounts/abi/bind/bind_test.go | 20 +++---- mobile/bind.go | 4 +- 5 files changed, 93 insertions(+), 16 deletions(-) diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index 415c9015e0f6..1db4a496af49 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -20,16 +20,29 @@ import ( "crypto/ecdsa" "errors" "io" + "io/ioutil" + "math/big" + "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/accounts/keystore" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/log" ) +// ErrNoChainID is returned whenever the user failed to specify a chain id. +var ErrNoChainID = errors.New("no chain id specified") + +// ErrNotAuthorized is returned when an account is not properly unlocked. +var ErrNotAuthorized = errors.New("not authorized to sign this account") + // NewTransactor is a utility method to easily create a transaction signer from // an encrypted json key stream and the associated passphrase. +// +// Deprecated: Use NewTransactorWithChainID instead. func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { + log.Warn("WARNING: NewTransactor has been deprecated in favour of NewTransactorWithChainID") json, err := io.ReadAll(keyin) if err != nil { return nil, err @@ -43,13 +56,17 @@ func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { // NewKeyedTransactor is a utility method to easily create a transaction signer // from a single private key. +// +// Deprecated: Use NewKeyedTransactorWithChainID instead. func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts { + log.Warn("WARNING: NewKeyedTransactor has been deprecated in favour of NewKeyedTransactorWithChainID") keyAddr := crypto.PubkeyToAddress(key.PublicKey) + signer := types.HomesteadSigner{} return &TransactOpts{ From: keyAddr, - Signer: func(signer types.Signer, address common.Address, tx *types.Transaction) (*types.Transaction, error) { + Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { if address != keyAddr { - return nil, errors.New("not authorized to sign this account") + return nil, ErrNotAuthorized } signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key) if err != nil { @@ -59,3 +76,62 @@ func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts { }, } } + +// NewTransactorWithChainID is a utility method to easily create a transaction signer from +// an encrypted json key stream and the associated passphrase. +func NewTransactorWithChainID(keyin io.Reader, passphrase string, chainID *big.Int) (*TransactOpts, error) { + json, err := ioutil.ReadAll(keyin) + if err != nil { + return nil, err + } + key, err := keystore.DecryptKey(json, passphrase) + if err != nil { + return nil, err + } + return NewKeyedTransactorWithChainID(key.PrivateKey, chainID) +} + +// NewKeyStoreTransactorWithChainID is a utility method to easily create a transaction signer from +// an decrypted key from a keystore. +func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accounts.Account, chainID *big.Int) (*TransactOpts, error) { + if chainID == nil { + return nil, ErrNoChainID + } + signer := types.NewEIP155Signer(chainID) + return &TransactOpts{ + From: account.Address, + Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { + if address != account.Address { + return nil, ErrNotAuthorized + } + signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes()) + if err != nil { + return nil, err + } + return tx.WithSignature(signer, signature) + }, + }, nil +} + +// NewKeyedTransactorWithChainID is a utility method to easily create a transaction signer +// from a single private key. +func NewKeyedTransactorWithChainID(key *ecdsa.PrivateKey, chainID *big.Int) (*TransactOpts, error) { + keyAddr := crypto.PubkeyToAddress(key.PublicKey) + if chainID == nil { + return nil, ErrNoChainID + } + signer := types.NewEIP155Signer(chainID) + return &TransactOpts{ + From: keyAddr, + Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { + if address != keyAddr { + return nil, ErrNotAuthorized + } + signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key) + if err != nil { + return nil, err + } + return tx.WithSignature(signer, signature) + }, + }, nil +} diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 0df4bd7450c1..b8c6814040a4 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -135,6 +135,7 @@ func NewXDCSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64, chainConfi // NewSimulatedBackend creates a new binding backend using a simulated blockchain // for testing purposes. +// A simulated backend always uses chainID 1337. func NewSimulatedBackend(alloc core.GenesisAlloc) *SimulatedBackend { database := rawdb.NewMemoryDatabase() genesis := core.Genesis{Config: params.AllEthashProtocolChanges, Alloc: alloc, GasLimit: 42000000} diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index d0e2d1c3930b..4d5390d15bc2 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -36,7 +36,7 @@ var ( // SignerFn is a signer function callback when a contract requires a method to // sign the transaction before submission. -type SignerFn func(types.Signer, common.Address, *types.Transaction) (*types.Transaction, error) +type SignerFn func(common.Address, *types.Transaction) (*types.Transaction, error) // CallOpts is the collection of options to fine tune a contract call request. type CallOpts struct { @@ -238,7 +238,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i if opts.Signer == nil { return nil, errors.New("no signer to authorize the transaction with") } - signedTx, err := opts.Signer(types.HomesteadSigner{}, opts.From, rawTx) + signedTx, err := opts.Signer(opts.From, rawTx) if err != nil { return nil, err } diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 8bdd5b85c0db..ce6e36bffd34 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -228,7 +228,7 @@ var bindTests = []struct { ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() - auth := bind.NewKeyedTransactor(key) + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig) // Deploy an interaction tester contract and call a transaction on it @@ -269,7 +269,7 @@ var bindTests = []struct { ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() - auth := bind.NewKeyedTransactor(key) + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig) // Deploy a tuple tester contract and execute a structured call on it @@ -301,7 +301,7 @@ var bindTests = []struct { ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() - auth := bind.NewKeyedTransactor(key) + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig) // Deploy a tuple tester contract and execute a structured call on it @@ -343,7 +343,7 @@ var bindTests = []struct { ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() - auth := bind.NewKeyedTransactor(key) + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig) // Deploy a slice tester contract and execute a n array call on it @@ -377,7 +377,7 @@ var bindTests = []struct { ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() - auth := bind.NewKeyedTransactor(key) + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig) // Deploy a default method invoker contract and execute its default method @@ -446,7 +446,7 @@ var bindTests = []struct { ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() - auth := bind.NewKeyedTransactor(key) + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig) // Deploy a funky gas pattern contract @@ -481,7 +481,7 @@ var bindTests = []struct { ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() - auth := bind.NewKeyedTransactor(key) + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig) // Deploy a sender tester contract and execute a structured call on it @@ -541,7 +541,7 @@ var bindTests = []struct { ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() - auth := bind.NewKeyedTransactor(key) + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig) // Deploy a underscorer tester contract and execute a structured call on it @@ -611,7 +611,7 @@ var bindTests = []struct { ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() - auth := bind.NewKeyedTransactor(key) + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig) // Deploy an eventer contract @@ -760,7 +760,7 @@ var bindTests = []struct { ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() - auth := bind.NewKeyedTransactor(key) + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig) //deploy the test contract diff --git a/mobile/bind.go b/mobile/bind.go index 0038347f6ada..23893e6d9b6b 100644 --- a/mobile/bind.go +++ b/mobile/bind.go @@ -39,7 +39,7 @@ type signer struct { } func (s *signer) Sign(addr *Address, unsignedTx *Transaction) (signedTx *Transaction, _ error) { - sig, err := s.sign(types.HomesteadSigner{}, addr.address, unsignedTx.tx) + sig, err := s.sign(addr.address, unsignedTx.tx) if err != nil { return nil, err } @@ -89,7 +89,7 @@ func (opts *TransactOpts) GetGasLimit() int64 { return int64(opts.opts.GasLimi func (opts *TransactOpts) SetFrom(from *Address) { opts.opts.From = from.address } func (opts *TransactOpts) SetNonce(nonce int64) { opts.opts.Nonce = big.NewInt(nonce) } func (opts *TransactOpts) SetSigner(s Signer) { - opts.opts.Signer = func(signer types.Signer, addr common.Address, tx *types.Transaction) (*types.Transaction, error) { + opts.opts.Signer = func(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { sig, err := s.Sign(&Address{addr}, &Transaction{tx}) if err != nil { return nil, err From 1521b8a66302a1ee4091fea340c8431e830673a1 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 17 Jun 2024 17:24:42 +0800 Subject: [PATCH 08/10] eth: move eth.Config to a common package (#22205) --- cmd/XDC/config.go | 6 +-- cmd/XDC/misccmd.go | 3 +- cmd/faucet/faucet.go | 4 +- cmd/gc/main.go | 12 +++--- cmd/utils/flags.go | 70 +++++++++++++++---------------- cmd/utils/utils.go | 3 +- console/console_test.go | 5 ++- eth/backend.go | 20 ++++----- eth/{ => ethconfig}/config.go | 22 +++++----- eth/{ => ethconfig}/gen_config.go | 2 +- eth/handler_test.go | 6 +-- eth/helper_test.go | 8 ++-- eth/protocol_test.go | 5 ++- les/backend.go | 5 ++- les/server.go | 5 ++- mobile/geth.go | 4 +- 16 files changed, 93 insertions(+), 87 deletions(-) rename eth/{ => ethconfig}/config.go (84%) rename eth/{ => ethconfig}/gen_config.go (99%) diff --git a/cmd/XDC/config.go b/cmd/XDC/config.go index 76e03981efa5..a47f19c7bf20 100644 --- a/cmd/XDC/config.go +++ b/cmd/XDC/config.go @@ -32,7 +32,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/XDCx" "github.com/XinFinOrg/XDPoSChain/cmd/utils" "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/eth" + "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" "github.com/XinFinOrg/XDPoSChain/internal/debug" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/node" @@ -90,7 +90,7 @@ type Bootnodes struct { } type XDCConfig struct { - Eth eth.Config + Eth ethconfig.Config Shh whisper.Config Node node.Config Ethstats ethstatsConfig @@ -129,7 +129,7 @@ func defaultNodeConfig() node.Config { func makeConfigNode(ctx *cli.Context) (*node.Node, XDCConfig) { // Load defaults. cfg := XDCConfig{ - Eth: eth.DefaultConfig, + Eth: ethconfig.Defaults, Shh: whisper.DefaultConfig, XDCX: XDCx.DefaultConfig, Node: defaultNodeConfig(), diff --git a/cmd/XDC/misccmd.go b/cmd/XDC/misccmd.go index a54ad673acd2..e86f7c27cccd 100644 --- a/cmd/XDC/misccmd.go +++ b/cmd/XDC/misccmd.go @@ -26,6 +26,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/cmd/utils" "github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/eth" + "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" "github.com/XinFinOrg/XDPoSChain/params" "gopkg.in/urfave/cli.v1" ) @@ -114,7 +115,7 @@ func version(ctx *cli.Context) error { } fmt.Println("Architecture:", runtime.GOARCH) fmt.Println("Protocol Versions:", eth.ProtocolVersions) - fmt.Println("Network Id:", eth.DefaultConfig.NetworkId) + fmt.Println("Network Id:", ethconfig.Defaults.NetworkId) fmt.Println("Go Version:", runtime.Version()) fmt.Println("Operating System:", runtime.GOOS) fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH")) diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index 1a4705daf07e..f61909393d1b 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -46,8 +46,8 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/types" - "github.com/XinFinOrg/XDPoSChain/eth" "github.com/XinFinOrg/XDPoSChain/eth/downloader" + "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" "github.com/XinFinOrg/XDPoSChain/ethclient" "github.com/XinFinOrg/XDPoSChain/ethstats" "github.com/XinFinOrg/XDPoSChain/les" @@ -239,7 +239,7 @@ func newFaucet(genesis *core.Genesis, port int, enodes []*discv5.Node, network u } // Assemble the Ethereum light client protocol if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { - cfg := eth.DefaultConfig + cfg := ethconfig.Defaults cfg.SyncMode = downloader.LightSync cfg.NetworkId = network cfg.Genesis = genesis diff --git a/cmd/gc/main.go b/cmd/gc/main.go index 4b3b004b77a6..6d3b2bdf546e 100644 --- a/cmd/gc/main.go +++ b/cmd/gc/main.go @@ -3,9 +3,6 @@ package main import ( "flag" "fmt" - "github.com/XinFinOrg/XDPoSChain/core/rawdb" - "github.com/XinFinOrg/XDPoSChain/ethdb" - "github.com/XinFinOrg/XDPoSChain/ethdb/leveldb" "os" "os/signal" "runtime" @@ -16,11 +13,14 @@ import ( "github.com/XinFinOrg/XDPoSChain/cmd/utils" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/state" - "github.com/XinFinOrg/XDPoSChain/eth" + "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" + "github.com/XinFinOrg/XDPoSChain/ethdb" + "github.com/XinFinOrg/XDPoSChain/ethdb/leveldb" "github.com/XinFinOrg/XDPoSChain/rlp" "github.com/XinFinOrg/XDPoSChain/trie" - "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru" ) var ( @@ -52,7 +52,7 @@ type ResultProcessNode struct { func main() { flag.Parse() - db, _ := leveldb.New(*dir, eth.DefaultConfig.DatabaseCache, utils.MakeDatabaseHandles(), "") + db, _ := leveldb.New(*dir, ethconfig.Defaults.DatabaseCache, utils.MakeDatabaseHandles(), "") lddb := rawdb.NewDatabase(db) head := core.GetHeadBlockHash(lddb) currentHeader := core.GetHeader(lddb, head, core.GetBlockNumber(lddb, head)) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index a0c5722d8917..d0d10b4c1dbc 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -38,8 +38,8 @@ import ( "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/crypto" - "github.com/XinFinOrg/XDPoSChain/eth" "github.com/XinFinOrg/XDPoSChain/eth/downloader" + "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" "github.com/XinFinOrg/XDPoSChain/eth/gasprice" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/log" @@ -148,7 +148,7 @@ var ( NetworkIdFlag = cli.Uint64Flag{ Name: "networkid", Usage: "Network identifier (integer, 89=XDPoSChain)", - Value: eth.DefaultConfig.NetworkId, + Value: ethconfig.Defaults.NetworkId, } TestnetFlag = cli.BoolFlag{ Name: "testnet", @@ -187,7 +187,7 @@ var ( Name: "light", Usage: "Enable light client mode", } - defaultSyncMode = eth.DefaultConfig.SyncMode + defaultSyncMode = ethconfig.Defaults.SyncMode SyncModeFlag = TextMarshalerFlag{ Name: "syncmode", Usage: `Blockchain sync mode ("fast", "full", or "light")`, @@ -206,7 +206,7 @@ var ( LightPeersFlag = cli.IntFlag{ Name: "lightpeers", Usage: "Maximum number of LES client peers", - Value: eth.DefaultConfig.LightPeers, + Value: ethconfig.Defaults.LightPeers, } LightKDFFlag = cli.BoolFlag{ Name: "lightkdf", @@ -225,27 +225,27 @@ var ( EthashCachesInMemoryFlag = cli.IntFlag{ Name: "ethash.cachesinmem", Usage: "Number of recent ethash caches to keep in memory (16MB each)", - Value: eth.DefaultConfig.Ethash.CachesInMem, + Value: ethconfig.Defaults.Ethash.CachesInMem, } EthashCachesOnDiskFlag = cli.IntFlag{ Name: "ethash.cachesondisk", Usage: "Number of recent ethash caches to keep on disk (16MB each)", - Value: eth.DefaultConfig.Ethash.CachesOnDisk, + Value: ethconfig.Defaults.Ethash.CachesOnDisk, } EthashDatasetDirFlag = DirectoryFlag{ Name: "ethash.dagdir", Usage: "Directory to store the ethash mining DAGs (default = inside home folder)", - Value: DirectoryString{eth.DefaultConfig.Ethash.DatasetDir}, + Value: DirectoryString{ethconfig.Defaults.Ethash.DatasetDir}, } EthashDatasetsInMemoryFlag = cli.IntFlag{ Name: "ethash.dagsinmem", Usage: "Number of recent ethash mining DAGs to keep in memory (1+GB each)", - Value: eth.DefaultConfig.Ethash.DatasetsInMem, + Value: ethconfig.Defaults.Ethash.DatasetsInMem, } EthashDatasetsOnDiskFlag = cli.IntFlag{ Name: "ethash.dagsondisk", Usage: "Number of recent ethash mining DAGs to keep on disk (1+GB each)", - Value: eth.DefaultConfig.Ethash.DatasetsOnDisk, + Value: ethconfig.Defaults.Ethash.DatasetsOnDisk, } // Transaction pool settings TxPoolNoLocalsFlag = cli.BoolFlag{ @@ -265,37 +265,37 @@ var ( TxPoolPriceLimitFlag = cli.Uint64Flag{ Name: "txpool.pricelimit", Usage: "Minimum gas price limit to enforce for acceptance into the pool", - Value: eth.DefaultConfig.TxPool.PriceLimit, + Value: ethconfig.Defaults.TxPool.PriceLimit, } TxPoolPriceBumpFlag = cli.Uint64Flag{ Name: "txpool.pricebump", Usage: "Price bump percentage to replace an already existing transaction", - Value: eth.DefaultConfig.TxPool.PriceBump, + Value: ethconfig.Defaults.TxPool.PriceBump, } TxPoolAccountSlotsFlag = cli.Uint64Flag{ Name: "txpool.accountslots", Usage: "Minimum number of executable transaction slots guaranteed per account", - Value: eth.DefaultConfig.TxPool.AccountSlots, + Value: ethconfig.Defaults.TxPool.AccountSlots, } TxPoolGlobalSlotsFlag = cli.Uint64Flag{ Name: "txpool.globalslots", Usage: "Maximum number of executable transaction slots for all accounts", - Value: eth.DefaultConfig.TxPool.GlobalSlots, + Value: ethconfig.Defaults.TxPool.GlobalSlots, } TxPoolAccountQueueFlag = cli.Uint64Flag{ Name: "txpool.accountqueue", Usage: "Maximum number of non-executable transaction slots permitted per account", - Value: eth.DefaultConfig.TxPool.AccountQueue, + Value: ethconfig.Defaults.TxPool.AccountQueue, } TxPoolGlobalQueueFlag = cli.Uint64Flag{ Name: "txpool.globalqueue", Usage: "Maximum number of non-executable transaction slots for all accounts", - Value: eth.DefaultConfig.TxPool.GlobalQueue, + Value: ethconfig.Defaults.TxPool.GlobalQueue, } TxPoolLifetimeFlag = cli.DurationFlag{ Name: "txpool.lifetime", Usage: "Maximum amount of time non-executable transaction are queued", - Value: eth.DefaultConfig.TxPool.Lifetime, + Value: ethconfig.Defaults.TxPool.Lifetime, } // Performance tuning settings CacheFlag = cli.IntFlag{ @@ -336,7 +336,7 @@ var ( GasPriceFlag = BigFlag{ Name: "gasprice", Usage: "Minimal gas price to accept for mining a transactions", - Value: eth.DefaultConfig.GasPrice, + Value: ethconfig.Defaults.GasPrice, } ExtraDataFlag = cli.StringFlag{ Name: "extradata", @@ -361,12 +361,12 @@ var ( RPCGlobalGasCapFlag = cli.Uint64Flag{ Name: "rpc.gascap", Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)", - Value: eth.DefaultConfig.RPCGasCap, + Value: ethconfig.Defaults.RPCGasCap, } RPCGlobalTxFeeCap = cli.Float64Flag{ Name: "rpc.txfeecap", Usage: "Sets a cap on transaction fee (in ether) that can be sent via the RPC APIs (0 = no cap)", - Value: eth.DefaultConfig.RPCTxFeeCap, + Value: ethconfig.Defaults.RPCTxFeeCap, } // Logging and debug settings EthStatsURLFlag = cli.StringFlag{ @@ -548,17 +548,17 @@ var ( GpoBlocksFlag = cli.IntFlag{ Name: "gpoblocks", Usage: "Number of recent blocks to check for gas prices", - Value: eth.DefaultConfig.GPO.Blocks, + Value: ethconfig.Defaults.GPO.Blocks, } GpoPercentileFlag = cli.IntFlag{ Name: "gpopercentile", Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices", - Value: eth.DefaultConfig.GPO.Percentile, + Value: ethconfig.Defaults.GPO.Percentile, } GpoMaxGasPriceFlag = cli.Int64Flag{ Name: "gpo.maxprice", Usage: "Maximum gas price will be recommended by gpo", - Value: eth.DefaultConfig.GPO.MaxPrice.Int64(), + Value: ethconfig.Defaults.GPO.MaxPrice.Int64(), } WhisperEnabledFlag = cli.BoolFlag{ Name: "shh", @@ -854,7 +854,7 @@ func MakeAddress(ks *keystore.KeyStore, account string) (accounts.Account, error // setEtherbase retrieves the etherbase either from the directly specified // command line flags or from the keystore if CLI indexed. -func setEtherbase(ctx *cli.Context, ks *keystore.KeyStore, cfg *eth.Config) { +func setEtherbase(ctx *cli.Context, ks *keystore.KeyStore, cfg *ethconfig.Config) { if ctx.GlobalIsSet(EtherbaseFlag.Name) { account, err := MakeAddress(ks, ctx.GlobalString(EtherbaseFlag.Name)) if err != nil { @@ -987,8 +987,8 @@ func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) { // If we are running the light client, apply another group // settings for gas oracle. if light { - cfg.Blocks = eth.DefaultLightGPOConfig.Blocks - cfg.Percentile = eth.DefaultLightGPOConfig.Percentile + cfg.Blocks = ethconfig.LightClientGPO.Blocks + cfg.Percentile = ethconfig.LightClientGPO.Percentile } if ctx.GlobalIsSet(GpoBlocksFlag.Name) { cfg.Blocks = ctx.GlobalInt(GpoBlocksFlag.Name) @@ -1034,7 +1034,7 @@ func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { } } -func setEthash(ctx *cli.Context, cfg *eth.Config) { +func setEthash(ctx *cli.Context, cfg *ethconfig.Config) { if ctx.GlobalIsSet(EthashCacheDirFlag.Name) { cfg.Ethash.CacheDir = ctx.GlobalString(EthashCacheDirFlag.Name) } @@ -1140,7 +1140,7 @@ func SetXDCXConfig(ctx *cli.Context, cfg *XDCx.Config, XDCDataDir string) { } // SetEthConfig applies eth-related command line flags to the config. -func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { +func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { // Avoid conflicting network flags checkExclusive(ctx, DeveloperFlag, TestnetFlag, RinkebyFlag) checkExclusive(ctx, FastSyncFlag, LightModeFlag, SyncModeFlag) @@ -1305,12 +1305,12 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai engine = ethash.NewFaker() if !ctx.GlobalBool(FakePoWFlag.Name) { engine = ethash.New(ethash.Config{ - CacheDir: stack.ResolvePath(eth.DefaultConfig.Ethash.CacheDir), - CachesInMem: eth.DefaultConfig.Ethash.CachesInMem, - CachesOnDisk: eth.DefaultConfig.Ethash.CachesOnDisk, - DatasetDir: stack.ResolvePath(eth.DefaultConfig.Ethash.DatasetDir), - DatasetsInMem: eth.DefaultConfig.Ethash.DatasetsInMem, - DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk, + CacheDir: stack.ResolvePath(ethconfig.Defaults.Ethash.CacheDir), + CachesInMem: ethconfig.Defaults.Ethash.CachesInMem, + CachesOnDisk: ethconfig.Defaults.Ethash.CachesOnDisk, + DatasetDir: stack.ResolvePath(ethconfig.Defaults.Ethash.DatasetDir), + DatasetsInMem: ethconfig.Defaults.Ethash.DatasetsInMem, + DatasetsOnDisk: ethconfig.Defaults.Ethash.DatasetsOnDisk, }) } Fatalf("Only support XDPoS consensus") @@ -1320,8 +1320,8 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai } cache := &core.CacheConfig{ Disabled: ctx.GlobalString(GCModeFlag.Name) == "archive", - TrieNodeLimit: eth.DefaultConfig.TrieCache, - TrieTimeLimit: eth.DefaultConfig.TrieTimeout, + TrieNodeLimit: ethconfig.Defaults.TrieCache, + TrieTimeLimit: ethconfig.Defaults.TrieTimeout, } if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) { cache.TrieNodeLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100 diff --git a/cmd/utils/utils.go b/cmd/utils/utils.go index 94d2eb387ce8..406d15ebfc83 100644 --- a/cmd/utils/utils.go +++ b/cmd/utils/utils.go @@ -5,6 +5,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/XDCxlending" "github.com/XinFinOrg/XDPoSChain/eth" "github.com/XinFinOrg/XDPoSChain/eth/downloader" + "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" "github.com/XinFinOrg/XDPoSChain/ethstats" "github.com/XinFinOrg/XDPoSChain/les" "github.com/XinFinOrg/XDPoSChain/node" @@ -12,7 +13,7 @@ import ( ) // RegisterEthService adds an Ethereum client to the stack. -func RegisterEthService(stack *node.Node, cfg *eth.Config) { +func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) { var err error if cfg.SyncMode == downloader.LightSync { err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { diff --git a/console/console_test.go b/console/console_test.go index 04a1f5a2e49d..9433026db868 100644 --- a/console/console_test.go +++ b/console/console_test.go @@ -31,6 +31,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/eth" + "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" "github.com/XinFinOrg/XDPoSChain/internal/jsre" "github.com/XinFinOrg/XDPoSChain/node" ) @@ -84,7 +85,7 @@ type tester struct { // newTester creates a test environment based on which the console can operate. // Please ensure you call Close() on the returned tester to avoid leaks. -func newTester(t *testing.T, confOverride func(*eth.Config)) *tester { +func newTester(t *testing.T, confOverride func(*ethconfig.Config)) *tester { // Create a temporary storage for the node keys and initialize it workspace, err := os.MkdirTemp("", "console-tester-") if err != nil { @@ -96,7 +97,7 @@ func newTester(t *testing.T, confOverride func(*eth.Config)) *tester { if err != nil { t.Fatalf("failed to create node: %v", err) } - ethConf := ð.Config{ + ethConf := ðconfig.Config{ Genesis: core.DeveloperGenesisBlock(15, common.Address{}), Etherbase: common.HexToAddress(testAddress), Ethash: ethash.Config{ diff --git a/eth/backend.go b/eth/backend.go index a572015b7786..531d633fa45f 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -25,15 +25,11 @@ import ( "sync" "sync/atomic" + "github.com/XinFinOrg/XDPoSChain/XDCx" "github.com/XinFinOrg/XDPoSChain/XDCxlending" - - "github.com/XinFinOrg/XDPoSChain/common/hexutil" - "github.com/XinFinOrg/XDPoSChain/eth/filters" - "github.com/XinFinOrg/XDPoSChain/eth/hooks" - "github.com/XinFinOrg/XDPoSChain/rlp" - "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" @@ -41,12 +37,13 @@ import ( "github.com/XinFinOrg/XDPoSChain/contracts" "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/bloombits" - - "github.com/XinFinOrg/XDPoSChain/XDCx" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/eth/downloader" + "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" + "github.com/XinFinOrg/XDPoSChain/eth/filters" "github.com/XinFinOrg/XDPoSChain/eth/gasprice" + "github.com/XinFinOrg/XDPoSChain/eth/hooks" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/event" "github.com/XinFinOrg/XDPoSChain/internal/ethapi" @@ -55,6 +52,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/node" "github.com/XinFinOrg/XDPoSChain/p2p" "github.com/XinFinOrg/XDPoSChain/params" + "github.com/XinFinOrg/XDPoSChain/rlp" "github.com/XinFinOrg/XDPoSChain/rpc" ) @@ -67,7 +65,7 @@ type LesServer interface { // Ethereum implements the Ethereum full node service. type Ethereum struct { - config *Config + config *ethconfig.Config chainConfig *params.ChainConfig // Channel for shutting down the service @@ -112,7 +110,7 @@ func (s *Ethereum) AddLesServer(ls LesServer) { // New creates a new Ethereum object (including the // initialisation of the common Ethereum object) -func New(ctx *node.ServiceContext, config *Config, XDCXServ *XDCx.XDCX, lendingServ *XDCxlending.Lending) (*Ethereum, error) { +func New(ctx *node.ServiceContext, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendingServ *XDCxlending.Lending) (*Ethereum, error) { if config.SyncMode == downloader.LightSync { return nil, errors.New("can't run eth.Ethereum in light sync mode, use les.LightEthereum") } @@ -326,7 +324,7 @@ func makeExtraData(extra []byte) []byte { } // CreateDB creates the chain database. -func CreateDB(ctx *node.ServiceContext, config *Config, name string) (ethdb.Database, error) { +func CreateDB(ctx *node.ServiceContext, config *ethconfig.Config, name string) (ethdb.Database, error) { db, err := ctx.OpenDatabase(name, config.DatabaseCache, config.DatabaseHandles) if err != nil { return nil, err diff --git a/eth/config.go b/eth/ethconfig/config.go similarity index 84% rename from eth/config.go rename to eth/ethconfig/config.go index 102166891348..010020a56e0a 100644 --- a/eth/config.go +++ b/eth/ethconfig/config.go @@ -14,7 +14,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package eth +// Package ethconfig contains the configuration of the ETH and LES protocols. +package ethconfig import ( "math/big" @@ -33,22 +34,22 @@ import ( "github.com/XinFinOrg/XDPoSChain/params" ) -// DefaultFullGPOConfig contains default gasprice oracle settings for full node. -var DefaultFullGPOConfig = gasprice.Config{ +// FullNodeGPO contains default gasprice oracle settings for full node. +var FullNodeGPO = gasprice.Config{ Blocks: 20, Percentile: 60, MaxPrice: gasprice.DefaultMaxPrice, } -// DefaultLightGPOConfig contains default gasprice oracle settings for light client. -var DefaultLightGPOConfig = gasprice.Config{ +// LightClientGPO contains default gasprice oracle settings for light client. +var LightClientGPO = gasprice.Config{ Blocks: 2, Percentile: 60, MaxPrice: gasprice.DefaultMaxPrice, } -// DefaultConfig contains default settings for use on the Ethereum main net. -var DefaultConfig = Config{ +// Defaults contains default settings for use on the Ethereum main net. +var Defaults = Config{ SyncMode: downloader.FullSync, Ethash: ethash.Config{ CacheDir: "ethash", @@ -66,7 +67,7 @@ var DefaultConfig = Config{ TxPool: core.DefaultTxPoolConfig, RPCGasCap: 25000000, - GPO: DefaultFullGPOConfig, + GPO: FullNodeGPO, RPCTxFeeCap: 1, // 1 ether } @@ -78,14 +79,15 @@ func init() { } } if runtime.GOOS == "windows" { - DefaultConfig.Ethash.DatasetDir = filepath.Join(home, "AppData", "Ethash") + Defaults.Ethash.DatasetDir = filepath.Join(home, "AppData", "Ethash") } else { - DefaultConfig.Ethash.DatasetDir = filepath.Join(home, ".ethash") + Defaults.Ethash.DatasetDir = filepath.Join(home, ".ethash") } } //go:generate gencodec -type Config -field-override configMarshaling -formats toml -out gen_config.go +// Config contains configuration options for of the ETH and LES protocols. type Config struct { // The genesis block, which is inserted if the database is empty. // If nil, the Ethereum main net block is used. diff --git a/eth/gen_config.go b/eth/ethconfig/gen_config.go similarity index 99% rename from eth/gen_config.go rename to eth/ethconfig/gen_config.go index abfed29e3547..d24b3251c05b 100644 --- a/eth/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -1,6 +1,6 @@ // Code generated by github.com/fjl/gencodec. DO NOT EDIT. -package eth +package ethconfig import ( "math/big" diff --git a/eth/handler_test.go b/eth/handler_test.go index 14dbcb3b8150..651a33a28c49 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -23,16 +23,16 @@ import ( "testing" "time" - "github.com/XinFinOrg/XDPoSChain/core/rawdb" - "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/eth/downloader" + "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" "github.com/XinFinOrg/XDPoSChain/event" "github.com/XinFinOrg/XDPoSChain/p2p" "github.com/XinFinOrg/XDPoSChain/params" @@ -477,7 +477,7 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool genesis = gspec.MustCommit(db) blockchain, _ = core.NewBlockChain(db, nil, config, pow, vm.Config{}) ) - pm, err := NewProtocolManager(config, downloader.FullSync, DefaultConfig.NetworkId, evmux, new(testTxPool), pow, blockchain, db) + pm, err := NewProtocolManager(config, downloader.FullSync, ethconfig.Defaults.NetworkId, evmux, new(testTxPool), pow, blockchain, db) if err != nil { t.Fatalf("failed to start test protocol manager: %v", err) } diff --git a/eth/helper_test.go b/eth/helper_test.go index 07c6d92ee166..4963093c1aa0 100644 --- a/eth/helper_test.go +++ b/eth/helper_test.go @@ -27,15 +27,15 @@ import ( "sync" "testing" - "github.com/XinFinOrg/XDPoSChain/core/rawdb" - "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/eth/downloader" + "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/event" "github.com/XinFinOrg/XDPoSChain/p2p" @@ -68,7 +68,7 @@ func newTestProtocolManager(mode downloader.SyncMode, blocks int, generator func panic(err) } - pm, err := NewProtocolManager(gspec.Config, mode, DefaultConfig.NetworkId, evmux, &testTxPool{added: newtx}, engine, blockchain, db) + pm, err := NewProtocolManager(gspec.Config, mode, ethconfig.Defaults.NetworkId, evmux, &testTxPool{added: newtx}, engine, blockchain, db) if err != nil { return nil, nil, err } @@ -183,7 +183,7 @@ func newTestPeer(name string, version int, pm *ProtocolManager, shake bool) (*te func (p *testPeer) handshake(t *testing.T, td *big.Int, head common.Hash, genesis common.Hash) { msg := &statusData{ ProtocolVersion: uint32(p.version), - NetworkId: DefaultConfig.NetworkId, + NetworkId: ethconfig.Defaults.NetworkId, TD: td, CurrentBlock: head, GenesisBlock: genesis, diff --git a/eth/protocol_test.go b/eth/protocol_test.go index 91788594f210..8c5283cd8b18 100644 --- a/eth/protocol_test.go +++ b/eth/protocol_test.go @@ -26,6 +26,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/eth/downloader" + "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" "github.com/XinFinOrg/XDPoSChain/p2p" "github.com/XinFinOrg/XDPoSChain/rlp" ) @@ -59,7 +60,7 @@ func testStatusMsgErrors(t *testing.T, protocol int) { wantError: errResp(ErrNoStatusMsg, "first msg has code 2 (!= 0)"), }, { - code: StatusMsg, data: statusData{10, DefaultConfig.NetworkId, td, head.Hash(), genesis.Hash()}, + code: StatusMsg, data: statusData{10, ethconfig.Defaults.NetworkId, td, head.Hash(), genesis.Hash()}, wantError: errResp(ErrProtocolVersionMismatch, "10 (!= %d)", protocol), }, { @@ -67,7 +68,7 @@ func testStatusMsgErrors(t *testing.T, protocol int) { wantError: errResp(ErrNetworkIdMismatch, "999 (!= 88)"), }, { - code: StatusMsg, data: statusData{uint32(protocol), DefaultConfig.NetworkId, td, head.Hash(), common.Hash{3}}, + code: StatusMsg, data: statusData{uint32(protocol), ethconfig.Defaults.NetworkId, td, head.Hash(), common.Hash{3}}, wantError: errResp(ErrGenesisBlockMismatch, "0300000000000000 (!= %x)", genesis.Hash().Bytes()[:8]), }, } diff --git a/les/backend.go b/les/backend.go index a4b2074744db..13bc90a3b07e 100644 --- a/les/backend.go +++ b/les/backend.go @@ -31,6 +31,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/eth" "github.com/XinFinOrg/XDPoSChain/eth/downloader" + "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" "github.com/XinFinOrg/XDPoSChain/eth/filters" "github.com/XinFinOrg/XDPoSChain/eth/gasprice" "github.com/XinFinOrg/XDPoSChain/ethdb" @@ -46,7 +47,7 @@ import ( ) type LightEthereum struct { - config *eth.Config + config *ethconfig.Config odr *LesOdr relay *LesTxRelay @@ -79,7 +80,7 @@ type LightEthereum struct { wg sync.WaitGroup } -func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) { +func New(ctx *node.ServiceContext, config *ethconfig.Config) (*LightEthereum, error) { chainDb, err := eth.CreateDB(ctx, config, "lightchaindata") if err != nil { return nil, err diff --git a/les/server.go b/les/server.go index 68762c441430..db494726e332 100644 --- a/les/server.go +++ b/les/server.go @@ -27,6 +27,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/eth" + "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/les/flowcontrol" "github.com/XinFinOrg/XDPoSChain/light" @@ -37,7 +38,7 @@ import ( ) type LesServer struct { - config *eth.Config + config *ethconfig.Config protocolManager *ProtocolManager fcManager *flowcontrol.ClientManager // nil if our node is client only fcCostStats *requestCostStats @@ -49,7 +50,7 @@ type LesServer struct { chtIndexer, bloomTrieIndexer *core.ChainIndexer } -func NewLesServer(eth *eth.Ethereum, config *eth.Config) (*LesServer, error) { +func NewLesServer(eth *eth.Ethereum, config *ethconfig.Config) (*LesServer, error) { quitSync := make(chan struct{}) pm, err := NewProtocolManager(eth.BlockChain().Config(), false, ServerProtocolVersions, config.NetworkId, eth.EventMux(), eth.Engine(), newPeerSet(), eth.BlockChain(), eth.TxPool(), eth.ChainDb(), nil, nil, quitSync, new(sync.WaitGroup)) if err != nil { diff --git a/mobile/geth.go b/mobile/geth.go index 02564b8e9ceb..fd62ea004971 100644 --- a/mobile/geth.go +++ b/mobile/geth.go @@ -25,8 +25,8 @@ import ( "path/filepath" "github.com/XinFinOrg/XDPoSChain/core" - "github.com/XinFinOrg/XDPoSChain/eth" "github.com/XinFinOrg/XDPoSChain/eth/downloader" + "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" "github.com/XinFinOrg/XDPoSChain/ethclient" "github.com/XinFinOrg/XDPoSChain/ethstats" "github.com/XinFinOrg/XDPoSChain/les" @@ -144,7 +144,7 @@ func NewNode(datadir string, config *NodeConfig) (stack *Node, _ error) { } // Register the Ethereum protocol if requested if config.EthereumEnabled { - ethConf := eth.DefaultConfig + ethConf := ethconfig.Defaults ethConf.Genesis = genesis ethConf.SyncMode = downloader.LightSync ethConf.NetworkId = uint64(config.EthereumNetworkID) From 2b365e8112778ed2b68a80f83450bad7ad6a2339 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 20 May 2024 14:30:51 +0800 Subject: [PATCH 09/10] eth/gasprice: improve stability of estimated price (#22722) --- eth/gasprice/gasprice.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index 8ffd90723149..d046437a6c70 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -205,6 +205,9 @@ func (gpo *Oracle) getBlockPrices(ctx context.Context, signer types.Signer, bloc var prices []*big.Int for _, tx := range txs { + if tx.GasPrice().Cmp(common.Big1) <= 0 { + continue + } sender, err := types.Sender(signer, tx) if err == nil && sender != block.Coinbase() { prices = append(prices, tx.GasPrice()) From f445196dcfea05fda19649631be6ee2c541f9838 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 20 May 2024 14:47:28 +0800 Subject: [PATCH 10/10] eth/gasprice: add configurable threshold to gas price oracle (#22752) --- cmd/XDC/main.go | 1 + cmd/XDC/usage.go | 1 + cmd/utils/flags.go | 8 ++++++++ eth/ethconfig/config.go | 14 ++++++++------ eth/gasprice/gasprice.go | 39 +++++++++++++++++++++++++-------------- 5 files changed, 43 insertions(+), 20 deletions(-) diff --git a/cmd/XDC/main.go b/cmd/XDC/main.go index 4a5c7507f980..3a028fe180aa 100644 --- a/cmd/XDC/main.go +++ b/cmd/XDC/main.go @@ -128,6 +128,7 @@ var ( //utils.GpoBlocksFlag, //utils.GpoPercentileFlag, utils.GpoMaxGasPriceFlag, + utils.GpoIgnoreGasPriceFlag, //utils.ExtraDataFlag, configFileFlag, utils.AnnounceTxsFlag, diff --git a/cmd/XDC/usage.go b/cmd/XDC/usage.go index 5269418fe590..f0e567bd555f 100644 --- a/cmd/XDC/usage.go +++ b/cmd/XDC/usage.go @@ -196,6 +196,7 @@ var AppHelpFlagGroups = []flagGroup{ // utils.GpoBlocksFlag, // utils.GpoPercentileFlag, // utils.GpoMaxGasPriceFlag, + // utils.GpoIgnoreGasPriceFlag, // }, //}, //{ diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index d0d10b4c1dbc..310a3f12e9b6 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -560,6 +560,11 @@ var ( Usage: "Maximum gas price will be recommended by gpo", Value: ethconfig.Defaults.GPO.MaxPrice.Int64(), } + GpoIgnoreGasPriceFlag = cli.Int64Flag{ + Name: "gpo.ignoreprice", + Usage: "Gas price below which gpo will ignore transactions", + Value: ethconfig.Defaults.GPO.IgnorePrice.Int64(), + } WhisperEnabledFlag = cli.BoolFlag{ Name: "shh", Usage: "Enable Whisper", @@ -999,6 +1004,9 @@ func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) { if ctx.GlobalIsSet(GpoMaxGasPriceFlag.Name) { cfg.MaxPrice = big.NewInt(ctx.GlobalInt64(GpoMaxGasPriceFlag.Name)) } + if ctx.GlobalIsSet(GpoIgnoreGasPriceFlag.Name) { + cfg.IgnorePrice = big.NewInt(ctx.GlobalInt64(GpoIgnoreGasPriceFlag.Name)) + } } func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 010020a56e0a..b246a9b332a6 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -36,16 +36,18 @@ import ( // FullNodeGPO contains default gasprice oracle settings for full node. var FullNodeGPO = gasprice.Config{ - Blocks: 20, - Percentile: 60, - MaxPrice: gasprice.DefaultMaxPrice, + Blocks: 20, + Percentile: 60, + MaxPrice: gasprice.DefaultMaxPrice, + IgnorePrice: gasprice.DefaultIgnorePrice, } // LightClientGPO contains default gasprice oracle settings for light client. var LightClientGPO = gasprice.Config{ - Blocks: 2, - Percentile: 60, - MaxPrice: gasprice.DefaultMaxPrice, + Blocks: 2, + Percentile: 60, + MaxPrice: gasprice.DefaultMaxPrice, + IgnorePrice: gasprice.DefaultIgnorePrice, } // Defaults contains default settings for use on the Ethereum main net. diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index d046437a6c70..fe3a4b511126 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -32,12 +32,14 @@ import ( const sampleNumber = 3 // Number of transactions sampled in a block var DefaultMaxPrice = big.NewInt(500 * params.GWei) +var DefaultIgnorePrice = big.NewInt(2 * params.Wei) type Config struct { - Blocks int - Percentile int - Default *big.Int `toml:",omitempty"` - MaxPrice *big.Int `toml:",omitempty"` + Blocks int + Percentile int + Default *big.Int `toml:",omitempty"` + MaxPrice *big.Int `toml:",omitempty"` + IgnorePrice *big.Int `toml:",omitempty"` } // OracleBackend includes all necessary background APIs for oracle. @@ -50,12 +52,13 @@ type OracleBackend interface { // Oracle recommends gas prices based on the content of recent // blocks. Suitable for both light and full clients. type Oracle struct { - backend OracleBackend - lastHead common.Hash - lastPrice *big.Int - maxPrice *big.Int - cacheLock sync.RWMutex - fetchLock sync.Mutex + backend OracleBackend + lastHead common.Hash + lastPrice *big.Int + maxPrice *big.Int + ignorePrice *big.Int + cacheLock sync.RWMutex + fetchLock sync.Mutex checkBlocks int percentile int @@ -83,10 +86,18 @@ func NewOracle(backend OracleBackend, params Config) *Oracle { maxPrice = DefaultMaxPrice log.Warn("Sanitizing invalid gasprice oracle price cap", "provided", params.MaxPrice, "updated", maxPrice) } + ignorePrice := params.IgnorePrice + if ignorePrice == nil || ignorePrice.Int64() <= 0 { + ignorePrice = DefaultIgnorePrice + log.Warn("Sanitizing invalid gasprice oracle ignore price", "provided", params.IgnorePrice, "updated", ignorePrice) + } else if ignorePrice.Int64() > 0 { + log.Info("Gasprice oracle is ignoring threshold set", "threshold", ignorePrice) + } return &Oracle{ backend: backend, lastPrice: params.Default, maxPrice: maxPrice, + ignorePrice: ignorePrice, checkBlocks: blocks, percentile: percent, } @@ -122,7 +133,7 @@ func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) { txPrices []*big.Int ) for sent < gpo.checkBlocks && number > 0 { - go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, result, quit) + go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, gpo.ignorePrice, result, quit) sent++ exp++ number-- @@ -145,7 +156,7 @@ func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) { // meaningful returned, try to query more blocks. But the maximum // is 2*checkBlocks. if len(res.prices) == 1 && len(txPrices)+1+exp < gpo.checkBlocks*2 && number > 0 { - go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, result, quit) + go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, gpo.ignorePrice, result, quit) sent++ exp++ number-- @@ -189,7 +200,7 @@ func (t transactionsByGasPrice) Less(i, j int) bool { return t[i].GasPriceCmp(t[ // and sends it to the result channel. If the block is empty or all transactions // are sent by the miner itself(it doesn't make any sense to include this kind of // transaction prices for sampling), nil gasprice is returned. -func (gpo *Oracle) getBlockPrices(ctx context.Context, signer types.Signer, blockNum uint64, limit int, result chan getBlockPricesResult, quit chan struct{}) { +func (gpo *Oracle) getBlockPrices(ctx context.Context, signer types.Signer, blockNum uint64, limit int, ignoreUnder *big.Int, result chan getBlockPricesResult, quit chan struct{}) { block, err := gpo.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNum)) if block == nil { select { @@ -205,7 +216,7 @@ func (gpo *Oracle) getBlockPrices(ctx context.Context, signer types.Signer, bloc var prices []*big.Int for _, tx := range txs { - if tx.GasPrice().Cmp(common.Big1) <= 0 { + if ignoreUnder != nil && tx.GasPrice().Cmp(ignoreUnder) == -1 { continue } sender, err := types.Sender(signer, tx)