From dfc9eef85ee3711eaa6d31d1aee89537dc66ab3c Mon Sep 17 00:00:00 2001 From: jarmg Date: Tue, 4 Jun 2019 16:49:18 -0700 Subject: [PATCH] Revert "Enable smart contract calling from LES (#207)" (#239) This reverts commit 348e0761c4d1d2883114c2ed510b3dac27a6cfee. --- consensus/istanbul/backend/engine.go | 9 --- core/currency.go | 116 +++++++++------------------ core/evm.go | 36 ++++----- core/registeredAddresses.go | 7 +- core/tx_list.go | 12 +-- core/tx_pool.go | 10 +-- core/tx_pool_test.go | 68 ++++++++-------- eth/api_backend.go | 2 +- eth/backend.go | 14 ++-- eth/gasprice/access_gasprice.go | 64 --------------- eth/gasprice/gasprice.go | 81 +++++++------------ les/api_backend.go | 3 +- les/backend.go | 21 ++--- les/handler_test.go | 4 +- light/lightchain.go | 7 +- miner/miner.go | 4 +- miner/worker.go | 8 +- miner/worker_test.go | 8 +- params/protocol_params.go | 1 - 19 files changed, 160 insertions(+), 315 deletions(-) delete mode 100644 eth/gasprice/access_gasprice.go diff --git a/consensus/istanbul/backend/engine.go b/consensus/istanbul/backend/engine.go index 5e198ab072b8..344a2b83b087 100644 --- a/consensus/istanbul/backend/engine.go +++ b/consensus/istanbul/backend/engine.go @@ -428,10 +428,6 @@ func (sb *Backend) IsLastBlockOfEpoch(header *types.Header) bool { // consensus rules that happen at finalization (e.g. block rewards). func (sb *Backend) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { - - // Calculate a new gas price suggestion and push it to the GasPriceOracle SmartContract - sb.updateGasPriceSuggestion(state) - // No block rewards in Istanbul, so the state remains as is and uncles are dropped header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) header.UncleHash = nilUncleHash @@ -440,11 +436,6 @@ func (sb *Backend) Finalize(chain consensus.ChainReader, header *types.Header, s return types.NewBlock(header, txs, nil, receipts), nil } -// TODO (jarmg 5/23/18): Implement this -func (sb *Backend) updateGasPriceSuggestion(state *state.StateDB) *state.StateDB { - return (state) -} - // Seal generates a new block for the given input block with the local miner's // seal place on top. func (sb *Backend) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { diff --git a/core/currency.go b/core/currency.go index 04e33958d35d..1aa985a44e47 100644 --- a/core/currency.go +++ b/core/currency.go @@ -109,66 +109,33 @@ type exchangeRate struct { Denominator *big.Int } -type CurrencyOperator struct { - gcWl *GasCurrencyWhitelist // Object to retrieve the set of currencies that will have their exchange rate monitored - exchangeRates map[common.Address]*exchangeRate // indexedCurrency:CeloGold exchange rate - regAdd *RegisteredAddresses - iEvmH *InternalEVMHandler - currencyOperatorMu sync.RWMutex +type PriceComparator struct { + gcWl *GasCurrencyWhitelist // Object to retrieve the set of currencies that will have their exchange rate monitored + exchangeRates map[common.Address]*exchangeRate // indexedCurrency:CeloGold exchange rate + regAdd *RegisteredAddresses + iEvmH *InternalEVMHandler } -func (co *CurrencyOperator) getExchangeRate(currency *common.Address) (*exchangeRate, error) { +// Returns the price of gold in the provided currency. +func (pc *PriceComparator) getExchangeRate(currency *common.Address) (*big.Int, *big.Int, error) { if currency == nil { - return &exchangeRate{cgExchangeRateNum, cgExchangeRateDen}, nil + return cgExchangeRateNum, cgExchangeRateDen, nil } else { - co.currencyOperatorMu.RLock() - defer co.currencyOperatorMu.RUnlock() - if exchangeRate, ok := co.exchangeRates[*currency]; !ok { - return nil, errExchangeRateCacheMiss + if exchangeRate, ok := pc.exchangeRates[*currency]; !ok { + return nil, nil, errExchangeRateCacheMiss } else { - return exchangeRate, nil + return exchangeRate.Numerator, exchangeRate.Denominator, nil } } } -func (co *CurrencyOperator) ConvertToGold(val *big.Int, currencyFrom *common.Address) (*big.Int, error) { - celoGoldAddress := co.regAdd.GetRegisteredAddress(params.GoldTokenRegistryId) - if currencyFrom == nil || currencyFrom == celoGoldAddress { - return val, nil - } - return co.Convert(val, currencyFrom, celoGoldAddress) -} - -// NOTE (jarmg 4/24/18): values are rounded down which can cause -// an estimate to be off by 1 (at most) -func (co *CurrencyOperator) Convert(val *big.Int, currencyFrom *common.Address, currencyTo *common.Address) (*big.Int, error) { - exchangeRateFrom, err1 := co.getExchangeRate(currencyFrom) - exchangeRateTo, err2 := co.getExchangeRate(currencyTo) - - if err1 != nil || err2 != nil { - log.Error("CurrencyOperator.Convert - Error in retreiving currency exchange rates") - if err1 != nil { - return nil, err1 - } - if err2 != nil { - return nil, err2 - } - } - - // Given value of val and rates n1/d1 and n2/d2 the function below does - // (val * n1 * d2) / (d1 * n2) - numerator := new(big.Int).Mul(val, new(big.Int).Mul(exchangeRateFrom.Numerator, exchangeRateTo.Denominator)) - denominator := new(big.Int).Mul(exchangeRateFrom.Denominator, exchangeRateTo.Numerator) - return new(big.Int).Div(numerator, denominator), nil -} - -func (co *CurrencyOperator) Cmp(val1 *big.Int, currency1 *common.Address, val2 *big.Int, currency2 *common.Address) int { +func (pc *PriceComparator) Cmp(val1 *big.Int, currency1 *common.Address, val2 *big.Int, currency2 *common.Address) int { if currency1 == currency2 { return val1.Cmp(val2) } - exchangeRate1, err1 := co.getExchangeRate(currency1) - exchangeRate2, err2 := co.getExchangeRate(currency2) + exchangeRate1Num, exchangeRate1Den, err1 := pc.getExchangeRate(currency1) + exchangeRate2Num, exchangeRate2Den, err2 := pc.getExchangeRate(currency2) if err1 != nil || err2 != nil { currency1Output := "nil" @@ -184,37 +151,35 @@ func (co *CurrencyOperator) Cmp(val1 *big.Int, currency1 *common.Address, val2 * } // Below code block is basically evaluating this comparison: - // val1 * exchangeRate1.Numerator/exchangeRate1.Denominator < val2 * exchangeRate2.Numerator/exchangeRate2.Denominator + // val1 / exchangeRate1Num/exchangeRate1Den < val2 / exchangeRate2Num/exchangeRate2Den // It will transform that comparison to this, to remove having to deal with fractional values. - // val1 * exchangeRate1.Numerator * exchangeRate2.Denominator < val2 * exchangeRate2.Numerator * exchangeRate1.Denominator - leftSide := new(big.Int).Mul(val1, new(big.Int).Mul(exchangeRate1.Numerator, exchangeRate2.Denominator)) - rightSide := new(big.Int).Mul(val2, new(big.Int).Mul(exchangeRate2.Numerator, exchangeRate1.Denominator)) + // val1 * exchangeRate2Num * exchangeRate1Den < val2 * exchangeRate1Num * exchangeRate2Den + leftSide := new(big.Int).Mul(val1, new(big.Int).Mul(exchangeRate2Num, exchangeRate1Den)) + rightSide := new(big.Int).Mul(val2, new(big.Int).Mul(exchangeRate1Num, exchangeRate2Den)) return leftSide.Cmp(rightSide) } // This function will retrieve the exchange rates from the SortedOracles contract and cache them. // SortedOracles must have a function with the following signature: // "function medianRate(address)" -func (co *CurrencyOperator) retrieveExchangeRates() { - gasCurrencyAddresses := co.gcWl.retrieveWhitelist() - log.Trace("CurrencyOperator.retrieveExchangeRates called", "gasCurrencyAddresses", gasCurrencyAddresses) +func (pc *PriceComparator) retrieveExchangeRates() { + gasCurrencyAddresses := pc.gcWl.retrieveWhitelist() + log.Trace("PriceComparator.retrieveExchangeRates called", "gasCurrencyAddresses", gasCurrencyAddresses) - sortedOraclesAddress := co.regAdd.GetRegisteredAddress(params.SortedOraclesRegistryId) + sortedOraclesAddress := pc.regAdd.GetRegisteredAddress(params.SortedOraclesRegistryId) if sortedOraclesAddress == nil { log.Error("Can't get the sortedOracles smart contract address from the registry") return } - celoGoldAddress := co.regAdd.GetRegisteredAddress(params.GoldTokenRegistryId) + celoGoldAddress := pc.regAdd.GetRegisteredAddress(params.GoldTokenRegistryId) if celoGoldAddress == nil { log.Error("Can't get the celo gold smart contract address from the registry") return } - co.currencyOperatorMu.Lock() - for _, gasCurrencyAddress := range gasCurrencyAddresses { if gasCurrencyAddress == *celoGoldAddress { continue @@ -222,52 +187,49 @@ func (co *CurrencyOperator) retrieveExchangeRates() { var returnArray [2]*big.Int - log.Trace("CurrencyOperator.retrieveExchangeRates - Calling medianRate", "sortedOraclesAddress", sortedOraclesAddress.Hex(), + log.Trace("PriceComparator.retrieveExchangeRates - Calling medianRate", "sortedOraclesAddress", sortedOraclesAddress.Hex(), "gas currency", gasCurrencyAddress.Hex()) - if leftoverGas, err := co.iEvmH.MakeCall(*sortedOraclesAddress, medianRateFuncABI, "medianRate", []interface{}{gasCurrencyAddress}, &returnArray, 20000, nil, nil); err != nil { - log.Error("CurrencyOperator.retrieveExchangeRates - SortedOracles.medianRate invocation error", "leftoverGas", leftoverGas, "err", err) + if leftoverGas, err := pc.iEvmH.MakeCall(*sortedOraclesAddress, medianRateFuncABI, "medianRate", []interface{}{gasCurrencyAddress}, &returnArray, 20000, nil, nil); err != nil { + log.Error("PriceComparator.retrieveExchangeRates - SortedOracles.medianRate invocation error", "leftoverGas", leftoverGas, "err", err) continue } else { - log.Trace("CurrencyOperator.retrieveExchangeRates - SortedOracles.medianRate invocation success", "returnArray", returnArray, "leftoverGas", leftoverGas) + log.Trace("PriceComparator.retrieveExchangeRates - SortedOracles.medianRate invocation success", "returnArray", returnArray, "leftoverGas", leftoverGas) - if _, ok := co.exchangeRates[gasCurrencyAddress]; !ok { - co.exchangeRates[gasCurrencyAddress] = &exchangeRate{} + if _, ok := pc.exchangeRates[gasCurrencyAddress]; !ok { + pc.exchangeRates[gasCurrencyAddress] = &exchangeRate{} } - co.exchangeRates[gasCurrencyAddress].Numerator = returnArray[0] - co.exchangeRates[gasCurrencyAddress].Denominator = returnArray[1] + pc.exchangeRates[gasCurrencyAddress].Numerator = returnArray[0] + pc.exchangeRates[gasCurrencyAddress].Denominator = returnArray[1] } } - - co.currencyOperatorMu.Unlock() } -// TODO (jarmg 5/30/18): Change this to cache based on block number -func (co *CurrencyOperator) mainLoop() { - co.retrieveExchangeRates() +func (pc *PriceComparator) mainLoop() { + pc.retrieveExchangeRates() ticker := time.NewTicker(10 * time.Second) for range ticker.C { - co.retrieveExchangeRates() + pc.retrieveExchangeRates() } } -func NewCurrencyOperator(gcWl *GasCurrencyWhitelist, regAdd *RegisteredAddresses, iEvmH *InternalEVMHandler) *CurrencyOperator { +func NewPriceComparator(gcWl *GasCurrencyWhitelist, regAdd *RegisteredAddresses, iEvmH *InternalEVMHandler) *PriceComparator { exchangeRates := make(map[common.Address]*exchangeRate) - co := &CurrencyOperator{ + pc := &PriceComparator{ gcWl: gcWl, exchangeRates: exchangeRates, regAdd: regAdd, iEvmH: iEvmH, } - if co.gcWl != nil { - go co.mainLoop() + if pc.gcWl != nil { + go pc.mainLoop() } - return co + return pc } // This function will retrieve the balance of an ERC20 token. diff --git a/core/evm.go b/core/evm.go index 0fb18e819934..46371318c0ac 100644 --- a/core/evm.go +++ b/core/evm.go @@ -29,24 +29,14 @@ import ( "github.com/ethereum/go-ethereum/params" ) -// ChainContext supports retrieving chain data and consensus parameters -// from the block chain to be used during transaction processing. +// ChainContext supports retrieving headers and consensus parameters from the +// current blockchain to be used during transaction processing. type ChainContext interface { - // Engine retrieves the blockchain's consensus engine. + // Engine retrieves the chain's consensus engine. Engine() consensus.Engine // GetHeader returns the hash corresponding to their hash. GetHeader(common.Hash, uint64) *types.Header - - // GetVMConfig returns the node's vm configuration - GetVMConfig() *vm.Config - - CurrentHeader() *types.Header - - State() (*state.StateDB, error) - - // Config returns the blockchain's chain configuration - Config() *params.ChainConfig } // NewEVMContext creates a new context for use in the EVM. @@ -148,8 +138,9 @@ func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int) // An EVM handler to make calls to smart contracts from within geth type InternalEVMHandler struct { - chain ChainContext - regAdd *RegisteredAddresses + blockchain *BlockChain // Used to construct the EVM object needed to make the call the medianator contract + chainConfig *params.ChainConfig // The config object of the eth object + regAdd *RegisteredAddresses } func (iEvmH *InternalEVMHandler) MakeCall(scAddress common.Address, abi abi.ABI, funcName string, args []interface{}, returnObj interface{}, gas uint64, header *types.Header, state *state.StateDB) (uint64, error) { @@ -157,15 +148,14 @@ func (iEvmH *InternalEVMHandler) MakeCall(scAddress common.Address, abi abi.ABI, // there are times (e.g. retrieving the set of validators when an epoch ends) that we need // to call the evm using the currently mined block. In that case, the header and state params // will be non nil. - log.Trace("InternalEVMHandler.MakeCall called") if header == nil { - header = iEvmH.chain.CurrentHeader() + header = iEvmH.blockchain.CurrentBlock().Header() } if state == nil { var err error - state, err = iEvmH.chain.State() + state, err = iEvmH.blockchain.StateAt(header.Root) if err != nil { log.Error("Error in retrieving the state from the blockchain") return 0, err @@ -175,8 +165,8 @@ func (iEvmH *InternalEVMHandler) MakeCall(scAddress common.Address, abi abi.ABI, // The EVM Context requires a msg, but the actual field values don't really matter for this case. // Putting in zero values. msg := types.NewMessage(common.HexToAddress("0x0"), nil, 0, common.Big0, 0, common.Big0, nil, nil, []byte{}, false) - context := NewEVMContext(msg, header, iEvmH.chain, nil, iEvmH.regAdd) - evm := vm.NewEVM(context, state, iEvmH.chain.Config(), *iEvmH.chain.GetVMConfig()) + context := NewEVMContext(msg, header, iEvmH.blockchain, nil, iEvmH.regAdd) + evm := vm.NewEVM(context, state, iEvmH.chainConfig, *iEvmH.blockchain.GetVMConfig()) zeroCaller := vm.AccountRef(common.HexToAddress("0x0")) return evm.ABIStaticCall(zeroCaller, scAddress, abi, funcName, args, returnObj, gas) @@ -186,9 +176,11 @@ func (iEvmH *InternalEVMHandler) SetRegisteredAddresses(regAdd *RegisteredAddres iEvmH.regAdd = regAdd } -func NewInternalEVMHandler(chain ChainContext) *InternalEVMHandler { +func NewInternalEVMHandler(chainConfig *params.ChainConfig, blockchain *BlockChain) *InternalEVMHandler { iEvmH := InternalEVMHandler{ - chain: chain, + blockchain: blockchain, + chainConfig: chainConfig, } + return &iEvmH } diff --git a/core/registeredAddresses.go b/core/registeredAddresses.go index f16a6be71c90..36741463dd21 100644 --- a/core/registeredAddresses.go +++ b/core/registeredAddresses.go @@ -50,7 +50,7 @@ const ( var ( registrySmartContractAddress = common.HexToAddress("0x000000000000000000000000000000000000ce10") - registeredContractIds = []string{params.GoldTokenRegistryId, params.AddressBasedEncryptionRegistryId, params.ReserveRegistryId, params.SortedOraclesRegistryId, params.GasCurrencyWhitelistRegistryId, params.ValidatorsRegistryId, params.GasPriceOracleRegistryId} + registeredContractIds = []string{params.GoldTokenRegistryId, params.AddressBasedEncryptionRegistryId, params.ReserveRegistryId, params.SortedOraclesRegistryId, params.GasCurrencyWhitelistRegistryId, params.ValidatorsRegistryId} getAddressForFuncABI, _ = abi.JSON(strings.NewReader(getAddressForABI)) zeroAddress = common.Address{} ) @@ -93,15 +93,10 @@ func (ra *RegisteredAddresses) RefreshAddresses() { } func (ra *RegisteredAddresses) GetRegisteredAddress(registryId string) *common.Address { - if len(ra.registeredAddresses) == 0 { // This refresh is for a light client that failed to refresh (did not have a network connection) during node construction - ra.RefreshAddresses() - } - ra.registeredAddressesMu.RLock() defer ra.registeredAddressesMu.RUnlock() if address, ok := ra.registeredAddresses[registryId]; !ok { - log.Error("RegisteredAddresses.GetRegisteredAddress - Error in address retrieval for ", "registry", registryId) return nil } else { return &address diff --git a/core/tx_list.go b/core/tx_list.go index 328f5c9462ee..d962ec40eb74 100644 --- a/core/tx_list.go +++ b/core/tx_list.go @@ -411,16 +411,16 @@ type txPricedList struct { nonNilCurrencyHeaps map[common.Address]*priceHeap // Heap of prices of all the stored non-nil currency transactions nilCurrencyHeap *priceHeap // Heap of prices of all the stored nil currency transactions stales int // Number of stale price points to (re-heap trigger) - co *CurrencyOperator // Comparator object used to compare prices that are using different currencies + pc *PriceComparator // Comparator object used to compare prices that are using different currencies } // newTxPricedList creates a new price-sorted transaction heap. -func newTxPricedList(all *txLookup, co *CurrencyOperator) *txPricedList { +func newTxPricedList(all *txLookup, pc *PriceComparator) *txPricedList { return &txPricedList{ all: all, nonNilCurrencyHeaps: make(map[common.Address]*priceHeap), nilCurrencyHeap: new(priceHeap), - co: co, + pc: pc, } } @@ -489,7 +489,7 @@ func (l *txPricedList) Cap(cgThreshold *big.Int, local *accountSet) types.Transa continue } - if l.co.Cmp(tx.GasPrice(), tx.GasCurrency(), cgThreshold, nil) >= 0 { + if l.pc.Cmp(tx.GasPrice(), tx.GasCurrency(), cgThreshold, nil) >= 0 { save = append(save, tx) break } @@ -531,7 +531,7 @@ func (l *txPricedList) Underpriced(tx *types.Transaction, local *accountSet) boo } cheapest := l.getMinPricedTx() - return l.co.Cmp(cheapest.GasPrice(), cheapest.GasCurrency(), tx.GasPrice(), tx.GasCurrency()) >= 0 + return l.pc.Cmp(cheapest.GasPrice(), cheapest.GasCurrency(), tx.GasPrice(), tx.GasCurrency()) >= 0 } // Discard finds a number of most underpriced transactions, removes them from the @@ -574,7 +574,7 @@ func (l *txPricedList) getHeapWithMinHead() (*priceHeap, *types.Transaction) { cheapestTxn = []*types.Transaction(*cheapestHeap)[0] } else { txn := []*types.Transaction(*priceHeap)[0] - if l.co.Cmp(cheapestTxn.GasPrice(), cheapestTxn.GasCurrency(), txn.GasPrice(), txn.GasCurrency()) < 0 { + if l.pc.Cmp(cheapestTxn.GasPrice(), cheapestTxn.GasCurrency(), txn.GasPrice(), txn.GasCurrency()) < 0 { cheapestHeap = priceHeap } } diff --git a/core/tx_pool.go b/core/tx_pool.go index d8c59f795ddf..54cf32f6deb0 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -246,14 +246,14 @@ type TxPool struct { homestead bool - co *CurrencyOperator + pc *PriceComparator gcWl *GasCurrencyWhitelist iEvmH *InternalEVMHandler } // NewTxPool creates a new transaction pool to gather, sort and filter inbound // transactions from the network. -func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain, co *CurrencyOperator, gcWl *GasCurrencyWhitelist, iEvmH *InternalEVMHandler) *TxPool { +func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain, pc *PriceComparator, gcWl *GasCurrencyWhitelist, iEvmH *InternalEVMHandler) *TxPool { // Sanitize the input to ensure no vulnerable gas prices are set config = (&config).sanitize() @@ -269,7 +269,7 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block all: newTxLookup(), chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize), gasPrice: new(big.Int).SetUint64(config.PriceLimit), - co: co, + pc: pc, gcWl: gcWl, iEvmH: iEvmH, } @@ -278,7 +278,7 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block log.Info("Setting new local account", "address", addr) pool.locals.add(addr) } - pool.priced = newTxPricedList(pool.all, pool.co) + pool.priced = newTxPricedList(pool.all, pool.pc) pool.reset(nil, chain.CurrentBlock().Header()) @@ -637,7 +637,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { // Drop non-local transactions under our own minimal accepted gas price local = local || pool.locals.contains(from) // account may be local even if the transaction arrived from the network - if !local && pool.co.Cmp(pool.gasPrice, nil, tx.GasPrice(), tx.GasCurrency()) > 0 { + if !local && pool.pc.Cmp(pool.gasPrice, nil, tx.GasPrice(), tx.GasCurrency()) > 0 { return ErrUnderpriced } // Ensure the transaction adheres to nonce ordering diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go index be050da1dcf5..2ff2a78cd801 100644 --- a/core/tx_pool_test.go +++ b/core/tx_pool_test.go @@ -97,8 +97,8 @@ func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} key, _ := crypto.GenerateKey() - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, pc, nil, nil) return pool, key } @@ -208,8 +208,8 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) { tx0 := transaction(0, 100000, key) tx1 := transaction(1, 100000, key) - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, pc, nil, nil) defer pool.Stop() nonce := pool.State().GetNonce(address) @@ -574,8 +574,8 @@ func TestTransactionPostponing(t *testing.T) { statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, pc, nil, nil) defer pool.Stop() // Create two test accounts to produce different gap profiles with @@ -794,8 +794,8 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) { config.NoLocals = nolocals config.GlobalQueue = config.AccountQueue*3 - 1 // reduce the queue limits to shorten test time (-1 to make it non divisible) - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(config, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(config, params.TestChainConfig, blockchain, pc, nil, nil) defer pool.Stop() // Create a number of test accounts and fund them (last one will be the local) @@ -883,8 +883,8 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { config.Lifetime = time.Second config.NoLocals = nolocals - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(config, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(config, params.TestChainConfig, blockchain, pc, nil, nil) defer pool.Stop() // Create two test accounts to ensure remotes expire but locals do not @@ -1037,8 +1037,8 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) { config := testTxPoolConfig config.GlobalSlots = config.AccountSlots * 10 - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(config, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(config, params.TestChainConfig, blockchain, pc, nil, nil) defer pool.Stop() // Create a number of test accounts and fund them @@ -1086,8 +1086,8 @@ func TestTransactionCapClearsFromAll(t *testing.T) { config.AccountQueue = 2 config.GlobalSlots = 8 - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(config, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(config, params.TestChainConfig, blockchain, pc, nil, nil) defer pool.Stop() // Create a number of test accounts and fund them @@ -1119,8 +1119,8 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) { config := testTxPoolConfig config.GlobalSlots = 1 - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(config, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(config, params.TestChainConfig, blockchain, pc, nil, nil) defer pool.Stop() // Create a number of test accounts and fund them @@ -1165,8 +1165,8 @@ func TestTransactionPoolRepricing(t *testing.T) { statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, pc, nil, nil) defer pool.Stop() // Keep track of transaction events to ensure all executables get announced @@ -1287,8 +1287,8 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) { statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, pc, nil, nil) defer pool.Stop() // Create a number of test accounts and fund them @@ -1354,8 +1354,8 @@ func TestTransactionPoolUnderpricing(t *testing.T) { config.GlobalSlots = 2 config.GlobalQueue = 2 - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(config, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(config, params.TestChainConfig, blockchain, pc, nil, nil) defer pool.Stop() // Keep track of transaction events to ensure all executables get announced @@ -1461,8 +1461,8 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) { config.GlobalSlots = 128 config.GlobalQueue = 0 - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(config, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(config, params.TestChainConfig, blockchain, pc, nil, nil) defer pool.Stop() // Keep track of transaction events to ensure all executables get announced @@ -1524,8 +1524,8 @@ func TestTransactionReplacement(t *testing.T) { statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, pc, nil, nil) defer pool.Stop() // Keep track of transaction events to ensure all executables get announced @@ -1624,8 +1624,8 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { config.Journal = journal config.Rejournal = time.Second - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(config, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(config, params.TestChainConfig, blockchain, pc, nil, nil) // Create two test accounts to ensure remotes expire but locals do not local, _ := crypto.GenerateKey() @@ -1662,8 +1662,8 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) blockchain = &testBlockChain{statedb, 1000000, new(event.Feed)} - co = NewCurrencyOperator(nil, nil, nil) - pool = NewTxPool(config, params.TestChainConfig, blockchain, co, nil, nil) + pc = NewPriceComparator(nil, nil, nil) + pool = NewTxPool(config, params.TestChainConfig, blockchain, pc, nil, nil) pending, queued = pool.Stats() if queued != 0 { @@ -1689,8 +1689,8 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) blockchain = &testBlockChain{statedb, 1000000, new(event.Feed)} - co = NewCurrencyOperator(nil, nil, nil) - pool = NewTxPool(config, params.TestChainConfig, blockchain, co, nil, nil) + pc = NewPriceComparator(nil, nil, nil) + pool = NewTxPool(config, params.TestChainConfig, blockchain, pc, nil, nil) pending, queued = pool.Stats() if pending != 0 { @@ -1720,8 +1720,8 @@ func TestTransactionStatusCheck(t *testing.T) { statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - co := NewCurrencyOperator(nil, nil, nil) - pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, co, nil, nil) + pc := NewPriceComparator(nil, nil, nil) + pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, pc, nil, nil) defer pool.Stop() // Create the test accounts to check various transaction statuses with diff --git a/eth/api_backend.go b/eth/api_backend.go index 97ffee3a10ac..a633f8723608 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -198,7 +198,7 @@ func (b *EthAPIBackend) ProtocolVersion() int { } func (b *EthAPIBackend) SuggestPrice(ctx context.Context) (*big.Int, error) { - return gasprice.GetGasPrice(ctx, b.eth.iEvmH, b.eth.regAdd) + return b.gpo.SuggestPrice(ctx) } func (b *EthAPIBackend) ChainDb() ethdb.Database { diff --git a/eth/backend.go b/eth/backend.go index 814ae9c82c25..1603fd3d98bb 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -186,9 +186,9 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { config.TxPool.Journal = ctx.ResolvePath(config.TxPool.Journal) } - // Create an internalEVMHandler handler object that geth can use to make calls to smart contracts. - // Note that this should NOT be used when executing smart contract calls done via end user transactions. - eth.iEvmH = core.NewInternalEVMHandler(eth.blockchain) + // Create an internalEVMHandler handler object that geth can use to make calls to smart contracts. Note + // that this should NOT be used when executing smart contract calls done via end user transactions. + eth.iEvmH = core.NewInternalEVMHandler(eth.chainConfig, eth.blockchain) // Object used to retrieve and cache registered addresses from the Registry smart contract. eth.regAdd = core.NewRegisteredAddresses(eth.iEvmH) @@ -198,16 +198,16 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { eth.gcWl = core.NewGasCurrencyWhitelist(eth.regAdd, eth.iEvmH) // Object used to compare two different prices using any of the whitelisted gas currencies. - co := core.NewCurrencyOperator(eth.gcWl, eth.regAdd, eth.iEvmH) + pc := core.NewPriceComparator(eth.gcWl, eth.regAdd, eth.iEvmH) - eth.txPool = core.NewTxPool(config.TxPool, eth.chainConfig, eth.blockchain, co, eth.gcWl, eth.iEvmH) + eth.txPool = core.NewTxPool(config.TxPool, eth.chainConfig, eth.blockchain, pc, eth.gcWl, eth.iEvmH) eth.blockchain.Processor().SetGasCurrencyWhitelist(eth.gcWl) eth.blockchain.Processor().SetRegisteredAddresses(eth.regAdd) if eth.protocolManager, err = NewProtocolManager(eth.chainConfig, config.SyncMode, config.NetworkId, eth.eventMux, eth.txPool, eth.engine, eth.blockchain, chainDb, config.Whitelist); err != nil { return nil, err } - eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine, config.MinerRecommit, config.MinerGasFloor, config.MinerGasCeil, eth.isLocalBlock, config.MinerVerificationServiceUrl, config.MinerVerificationRewards, co) + eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine, config.MinerRecommit, config.MinerGasFloor, config.MinerGasCeil, eth.isLocalBlock, config.MinerVerificationServiceUrl, config.MinerVerificationRewards, pc) eth.miner.SetExtra(makeExtraData(config.MinerExtraData)) eth.APIBackend = &EthAPIBackend{eth, nil} @@ -215,7 +215,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { if gpoParams.Default == nil { gpoParams.Default = config.MinerGasPrice } - eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, gpoParams, co) + eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, gpoParams) return eth, nil } diff --git a/eth/gasprice/access_gasprice.go b/eth/gasprice/access_gasprice.go deleted file mode 100644 index 1ac715acff73..000000000000 --- a/eth/gasprice/access_gasprice.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2017 The Celo Authors -// This file is part of the celo library. -// -// The celo 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 celo 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 celo library. If not, see . - -package gasprice - -import ( - "context" - "errors" - "math/big" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/params" -) - -// TODO (jarmg 5/22/18): Store contract function ABIs in a central location -const ( - getGasPriceABIString = `[{ - "constant": true, - "inputs": [], - "name": "getGasPriceSuggestion", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }]` -) - -var ( - gasPriceOracleABI, _ = abi.JSON(strings.NewReader(getGasPriceABIString)) -) - -func GetGasPrice(ctx context.Context, iEvmH *core.InternalEVMHandler, regAdd *core.RegisteredAddresses) (*big.Int, error) { - - var gasPrice *big.Int - gasPriceOracleAddress := regAdd.GetRegisteredAddress(params.GasPriceOracleRegistryId) - - if gasPriceOracleAddress == nil { - return nil, errors.New("no gasprice oracle contract address found") - } - - _, err := iEvmH.MakeCall(*gasPriceOracleAddress, gasPriceOracleABI, "getGasPriceSuggestion", []interface{}{}, &gasPrice, 2000, nil, nil) - - return gasPrice, err -} diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index 620bf9676fa0..a0cbd6563bc2 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -23,10 +23,8 @@ import ( "sync" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/internal/ethapi" - "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" ) @@ -53,11 +51,10 @@ type Oracle struct { percentile int defaultPrice *big.Int alwaysZero bool - co *core.CurrencyOperator } // NewOracle returns a new oracle. -func NewOracle(backend ethapi.Backend, params Config, co *core.CurrencyOperator) *Oracle { +func NewOracle(backend ethapi.Backend, params Config) *Oracle { blocks := params.Blocks if blocks < 1 { blocks = 1 @@ -78,7 +75,6 @@ func NewOracle(backend ethapi.Backend, params Config, co *core.CurrencyOperator) percentile: percent, defaultPrice: params.Default, alwaysZero: params.AlwaysZero, - co: co, } } @@ -89,27 +85,29 @@ func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) { return big.NewInt(0), nil } - price := getCachedPrice(gpo, ctx) - if price != nil { - return price, nil + 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 } - return calculateGasSuggestion(gpo, ctx) -} -func calculateGasSuggestion(gpo *Oracle, ctx context.Context) (*big.Int, error) { gpo.fetchLock.Lock() defer gpo.fetchLock.Unlock() - // check if the cache was refreshed while we waited for the lock - price := getCachedPrice(gpo, ctx) - if price != nil { - return price, nil + // 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 } - head, _ := gpo.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber) - headHash := head.Hash() - lastPrice := gpo.lastPrice - blockNum := head.Number.Uint64() ch := make(chan getBlockPricesResult, gpo.checkBlocks) sent := 0 @@ -143,7 +141,7 @@ func calculateGasSuggestion(gpo *Oracle, ctx context.Context) (*big.Int, error) blockNum-- } } - price = gpo.defaultPrice + price := gpo.defaultPrice if len(blockPrices) > 0 { sort.Sort(bigIntArray(blockPrices)) price = blockPrices[(len(blockPrices)-1)*gpo.percentile/100] @@ -159,27 +157,17 @@ func calculateGasSuggestion(gpo *Oracle, ctx context.Context) (*big.Int, error) return price, nil } -// getCachedPrice is a private function which checks if the last gasPrice -// suggestion was pulled from the current block and, if so, returns it -func getCachedPrice(gpo *Oracle, ctx context.Context) *big.Int { - 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 - } - return 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) { @@ -190,25 +178,18 @@ func (gpo *Oracle) getBlockPrices(ctx context.Context, signer types.Signer, bloc } blockTxs := block.Transactions() - prices := make([]*big.Int, len(blockTxs)) + txs := make([]*types.Transaction, len(blockTxs)) + copy(txs, blockTxs) + sort.Sort(transactionsByGasPrice(txs)) - for _, tx := range blockTxs { + for _, tx := range txs { sender, err := types.Sender(signer, tx) if err == nil && sender != block.Coinbase() { - gpInGold, err := gpo.co.ConvertToGold(tx.GasPrice(), tx.GasCurrency()) - if err != nil { - log.Error("Error converting gas to gold", "error", err) - } else { - prices = append(prices, gpInGold) - } + ch <- getBlockPricesResult{tx.GasPrice(), nil} + return } } - if len(prices) == 0 { - ch <- getBlockPricesResult{nil, nil} - } else { - sort.Sort(bigIntArray(prices)) - ch <- getBlockPricesResult{prices[0], nil} - } + ch <- getBlockPricesResult{nil, nil} } type bigIntArray []*big.Int diff --git a/les/api_backend.go b/les/api_backend.go index 881a8af204d5..65d51e208c6e 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -40,6 +40,7 @@ import ( type LesApiBackend struct { eth *LightEthereum + gpo *gasprice.Oracle } func (b *LesApiBackend) ChainConfig() *params.ChainConfig { @@ -172,7 +173,7 @@ func (b *LesApiBackend) ProtocolVersion() int { } func (b *LesApiBackend) SuggestPrice(ctx context.Context) (*big.Int, error) { - return gasprice.GetGasPrice(ctx, b.eth.iEvmH, b.eth.regAdd) + return b.gpo.SuggestPrice(ctx) } func (b *LesApiBackend) ChainDb() ethdb.Database { diff --git a/les/backend.go b/les/backend.go index 1f82f701a7d9..da157062b0c4 100644 --- a/les/backend.go +++ b/les/backend.go @@ -33,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/filters" + "github.com/ethereum/go-ethereum/eth/gasprice" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/light" @@ -73,9 +74,6 @@ type LightEthereum struct { networkId uint64 netRPCService *ethapi.PublicNetAPI - regAdd *core.RegisteredAddresses - iEvmH *core.InternalEVMHandler - wg sync.WaitGroup } @@ -137,16 +135,6 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) { if leth.blockchain, err = light.NewLightChain(leth.odr, leth.chainConfig, leth.engine); err != nil { return nil, err } - - // Create an internalEVMHandler handler object that geth can use to make calls to smart contracts. - // Note: that this should NOT be used when executing smart contract calls done via end user transactions. - leth.iEvmH = core.NewInternalEVMHandler(leth.blockchain) - - // Object used to retrieve and cache registered addresses from the Registry smart contract. - leth.regAdd = core.NewRegisteredAddresses(leth.iEvmH) - leth.iEvmH.SetRegisteredAddresses(leth.regAdd) - leth.regAdd.RefreshAddresses() - // Note: AddChildIndexer starts the update process for the child leth.bloomIndexer.AddChildIndexer(leth.bloomTrieIndexer) leth.chtIndexer.Start(leth.blockchain) @@ -163,7 +151,12 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) { if leth.protocolManager, err = NewProtocolManager(leth.chainConfig, light.DefaultClientIndexerConfig, syncMode, config.NetworkId, leth.eventMux, leth.engine, leth.peers, leth.blockchain, nil, chainDb, leth.odr, leth.relay, leth.serverPool, quitSync, &leth.wg, config.Etherbase); err != nil { return nil, err } - leth.ApiBackend = &LesApiBackend{leth} + leth.ApiBackend = &LesApiBackend{leth, nil} + gpoParams := config.GPO + if gpoParams.Default == nil { + gpoParams.Default = config.MinerGasPrice + } + leth.ApiBackend.gpo = gasprice.NewOracle(leth.ApiBackend, gpoParams) return leth, nil } diff --git a/les/handler_test.go b/les/handler_test.go index fbdee28a2733..e3567257f706 100644 --- a/les/handler_test.go +++ b/les/handler_test.go @@ -498,8 +498,8 @@ func TestTransactionStatusLes2(t *testing.T) { chain := pm.blockchain.(*core.BlockChain) config := core.DefaultTxPoolConfig config.Journal = "" - co := core.NewCurrencyOperator(nil, nil, nil) - txpool := core.NewTxPool(config, params.TestChainConfig, chain, co, nil, nil) + pc := core.NewPriceComparator(nil, nil, nil) + txpool := core.NewTxPool(config, params.TestChainConfig, chain, pc, nil, nil) pm.txpool = txpool peer, _ := newTestPeer(t, "peer", 2, pm, true) defer peer.close() diff --git a/light/lightchain.go b/light/lightchain.go index ed0c9fbeda77..9b650ee2c6d1 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -31,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" @@ -214,7 +213,7 @@ func (bc *LightChain) Genesis() *types.Block { // State returns a new mutable state based on the current HEAD block. func (bc *LightChain) State() (*state.StateDB, error) { - return NewState(context.Background(), bc.CurrentHeader(), bc.odr), nil // TODO: Any issues with using context.Background() here? + return nil, errors.New("not implemented, needs client/server interface split") } // GetBody retrieves a block body (transactions and uncles) from the database @@ -476,10 +475,6 @@ func (self *LightChain) GetHeaderByNumberOdr(ctx context.Context, number uint64) return GetHeaderByNumber(ctx, self.odr, number) } -func (self *LightChain) GetVMConfig() *vm.Config { - return &vm.Config{} -} - // Config retrieves the header chain's chain configuration. func (self *LightChain) Config() *params.ChainConfig { return self.hc.Config() } diff --git a/miner/miner.go b/miner/miner.go index de76b351667a..41ea831abb27 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -57,13 +57,13 @@ type Miner struct { shouldStart int32 // should start indicates whether we should start after sync } -func New(eth Backend, config *params.ChainConfig, mux *event.TypeMux, engine consensus.Engine, recommit time.Duration, gasFloor, gasCeil uint64, isLocalBlock func(block *types.Block) bool, verificationService string, verificationRewards common.Address, co *core.CurrencyOperator) *Miner { +func New(eth Backend, config *params.ChainConfig, mux *event.TypeMux, engine consensus.Engine, recommit time.Duration, gasFloor, gasCeil uint64, isLocalBlock func(block *types.Block) bool, verificationService string, verificationRewards common.Address, pc *core.PriceComparator) *Miner { miner := &Miner{ eth: eth, mux: mux, engine: engine, exitCh: make(chan struct{}), - worker: newWorker(config, engine, eth, mux, recommit, gasFloor, gasCeil, isLocalBlock, verificationService, verificationRewards, co), + worker: newWorker(config, engine, eth, mux, recommit, gasFloor, gasCeil, isLocalBlock, verificationService, verificationRewards, pc), canStart: 1, } go miner.update() diff --git a/miner/worker.go b/miner/worker.go index 20cf186a28b6..573ea5a5fe15 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -186,10 +186,10 @@ type worker struct { lastBlockVerified uint64 // Transaction processing - co *core.CurrencyOperator + pc *core.PriceComparator } -func newWorker(config *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, recommit time.Duration, gasFloor, gasCeil uint64, isLocalBlock func(*types.Block) bool, verificationService string, verificationRewards common.Address, co *core.CurrencyOperator) *worker { +func newWorker(config *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, recommit time.Duration, gasFloor, gasCeil uint64, isLocalBlock func(*types.Block) bool, verificationService string, verificationRewards common.Address, pc *core.PriceComparator) *worker { worker := &worker{ config: config, engine: engine, @@ -215,7 +215,7 @@ func newWorker(config *params.ChainConfig, engine consensus.Engine, eth Backend, startCh: make(chan struct{}, 1), resubmitIntervalCh: make(chan time.Duration), resubmitAdjustCh: make(chan *intervalAdjust, resubmitAdjustChanSize), - co: co, + pc: pc, } // Subscribe NewTxsEvent for tx pool worker.txsSub = eth.TxPool().SubscribeNewTxsEvent(worker.txsCh) @@ -322,7 +322,7 @@ func (w *worker) close() { } func (w *worker) txCmp(tx1 *types.Transaction, tx2 *types.Transaction) int { - return w.co.Cmp(tx1.GasPrice(), tx1.GasCurrency(), tx2.GasPrice(), tx2.GasCurrency()) + return w.pc.Cmp(tx1.GasPrice(), tx1.GasCurrency(), tx2.GasPrice(), tx2.GasCurrency()) } // newWorkLoop is a standalone goroutine to submit new mining work upon received events. diff --git a/miner/worker_test.go b/miner/worker_test.go index 025d2e48417f..41f4143e2cf3 100644 --- a/miner/worker_test.go +++ b/miner/worker_test.go @@ -120,8 +120,8 @@ func newTestWorkerBackend(t *testing.T, chainConfig *params.ChainConfig, engine genesis := gspec.MustCommit(db) chain, _ := core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil) - co := core.NewCurrencyOperator(nil, nil, nil) - txpool := core.NewTxPool(testTxPoolConfig, chainConfig, chain, co, nil, nil) + pc := core.NewPriceComparator(nil, nil, nil) + txpool := core.NewTxPool(testTxPoolConfig, chainConfig, chain, pc, nil, nil) // Generate a small n-block chain and an uncle block for it if n > 0 { @@ -166,8 +166,8 @@ func newTestWorker(t *testing.T, chainConfig *params.ChainConfig, engine consens if shouldAddPendingTxs { backend.txPool.AddLocals(pendingTxs) } - co := core.NewCurrencyOperator(nil, nil, nil) - w := newWorker(chainConfig, engine, backend, new(event.TypeMux), time.Second, params.GenesisGasLimit, params.GenesisGasLimit, nil, testVerificationService, testVerificationRewardsAddress, co) + pc := core.NewPriceComparator(nil, nil, nil) + w := newWorker(chainConfig, engine, backend, new(event.TypeMux), time.Second, params.GenesisGasLimit, params.GenesisGasLimit, nil, testVerificationService, testVerificationRewardsAddress, pc) w.setEtherbase(testBankAddress) return w, backend } diff --git a/params/protocol_params.go b/params/protocol_params.go index b83660ff8ebb..4d9430b2a874 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -101,7 +101,6 @@ const ( SortedOraclesRegistryId = "SortedOracles" GasCurrencyWhitelistRegistryId = "GasCurrencyWhitelist" ValidatorsRegistryId = "Validators" - GasPriceOracleRegistryId = "GasPriceOracle" ) var (