Add signers and finality to block status rpc api.

This commit is contained in:
parmmarrushabh 2018-10-27 16:28:04 +05:30
parent 17f9e27d8c
commit dccf2ca3e9
12 changed files with 126 additions and 81 deletions

View file

@ -358,7 +358,7 @@ func startNode(ctx *cli.Context, stack *node.Node) {
// get masternodes information from smart contract
client, err := ethclient.Dial(stack.IPCEndpoint())
if err != nil {
utils.Fatalf("Fail to connect RPC: %v", err)
utils.Fatalf("Fail to connect IPC: %v", err)
}
addr := common.HexToAddress(common.MasternodeVotingSMC)
validator, err := validatorContract.NewXDCValidator(addr, client)

View file

@ -397,11 +397,7 @@ func position(list []common.Address, x common.Address) int {
func (c *Clique) GetMasternodes(chain consensus.ChainReader, header *types.Header) []common.Address {
lastCheckpointNumber := header.Number.Uint64() - (header.Number.Uint64() % c.config.Epoch)
preCheckpointHeader := chain.GetHeaderByNumber(lastCheckpointNumber)
masternodes := make([]common.Address, (len(preCheckpointHeader.Extra)-extraVanity-extraSeal)/common.AddressLength)
for i := 0; i < len(masternodes); i++ {
copy(masternodes[i][:], preCheckpointHeader.Extra[extraVanity+i*common.AddressLength:])
}
return masternodes
return c.GetMasternodesFromCheckpointHeader(preCheckpointHeader)
}
func (c *Clique) GetPeriod() uint64 { return c.config.Period }
@ -718,10 +714,9 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, stop <-ch
if err != nil {
return nil, err
}
masternodes := []common.Address{}
if _, authorized := snap.Signers[signer]; !authorized {
valid := false
masternodes = c.GetMasternodes(chain, header)
masternodes := c.GetMasternodes(chain, header)
for _, m := range masternodes {
if m == signer {
valid = true
@ -736,7 +731,7 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, stop <-ch
for seen, recent := range snap.Recents {
if recent == signer {
// Signer is among recents, only wait if the current block doesn't shift it out
if limit := uint64(len(masternodes)/2 + 1); number < limit || seen > number-limit {
if limit := uint64(len(snap.Signers)/2 + 1); number < limit || seen > number-limit {
log.Info("Signed recently, must wait for others")
<-stop
return nil, nil
@ -803,4 +798,13 @@ func (c *Clique) APIs(chain consensus.ChainReader) []rpc.API {
func (c *Clique) RecoverSigner(header *types.Header) (common.Address, error) {
return ecrecover(header, c.signatures)
}
// Get master nodes over extra data of previous checkpoint block.
func (c *Clique) GetMasternodesFromCheckpointHeader(preCheckpointHeader *types.Header) []common.Address {
masternodes := make([]common.Address, (len(preCheckpointHeader.Extra)-extraVanity-extraSeal)/common.AddressLength)
for i := 0; i < len(masternodes); i++ {
copy(masternodes[i][:], preCheckpointHeader.Extra[extraVanity+i*common.AddressLength:])
}
return masternodes
}

View file

@ -43,7 +43,7 @@ func TestBlockSigner(t *testing.T) {
byte0 := randomHash()
// Test sign.
tx, err := blockSigner.Sign(big.NewInt(50), byte0)
tx, err := blockSigner.Sign(big.NewInt(2), byte0)
if err != nil {
t.Fatalf("can't sign: %v", err)
}

View file

@ -17,8 +17,8 @@ contract BlockSigner {
function sign(uint256 _blockNumber, bytes32 _blockHash) external {
// consensus should validate all senders are validators, gas = 0
//require(block.number >= _blockNumber);
//require(block.number <= _blockNumber.add(epochNumber * 2));
require(block.number >= _blockNumber);
require(block.number <= _blockNumber.add(epochNumber * 2));
blocks[_blockNumber].push(_blockHash);
blockSigners[_blockHash].push(msg.sender);

View file

@ -19,7 +19,7 @@ import (
const BlockSignerABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_blockNumber\",\"type\":\"uint256\"},{\"name\":\"_blockHash\",\"type\":\"bytes32\"}],\"name\":\"sign\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_blockHash\",\"type\":\"bytes32\"}],\"name\":\"getSigners\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"epochNumber\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_epochNumber\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_signer\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"_blockHash\",\"type\":\"bytes32\"}],\"name\":\"Sign\",\"type\":\"event\"}]"
// BlockSignerBin is the compiled bytecode used for deploying new contracts.
const BlockSignerBin = `0x6060604052341561000f57600080fd5b60405160208061034083398101604052808051600255505061030a806100366000396000f3006060604052600436106100565763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663e341eaa4811461005b578063e7ec6aef14610076578063f4145a83146100df575b600080fd5b341561006657600080fd5b610074600435602435610104565b005b341561008157600080fd5b61008c6004356101f7565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156100cb5780820151838201526020016100b3565b505050509050019250505060405180910390f35b34156100ea57600080fd5b6100f261027c565b60405190815260200160405180910390f35b60008281526001602081905260409091208054909181016101258382610282565b506000918252602080832091909101839055828252819052604090208054600181016101518382610282565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff19163373ffffffffffffffffffffffffffffffffffffffff8116919091179091557f62855fa22e051687c32ac285857751f6d3f2c100c72756d8d30cb7ecb1f64f5490838360405173ffffffffffffffffffffffffffffffffffffffff909316835260208301919091526040808301919091526060909101905180910390a15050565b6101ff6102ab565b6000828152602081815260409182902080549092909182810201905190810160405280929190818152602001828054801561027057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610245575b50505050509050919050565b60025481565b8154818355818115116102a6576000838152602090206102a69181019083016102bd565b505050565b60206040519081016040526000815290565b6102db91905b808211156102d757600081556001016102c3565b5090565b905600a165627a7a72305820fd1c307716c14d8f8b179bb09b89555ec490e6b216e2c1018c7232361b947bc40029`
const BlockSignerBin = `0x608060405234801561001057600080fd5b506040516020806102c58339810160405251600255610291806100346000396000f3006080604052600436106100565763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663e341eaa4811461005b578063e7ec6aef14610078578063f4145a83146100e0575b600080fd5b34801561006757600080fd5b50610076600435602435610107565b005b34801561008457600080fd5b506100906004356101d2565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156100cc5781810151838201526020016100b4565b505050509050019250505060405180910390f35b3480156100ec57600080fd5b506100f5610249565b60408051918252519081900360200190f35b4382111561011457600080fd5b6002805461012a9184910263ffffffff61024f16565b43111561013657600080fd5b6000828152600160208181526040808420805480850182559085528285200185905584845283825280842080549384018155845292819020909101805473ffffffffffffffffffffffffffffffffffffffff191633908117909155825190815290810184905280820183905290517f62855fa22e051687c32ac285857751f6d3f2c100c72756d8d30cb7ecb1f64f549181900360600190a15050565b6000818152602081815260409182902080548351818402810184019094528084526060939283018282801561023d57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610212575b50505050509050919050565b60025481565b60008282018381101561025e57fe5b93925050505600a165627a7a72305820b035faa3fa77d5019e1705483157467de16d51fe08a7194c30e2586e42ca7ccb0029`
// DeployBlockSigner deploys a new Ethereum contract, binding an instance of BlockSigner to it.
func DeployBlockSigner(auth *bind.TransactOpts, backend bind.ContractBackend, _epochNumber *big.Int) (common.Address, *types.Transaction, *BlockSigner, error) {
@ -377,7 +377,7 @@ func (_BlockSigner *BlockSignerFilterer) WatchSign(opts *bind.WatchOpts, sink ch
const SafeMathABI = "[]"
// SafeMathBin is the compiled bytecode used for deploying new contracts.
const SafeMathBin = `0x604c602c600b82828239805160001a60731460008114601c57601e565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146060604052600080fd00a165627a7a72305820b9407d48ebc7efee5c9f08b3b3a957df2939281f5913225e8c1291f069b900490029`
const SafeMathBin = `0x604c602c600b82828239805160001a60731460008114601c57601e565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146080604052600080fd00a165627a7a72305820a3f63b465e1cf25f306b1eb1efefc8dac3c38993a7340f69d8b470c3bf599ff30029`
// DeploySafeMath deploys a new Ethereum contract, binding an instance of SafeMath to it.
func DeploySafeMath(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SafeMath, error) {
@ -532,4 +532,4 @@ func (_SafeMath *SafeMathTransactorRaw) Transfer(opts *bind.TransactOpts) (*type
// Transact invokes the (paid) contract method with params as input values.
func (_SafeMath *SafeMathTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _SafeMath.Contract.contract.Transact(opts, method, params...)
}
}

View file

@ -88,37 +88,6 @@ func TestSendTxSign(t *testing.T) {
t.Error("Tx sign for block validators not match")
}
}
// Unit test for reward checkpoint.
//rCheckpoint := uint64(5)
//chainReward := new(big.Int).SetUint64(15 * params.Ether)
//total := new(uint64)
//for i := uint64(0); i < 100; i++ {
// if i > 0 && i%rCheckpoint == 0 && i-rCheckpoint > 0 {
// _, err := GetRewardForCheckpoint(blockSignerAddr, i, rCheckpoint, backend, total)
// if err != nil {
// t.Errorf("Fail to get signers for reward checkpoint: %v", err)
// }
// }
//}
//
//signers := make(map[common.Address]*rewardLog)
//totalSigner := uint64(17)
//signers[common.HexToAddress("0x12f588d7d03bb269b382b842fc15d874e8c055a7")] = &rewardLog{5, new(big.Int).SetUint64(0)}
//signers[common.HexToAddress("0x1f9e122c0921a4504fc116d967baf7a7bf2604ef")] = &rewardLog{6, new(big.Int).SetUint64(0)}
//signers[common.HexToAddress("0xea489e4e673c25ff0614617ebe88efd853efe00c")] = &rewardLog{6, new(big.Int).SetUint64(0)}
//rewardSigners, err := CalculateRewardForSigner(chainReward, signers, totalSigner)
//if err != nil {
// t.Errorf("Fail to calculate reward for signers: %v", err)
//}
////t.Error("Reward", rewardSigners)
//rewards := new(big.Int)
//for _, reward := range rewardSigners {
// rewards.Add(rewards, reward)
//}
//if rewards.Cmp(new(big.Int).SetUint64(14999999999999999996)) != 0 {
// t.Errorf("Total reward not same reward checkpoint: %v - %v", chainReward, rewards)
//}
}
// Generate random string.

View file

@ -34,6 +34,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
@ -62,7 +63,6 @@ const (
// BlockChainVersion ensures that an incompatible database forces a resync from scratch.
BlockChainVersion = 3
)
// CacheConfig contains the configuration values for the trie caching/pruning
@ -129,7 +129,9 @@ type BlockChain struct {
validator Validator // block and state validator interface
vmConfig vm.Config
badBlocks *lru.Cache // Bad block cache
badBlocks *lru.Cache // Bad block cache
IPCEndpoint string
Client *ethclient.Client // Global ipc client instance.
}
// NewBlockChain returns a fully initialised block chain using information
@ -1194,7 +1196,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
}
// prepare set of masternodes for the next epoch
if (chain[i].NumberU64() % bc.chainConfig.Clique.Epoch) == (bc.chainConfig.Clique.Epoch - bc.chainConfig.Clique.Gap) {
M1Ch <- 1
M1Ch <- 1
}
}
}
@ -1243,7 +1245,6 @@ func (st *insertStats) report(chain []*types.Block, index int, cache common.Stor
context = append(context, []interface{}{"ignored", st.ignored}...)
}
log.Info("Imported new chain segment", context...)
*st = insertStats{startTime: now, lastIndex: index + 1}
}
}
@ -1571,4 +1572,19 @@ func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Su
// SubscribeLogsEvent registers a subscription of []*types.Log.
func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
return bc.scope.Track(bc.logsFeed.Subscribe(ch))
}
// Get current IPC Client.
func (bc *BlockChain) GetClient() (*ethclient.Client, error) {
if bc.Client == nil {
// Inject ipc client global instance.
client, err := ethclient.Dial(bc.IPCEndpoint)
if err != nil {
log.Error("Fail to connect IPC", "error", err)
return nil, err
}
bc.Client = client
}
return bc.Client, nil
}

View file

@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/state"
@ -30,6 +31,7 @@ import (
"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/ethclient"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params"
@ -218,3 +220,16 @@ func (b *EthApiBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma
go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests)
}
}
func (b *EthApiBackend) GetIPCClient() (*ethclient.Client, error) {
client, err := b.eth.blockchain.GetClient()
if err != nil {
return nil, err
}
return client, nil
}
func (b *EthApiBackend) GetEngine() consensus.Engine {
return b.eth.engine
}

View file

@ -41,7 +41,6 @@ import (
"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/ethclient"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/internal/ethapi"
@ -97,9 +96,7 @@ type Ethereum struct {
networkId uint64
netRPCService *ethapi.PublicNetAPI
lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase)
IPCEndpoint string
Client *ethclient.Client // Global ipc client instance.
lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase)
}
func (s *Ethereum) AddLesServer(ls LesServer) {
@ -186,17 +183,21 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
}
eth.ApiBackend.gpo = gasprice.NewOracle(eth.ApiBackend, gpoParams)
// Set global ipc endpoint.
eth.blockchain.IPCEndpoint = ctx.GetConfig().IPCEndpoint()
if eth.chainConfig.Clique != nil {
c := eth.engine.(*clique.Clique)
// Set global ipc endpoint.
eth.IPCEndpoint = ctx.GetConfig().IPCEndpoint()
// Inject hook for send tx sign to smartcontract after insert block into chain.
importedHook := func(block *types.Block) {
snap, err := c.GetSnapshot(eth.blockchain, block.Header())
if err != nil {
log.Error("Fail to get snapshot for sign tx validator.", "error", err)
if err == consensus.ErrUnknownAncestor {
log.Warn("Block chain forked.", "error", err)
} else {
log.Error("Fail to get snapshot for sign tx validator.", "error", err)
}
return
}
if _, authorized := snap.Signers[eth.etherbase]; authorized {
@ -210,7 +211,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
// Hook reward for clique validator.
c.HookReward = func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) error {
client, err := eth.GetClient()
client, err := eth.blockchain.GetClient()
if err != nil {
log.Error("Fail to connect IPC client for blockSigner", "error", err)
}
@ -533,19 +534,4 @@ func (s *Ethereum) Stop() error {
close(s.shutdownChan)
return nil
}
// Get current IPC Client.
func (s *Ethereum) GetClient() (*ethclient.Client, error) {
if s.Client == nil {
// Inject ipc client global instance.
client, err := ethclient.Dial(s.IPCEndpoint)
if err != nil {
log.Error("Fail to connect RPC", "error", err)
return nil, err
}
s.Client = client
}
return s.Client, nil
}

View file

@ -30,7 +30,9 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus/clique"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/contracts"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
@ -507,7 +509,7 @@ func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Add
func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
block, err := s.b.BlockByNumber(ctx, blockNr)
if block != nil {
response, err := s.rpcOutputBlock(block, true, fullTx)
response, err := s.rpcOutputBlock(block, true, fullTx, ctx)
if err == nil && blockNr == rpc.PendingBlockNumber {
// Pending blocks need to nil out a few fields
for _, field := range []string{"hash", "nonce", "miner"} {
@ -524,7 +526,7 @@ func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.
func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (map[string]interface{}, error) {
block, err := s.b.GetBlock(ctx, blockHash)
if block != nil {
return s.rpcOutputBlock(block, true, fullTx)
return s.rpcOutputBlock(block, true, fullTx, ctx)
}
return nil, err
}
@ -540,7 +542,7 @@ func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context,
return nil, nil
}
block = types.NewBlockWithHeader(uncles[index])
return s.rpcOutputBlock(block, false, false)
return s.rpcOutputBlock(block, false, false, ctx)
}
return nil, err
}
@ -556,7 +558,7 @@ func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, b
return nil, nil
}
block = types.NewBlockWithHeader(uncles[index])
return s.rpcOutputBlock(block, false, false)
return s.rpcOutputBlock(block, false, false, ctx)
}
return nil, err
}
@ -793,7 +795,7 @@ func FormatLogs(logs []vm.StructLog) []StructLogRes {
// rpcOutputBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
// transaction hashes.
func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool, ctx context.Context) (map[string]interface{}, error) {
head := b.Header() // copies the header once
fields := map[string]interface{}{
"number": (*hexutil.Big)(head.Number),
@ -845,6 +847,45 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
}
fields["uncles"] = uncleHashes
// Get signers for block.
client, err := s.b.GetIPCClient()
if err != nil {
log.Error("Fail to connect IPC client for block status", "error", err)
}
var signers []common.Address
var filterSigners []common.Address
finality := false
if b.Number().Int64() > 0 {
addrBlockSigner := common.HexToAddress(common.BlockSigners)
signers, err = contracts.GetSignersFromContract(addrBlockSigner, client, b.Hash())
if err != nil {
log.Error("Fail to get signers from block signer SC.", "error", err)
}
// Get block epoc latest.
if s.b.ChainConfig().Clique != nil {
engine := s.b.GetEngine()
lastCheckpointNumber := rpc.BlockNumber(b.Number().Uint64() - (b.Number().Uint64() % s.b.ChainConfig().Clique.Epoch))
prevCheckpointBlock, _ := s.b.BlockByNumber(ctx, lastCheckpointNumber)
if prevCheckpointBlock != nil {
masternodes := engine.(*clique.Clique).GetMasternodesFromCheckpointHeader(prevCheckpointBlock.Header())
countFinality := 0
for _, masternode := range masternodes {
for _, signer := range signers {
if signer == masternode {
countFinality++
filterSigners = append(filterSigners, masternode)
}
}
}
if countFinality >= len(masternodes)*75/100 {
finality = true
}
}
}
}
fields["signers"] = filterSigners
fields["finality"] = finality
return fields, nil
}
@ -1475,4 +1516,4 @@ func (s *PublicNetAPI) PeerCount() hexutil.Uint {
// Version returns the current ethereum protocol version.
func (s *PublicNetAPI) Version() string {
return fmt.Sprintf("%d", s.networkVersion)
}
}

View file

@ -23,11 +23,13 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core"
"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/ethclient"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params"
@ -69,6 +71,8 @@ type Backend interface {
ChainConfig() *params.ChainConfig
CurrentBlock() *types.Block
GetIPCClient() (*ethclient.Client, error)
GetEngine() consensus.Engine
}
func GetAPIs(apiBackend Backend) []rpc.API {
@ -115,4 +119,4 @@ func GetAPIs(apiBackend Backend) []rpc.API {
Public: false,
},
}
}
}

View file

@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/state"
@ -30,6 +31,7 @@ import (
"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/ethclient"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/light"
@ -190,3 +192,11 @@ func (b *LesApiBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma
go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests)
}
}
func (b *LesApiBackend) GetIPCClient() (*ethclient.Client, error) {
return nil, nil
}
func (b *LesApiBackend) GetEngine() consensus.Engine {
return b.eth.engine
}