diff options
-rw-r--r-- | cmd/utils/flags.go | 2 | ||||
-rw-r--r-- | dex/api_backend.go | 2 | ||||
-rw-r--r-- | dex/backend.go | 2 | ||||
-rw-r--r-- | dex/config.go | 2 | ||||
-rw-r--r-- | dex/gasprice/gasprice.go | 189 |
5 files changed, 4 insertions, 193 deletions
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index feb304706..0ea9761d2 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -41,9 +41,9 @@ import ( "github.com/dexon-foundation/dexon/crypto" "github.com/dexon-foundation/dexon/dashboard" "github.com/dexon-foundation/dexon/dex" - "github.com/dexon-foundation/dexon/dex/gasprice" "github.com/dexon-foundation/dexon/eth" "github.com/dexon-foundation/dexon/eth/downloader" + "github.com/dexon-foundation/dexon/eth/gasprice" "github.com/dexon-foundation/dexon/ethdb" "github.com/dexon-foundation/dexon/ethstats" "github.com/dexon-foundation/dexon/les" diff --git a/dex/api_backend.go b/dex/api_backend.go index d8d52974d..c6c1d214d 100644 --- a/dex/api_backend.go +++ b/dex/api_backend.go @@ -29,8 +29,8 @@ import ( "github.com/dexon-foundation/dexon/core/state" "github.com/dexon-foundation/dexon/core/types" "github.com/dexon-foundation/dexon/core/vm" - "github.com/dexon-foundation/dexon/dex/gasprice" "github.com/dexon-foundation/dexon/eth/downloader" + "github.com/dexon-foundation/dexon/eth/gasprice" "github.com/dexon-foundation/dexon/ethdb" "github.com/dexon-foundation/dexon/event" diff --git a/dex/backend.go b/dex/backend.go index 3b727adde..d7bc4630e 100644 --- a/dex/backend.go +++ b/dex/backend.go @@ -34,9 +34,9 @@ import ( "github.com/dexon-foundation/dexon/core/bloombits" "github.com/dexon-foundation/dexon/core/rawdb" "github.com/dexon-foundation/dexon/core/vm" - "github.com/dexon-foundation/dexon/dex/gasprice" "github.com/dexon-foundation/dexon/eth/downloader" "github.com/dexon-foundation/dexon/eth/filters" + "github.com/dexon-foundation/dexon/eth/gasprice" "github.com/dexon-foundation/dexon/ethdb" "github.com/dexon-foundation/dexon/event" "github.com/dexon-foundation/dexon/internal/ethapi" diff --git a/dex/config.go b/dex/config.go index e74425ea3..cd9d1b1db 100644 --- a/dex/config.go +++ b/dex/config.go @@ -26,8 +26,8 @@ import ( "time" "github.com/dexon-foundation/dexon/core" - "github.com/dexon-foundation/dexon/dex/gasprice" "github.com/dexon-foundation/dexon/eth/downloader" + "github.com/dexon-foundation/dexon/eth/gasprice" "github.com/dexon-foundation/dexon/params" ) diff --git a/dex/gasprice/gasprice.go b/dex/gasprice/gasprice.go deleted file mode 100644 index 9af33c682..000000000 --- a/dex/gasprice/gasprice.go +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package gasprice - -import ( - "context" - "math/big" - "sort" - "sync" - - "github.com/dexon-foundation/dexon/common" - "github.com/dexon-foundation/dexon/core/types" - "github.com/dexon-foundation/dexon/internal/ethapi" - "github.com/dexon-foundation/dexon/params" - "github.com/dexon-foundation/dexon/rpc" -) - -var maxPrice = big.NewInt(500 * params.GWei) - -type Config struct { - Blocks int - Percentile int - Default *big.Int `toml:",omitempty"` -} - -// Oracle recommends gas prices based on the content of recent -// blocks. Suitable for both light and full clients. -type Oracle struct { - backend ethapi.Backend - lastHead common.Hash - lastPrice *big.Int - cacheLock sync.RWMutex - fetchLock sync.Mutex - - checkBlocks, maxEmpty, maxBlocks int - percentile int -} - -// NewOracle returns a new oracle. -func NewOracle(backend ethapi.Backend, params Config) *Oracle { - blocks := params.Blocks - if blocks < 1 { - blocks = 1 - } - percent := params.Percentile - if percent < 0 { - percent = 0 - } - if percent > 100 { - percent = 100 - } - return &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 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 - gpo.cacheLock.RLock() - lastHead = gpo.lastHead - lastPrice = 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) - sent++ - exp++ - blockNum-- - } - maxEmpty := gpo.maxEmpty - for exp > 0 { - res := <-ch - if res.err != nil { - return lastPrice, res.err - } - exp-- - if res.price != nil { - blockPrices = append(blockPrices, res.price) - continue - } - if maxEmpty > 0 { - maxEmpty-- - continue - } - if blockNum > 0 && sent < gpo.maxBlocks { - go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(blockNum))), blockNum, ch) - sent++ - exp++ - blockNum-- - } - } - price := lastPrice - if len(blockPrices) > 0 { - sort.Sort(bigIntArray(blockPrices)) - price = blockPrices[(len(blockPrices)-1)*gpo.percentile/100] - } - if price.Cmp(maxPrice) > 0 { - price = new(big.Int).Set(maxPrice) - } - - gpo.cacheLock.Lock() - gpo.lastHead = headHash - gpo.lastPrice = price - gpo.cacheLock.Unlock() - return price, nil -} - -type getBlockPricesResult struct { - price *big.Int - err error -} - -type transactionsByGasPrice []*types.Transaction - -func (t transactionsByGasPrice) Len() int { return len(t) } -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].GasPrice().Cmp(t[j].GasPrice()) < 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) { - block, err := gpo.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNum)) - if block == nil { - ch <- getBlockPricesResult{nil, err} - return - } - - blockTxs := block.Transactions() - txs := make([]*types.Transaction, len(blockTxs)) - copy(txs, blockTxs) - sort.Sort(transactionsByGasPrice(txs)) - - for _, tx := range txs { - sender, err := types.Sender(signer, tx) - if err == nil && sender != block.Coinbase() { - ch <- getBlockPricesResult{tx.GasPrice(), nil} - return - } - } - ch <- getBlockPricesResult{nil, nil} -} - -type bigIntArray []*big.Int - -func (s bigIntArray) Len() int { return len(s) } -func (s bigIntArray) Less(i, j int) bool { return s[i].Cmp(s[j]) < 0 } -func (s bigIntArray) Swap(i, j int) { s[i], s[j] = s[j], s[i] } |