de39513ced
Until this commit, when sending an RPC request that called `NewEVM`, a blank `vm.Config` would be taken so as to set some options, based on the default configuration. If some extra configuration switches were passed to the blockchain, those would be ignored. This PR adds a function to get the config from the blockchain, and this is what is now used for RPC calls. Some subsequent changes need to be made, see https://github.com/ethereum/go-ethereum/pull/17955#pullrequestreview-182237244 for the details of the discussion.
203 lines
6.7 KiB
Go
203 lines
6.7 KiB
Go
// Copyright 2016 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 les
|
|
|
|
import (
|
|
"context"
|
|
"math/big"
|
|
|
|
"github.com/ethereum/go-ethereum/accounts"
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/ethereum/go-ethereum/common/math"
|
|
"github.com/ethereum/go-ethereum/core"
|
|
"github.com/ethereum/go-ethereum/core/bloombits"
|
|
"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/eth/downloader"
|
|
"github.com/ethereum/go-ethereum/eth/gasprice"
|
|
"github.com/ethereum/go-ethereum/ethdb"
|
|
"github.com/ethereum/go-ethereum/event"
|
|
"github.com/ethereum/go-ethereum/light"
|
|
"github.com/ethereum/go-ethereum/params"
|
|
"github.com/ethereum/go-ethereum/rpc"
|
|
)
|
|
|
|
type LesApiBackend struct {
|
|
eth *LightEthereum
|
|
gpo *gasprice.Oracle
|
|
}
|
|
|
|
func (b *LesApiBackend) ChainConfig() *params.ChainConfig {
|
|
return b.eth.chainConfig
|
|
}
|
|
|
|
func (b *LesApiBackend) CurrentBlock() *types.Block {
|
|
return types.NewBlockWithHeader(b.eth.BlockChain().CurrentHeader())
|
|
}
|
|
|
|
func (b *LesApiBackend) SetHead(number uint64) {
|
|
b.eth.protocolManager.downloader.Cancel()
|
|
b.eth.blockchain.SetHead(number)
|
|
}
|
|
|
|
func (b *LesApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
|
|
if blockNr == rpc.LatestBlockNumber || blockNr == rpc.PendingBlockNumber {
|
|
return b.eth.blockchain.CurrentHeader(), nil
|
|
}
|
|
return b.eth.blockchain.GetHeaderByNumberOdr(ctx, uint64(blockNr))
|
|
}
|
|
|
|
func (b *LesApiBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
|
|
return b.eth.blockchain.GetHeaderByHash(hash), nil
|
|
}
|
|
|
|
func (b *LesApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) {
|
|
header, err := b.HeaderByNumber(ctx, blockNr)
|
|
if header == nil || err != nil {
|
|
return nil, err
|
|
}
|
|
return b.GetBlock(ctx, header.Hash())
|
|
}
|
|
|
|
func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
|
|
header, err := b.HeaderByNumber(ctx, blockNr)
|
|
if header == nil || err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return light.NewState(ctx, header, b.eth.odr), header, nil
|
|
}
|
|
|
|
func (b *LesApiBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) {
|
|
return b.eth.blockchain.GetBlockByHash(ctx, blockHash)
|
|
}
|
|
|
|
func (b *LesApiBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
|
|
if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil {
|
|
return light.GetBlockReceipts(ctx, b.eth.odr, hash, *number)
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
func (b *LesApiBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
|
|
if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil {
|
|
return light.GetBlockLogs(ctx, b.eth.odr, hash, *number)
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
func (b *LesApiBackend) GetTd(hash common.Hash) *big.Int {
|
|
return b.eth.blockchain.GetTdByHash(hash)
|
|
}
|
|
|
|
func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) {
|
|
state.SetBalance(msg.From(), math.MaxBig256)
|
|
context := core.NewEVMContext(msg, header, b.eth.blockchain, nil)
|
|
return vm.NewEVM(context, state, b.eth.chainConfig, vm.Config{}), state.Error, nil
|
|
}
|
|
|
|
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
|
return b.eth.txPool.Add(ctx, signedTx)
|
|
}
|
|
|
|
func (b *LesApiBackend) RemoveTx(txHash common.Hash) {
|
|
b.eth.txPool.RemoveTx(txHash)
|
|
}
|
|
|
|
func (b *LesApiBackend) GetPoolTransactions() (types.Transactions, error) {
|
|
return b.eth.txPool.GetTransactions()
|
|
}
|
|
|
|
func (b *LesApiBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction {
|
|
return b.eth.txPool.GetTransaction(txHash)
|
|
}
|
|
|
|
func (b *LesApiBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
|
|
return b.eth.txPool.GetNonce(ctx, addr)
|
|
}
|
|
|
|
func (b *LesApiBackend) Stats() (pending int, queued int) {
|
|
return b.eth.txPool.Stats(), 0
|
|
}
|
|
|
|
func (b *LesApiBackend) TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) {
|
|
return b.eth.txPool.Content()
|
|
}
|
|
|
|
func (b *LesApiBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
|
|
return b.eth.txPool.SubscribeNewTxsEvent(ch)
|
|
}
|
|
|
|
func (b *LesApiBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
|
|
return b.eth.blockchain.SubscribeChainEvent(ch)
|
|
}
|
|
|
|
func (b *LesApiBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription {
|
|
return b.eth.blockchain.SubscribeChainHeadEvent(ch)
|
|
}
|
|
|
|
func (b *LesApiBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription {
|
|
return b.eth.blockchain.SubscribeChainSideEvent(ch)
|
|
}
|
|
|
|
func (b *LesApiBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
|
|
return b.eth.blockchain.SubscribeLogsEvent(ch)
|
|
}
|
|
|
|
func (b *LesApiBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
|
|
return b.eth.blockchain.SubscribeRemovedLogsEvent(ch)
|
|
}
|
|
|
|
func (b *LesApiBackend) Downloader() *downloader.Downloader {
|
|
return b.eth.Downloader()
|
|
}
|
|
|
|
func (b *LesApiBackend) ProtocolVersion() int {
|
|
return b.eth.LesVersion() + 10000
|
|
}
|
|
|
|
func (b *LesApiBackend) SuggestPrice(ctx context.Context) (*big.Int, error) {
|
|
return b.gpo.SuggestPrice(ctx)
|
|
}
|
|
|
|
func (b *LesApiBackend) ChainDb() ethdb.Database {
|
|
return b.eth.chainDb
|
|
}
|
|
|
|
func (b *LesApiBackend) EventMux() *event.TypeMux {
|
|
return b.eth.eventMux
|
|
}
|
|
|
|
func (b *LesApiBackend) AccountManager() *accounts.Manager {
|
|
return b.eth.accountManager
|
|
}
|
|
|
|
func (b *LesApiBackend) BloomStatus() (uint64, uint64) {
|
|
if b.eth.bloomIndexer == nil {
|
|
return 0, 0
|
|
}
|
|
sections, _, _ := b.eth.bloomIndexer.Sections()
|
|
return params.BloomBitsBlocksClient, sections
|
|
}
|
|
|
|
func (b *LesApiBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) {
|
|
for i := 0; i < bloomFilterThreads; i++ {
|
|
go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests)
|
|
}
|
|
}
|