|
|
@ -24,18 +24,20 @@ import ( |
|
|
|
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/common" |
|
|
|
"github.com/ethereum/go-ethereum/common" |
|
|
|
"github.com/ethereum/go-ethereum/core/types" |
|
|
|
"github.com/ethereum/go-ethereum/core/types" |
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/log" |
|
|
|
"github.com/ethereum/go-ethereum/params" |
|
|
|
"github.com/ethereum/go-ethereum/params" |
|
|
|
"github.com/ethereum/go-ethereum/rpc" |
|
|
|
"github.com/ethereum/go-ethereum/rpc" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
const sampleNumber = 3 // Number of transactions sampled in a block
|
|
|
|
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 { |
|
|
|
type Config struct { |
|
|
|
Blocks int |
|
|
|
Blocks int |
|
|
|
Percentile int |
|
|
|
Percentile int |
|
|
|
Default *big.Int `toml:",omitempty"` |
|
|
|
Default *big.Int `toml:",omitempty"` |
|
|
|
|
|
|
|
MaxPrice *big.Int `toml:",omitempty"` |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// OracleBackend includes all necessary background APIs for oracle.
|
|
|
|
// OracleBackend includes all necessary background APIs for oracle.
|
|
|
@ -51,6 +53,7 @@ type Oracle struct { |
|
|
|
backend OracleBackend |
|
|
|
backend OracleBackend |
|
|
|
lastHead common.Hash |
|
|
|
lastHead common.Hash |
|
|
|
lastPrice *big.Int |
|
|
|
lastPrice *big.Int |
|
|
|
|
|
|
|
maxPrice *big.Int |
|
|
|
cacheLock sync.RWMutex |
|
|
|
cacheLock sync.RWMutex |
|
|
|
fetchLock sync.Mutex |
|
|
|
fetchLock sync.Mutex |
|
|
|
|
|
|
|
|
|
|
@ -64,17 +67,26 @@ func NewOracle(backend OracleBackend, params Config) *Oracle { |
|
|
|
blocks := params.Blocks |
|
|
|
blocks := params.Blocks |
|
|
|
if blocks < 1 { |
|
|
|
if blocks < 1 { |
|
|
|
blocks = 1 |
|
|
|
blocks = 1 |
|
|
|
|
|
|
|
log.Warn("Sanitizing invalid gasprice oracle sample blocks", "provided", params.Blocks, "updated", blocks) |
|
|
|
} |
|
|
|
} |
|
|
|
percent := params.Percentile |
|
|
|
percent := params.Percentile |
|
|
|
if percent < 0 { |
|
|
|
if percent < 0 { |
|
|
|
percent = 0 |
|
|
|
percent = 0 |
|
|
|
|
|
|
|
log.Warn("Sanitizing invalid gasprice oracle sample percentile", "provided", params.Percentile, "updated", percent) |
|
|
|
} |
|
|
|
} |
|
|
|
if percent > 100 { |
|
|
|
if percent > 100 { |
|
|
|
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{ |
|
|
|
return &Oracle{ |
|
|
|
backend: backend, |
|
|
|
backend: backend, |
|
|
|
lastPrice: params.Default, |
|
|
|
lastPrice: params.Default, |
|
|
|
|
|
|
|
maxPrice: maxPrice, |
|
|
|
checkBlocks: blocks, |
|
|
|
checkBlocks: blocks, |
|
|
|
percentile: percent, |
|
|
|
percentile: percent, |
|
|
|
} |
|
|
|
} |
|
|
@ -146,8 +158,8 @@ func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) { |
|
|
|
sort.Sort(bigIntArray(txPrices)) |
|
|
|
sort.Sort(bigIntArray(txPrices)) |
|
|
|
price = txPrices[(len(txPrices)-1)*gpo.percentile/100] |
|
|
|
price = txPrices[(len(txPrices)-1)*gpo.percentile/100] |
|
|
|
} |
|
|
|
} |
|
|
|
if price.Cmp(maxPrice) > 0 { |
|
|
|
if price.Cmp(gpo.maxPrice) > 0 { |
|
|
|
price = new(big.Int).Set(maxPrice) |
|
|
|
price = new(big.Int).Set(gpo.maxPrice) |
|
|
|
} |
|
|
|
} |
|
|
|
gpo.cacheLock.Lock() |
|
|
|
gpo.cacheLock.Lock() |
|
|
|
gpo.lastHead = headHash |
|
|
|
gpo.lastHead = headHash |
|
|
|