github.com/dominant-strategies/go-quai@v0.28.2/eth/api_backend.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package eth
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"math/big"
    23  
    24  	quai "github.com/dominant-strategies/go-quai"
    25  
    26  	"github.com/dominant-strategies/go-quai/common"
    27  	"github.com/dominant-strategies/go-quai/consensus"
    28  	"github.com/dominant-strategies/go-quai/core"
    29  	"github.com/dominant-strategies/go-quai/core/bloombits"
    30  	"github.com/dominant-strategies/go-quai/core/rawdb"
    31  	"github.com/dominant-strategies/go-quai/core/state"
    32  	"github.com/dominant-strategies/go-quai/core/types"
    33  	"github.com/dominant-strategies/go-quai/core/vm"
    34  	"github.com/dominant-strategies/go-quai/eth/downloader"
    35  	"github.com/dominant-strategies/go-quai/eth/gasprice"
    36  	"github.com/dominant-strategies/go-quai/ethdb"
    37  	"github.com/dominant-strategies/go-quai/event"
    38  	"github.com/dominant-strategies/go-quai/params"
    39  	"github.com/dominant-strategies/go-quai/rpc"
    40  )
    41  
    42  // QuaiAPIBackend implements quaiapi.Backend for full nodes
    43  type QuaiAPIBackend struct {
    44  	extRPCEnabled bool
    45  	eth           *Quai
    46  	gpo           *gasprice.Oracle
    47  }
    48  
    49  // ChainConfig returns the active chain configuration.
    50  func (b *QuaiAPIBackend) ChainConfig() *params.ChainConfig {
    51  	return b.eth.core.Config()
    52  }
    53  
    54  func (b *QuaiAPIBackend) TxPool() *core.TxPool {
    55  	nodeCtx := common.NodeLocation.Context()
    56  	if nodeCtx != common.ZONE_CTX {
    57  		return nil
    58  	}
    59  	return b.eth.core.TxPool()
    60  }
    61  
    62  func (b *QuaiAPIBackend) CurrentBlock() *types.Block {
    63  	return b.eth.core.CurrentBlock()
    64  }
    65  
    66  // CurrentLogEntropy returns the logarithm of the total entropy reduction since genesis for our current head block
    67  func (b *QuaiAPIBackend) CurrentLogEntropy() *big.Int {
    68  	return b.eth.core.CurrentLogEntropy()
    69  }
    70  
    71  // TotalLogS returns the total entropy reduction if the chain since genesis to the given header
    72  func (b *QuaiAPIBackend) TotalLogS(header *types.Header) *big.Int {
    73  	return b.eth.core.TotalLogS(header)
    74  }
    75  
    76  // CalcOrder returns the order of the block within the hierarchy of chains
    77  func (b *QuaiAPIBackend) CalcOrder(header *types.Header) (*big.Int, int, error) {
    78  	return b.eth.core.CalcOrder(header)
    79  }
    80  
    81  func (b *QuaiAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
    82  	// Pending block is only known by the miner
    83  	if number == rpc.PendingBlockNumber {
    84  		block := b.eth.core.PendingBlock()
    85  		return block.Header(), nil
    86  	}
    87  	// Otherwise resolve and return the block
    88  	if number == rpc.LatestBlockNumber {
    89  		return b.eth.core.CurrentBlock().Header(), nil
    90  	}
    91  	return b.eth.core.GetHeaderByNumber(uint64(number)), nil
    92  }
    93  
    94  func (b *QuaiAPIBackend) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) {
    95  	if blockNr, ok := blockNrOrHash.Number(); ok {
    96  		return b.HeaderByNumber(ctx, blockNr)
    97  	}
    98  	if hash, ok := blockNrOrHash.Hash(); ok {
    99  		header := b.eth.core.GetHeaderByHash(hash)
   100  		if header == nil {
   101  			return nil, errors.New("header for hash not found")
   102  		}
   103  		if blockNrOrHash.RequireCanonical && b.eth.core.GetCanonicalHash(header.Number().Uint64()) != hash {
   104  			return nil, errors.New("hash is not currently canonical")
   105  		}
   106  		return header, nil
   107  	}
   108  	return nil, errors.New("invalid arguments; neither block nor hash specified")
   109  }
   110  
   111  func (b *QuaiAPIBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
   112  	return b.eth.core.GetHeaderByHash(hash), nil
   113  }
   114  
   115  func (b *QuaiAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
   116  	// Pending block is only known by the miner
   117  	if number == rpc.PendingBlockNumber {
   118  		block := b.eth.core.PendingBlock()
   119  		return block, nil
   120  	}
   121  	// Otherwise resolve and return the block
   122  	if number == rpc.LatestBlockNumber {
   123  		number = rpc.BlockNumber(b.eth.core.CurrentHeader().NumberU64())
   124  	}
   125  	block := b.eth.core.GetBlockByNumber(uint64(number))
   126  	if block != nil {
   127  		return block, nil
   128  	}
   129  	return nil, errors.New("block is nil api backend")
   130  }
   131  
   132  func (b *QuaiAPIBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
   133  	return b.eth.core.GetBlockByHash(hash), nil
   134  }
   135  
   136  func (b *QuaiAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) {
   137  	if blockNr, ok := blockNrOrHash.Number(); ok {
   138  		return b.BlockByNumber(ctx, blockNr)
   139  	}
   140  	if hash, ok := blockNrOrHash.Hash(); ok {
   141  		header := b.eth.core.GetHeaderByHash(hash)
   142  		if header == nil {
   143  			return nil, errors.New("header for hash not found")
   144  		}
   145  		if blockNrOrHash.RequireCanonical && b.eth.core.GetCanonicalHash(header.Number().Uint64()) != hash {
   146  			return nil, errors.New("hash is not currently canonical")
   147  		}
   148  		block := b.eth.core.GetBlock(hash, header.Number().Uint64())
   149  		if block == nil {
   150  			return nil, errors.New("header found, but block body is missing")
   151  		}
   152  		return block, nil
   153  	}
   154  	return nil, errors.New("invalid arguments; neither block nor hash specified")
   155  }
   156  
   157  func (b *QuaiAPIBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
   158  	return b.eth.core.PendingBlockAndReceipts()
   159  }
   160  
   161  func (b *QuaiAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
   162  	nodeCtx := common.NodeLocation.Context()
   163  	if nodeCtx != common.ZONE_CTX {
   164  		return nil, nil, errors.New("stateAndHeaderByNumber can only be called in zone chain")
   165  	}
   166  	// Pending state is only known by the miner
   167  	if number == rpc.PendingBlockNumber {
   168  		block := b.eth.core.Pending()
   169  		return &state.StateDB{}, block.Header(), nil
   170  	}
   171  	// Otherwise resolve the block number and return its state
   172  	header, err := b.HeaderByNumber(ctx, number)
   173  	if err != nil {
   174  		return nil, nil, err
   175  	}
   176  	if header == nil {
   177  		return nil, nil, errors.New("header not found")
   178  	}
   179  	stateDb, err := b.eth.Core().StateAt(header.Root())
   180  	return stateDb, header, err
   181  }
   182  
   183  func (b *QuaiAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) {
   184  	nodeCtx := common.NodeLocation.Context()
   185  	if nodeCtx != common.ZONE_CTX {
   186  		return nil, nil, errors.New("stateAndHeaderByNumberOrHash can only be called in zone chain")
   187  	}
   188  	if blockNr, ok := blockNrOrHash.Number(); ok {
   189  		return b.StateAndHeaderByNumber(ctx, blockNr)
   190  	}
   191  	if hash, ok := blockNrOrHash.Hash(); ok {
   192  		header, err := b.HeaderByHash(ctx, hash)
   193  		if err != nil {
   194  			return nil, nil, err
   195  		}
   196  		if header == nil {
   197  			return nil, nil, errors.New("header for hash not found")
   198  		}
   199  		if blockNrOrHash.RequireCanonical && b.eth.core.GetCanonicalHash(header.Number().Uint64()) != hash {
   200  			return nil, nil, errors.New("hash is not currently canonical")
   201  		}
   202  		stateDb, err := b.eth.Core().StateAt(header.Root())
   203  		return stateDb, header, err
   204  	}
   205  	return nil, nil, errors.New("invalid arguments; neither block nor hash specified")
   206  }
   207  
   208  func (b *QuaiAPIBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
   209  	nodeCtx := common.NodeLocation.Context()
   210  	if nodeCtx != common.ZONE_CTX {
   211  		return nil, errors.New("getReceipts can only be called in zone chain")
   212  	}
   213  	return b.eth.core.GetReceiptsByHash(hash), nil
   214  }
   215  
   216  // GetBloom returns the bloom for the given block hash
   217  func (b *QuaiAPIBackend) GetBloom(hash common.Hash) (*types.Bloom, error) {
   218  	nodeCtx := common.NodeLocation.Context()
   219  	if nodeCtx != common.ZONE_CTX {
   220  		return nil, errors.New("getBloom can only be called in zone chain")
   221  	}
   222  	return b.eth.core.Slice().HeaderChain().GetBloom(hash)
   223  }
   224  
   225  func (b *QuaiAPIBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
   226  	nodeCtx := common.NodeLocation.Context()
   227  	if nodeCtx != common.ZONE_CTX {
   228  		return nil, errors.New("getLogs can only be called in zone chain")
   229  	}
   230  	receipts := b.eth.core.GetReceiptsByHash(hash)
   231  	if receipts == nil {
   232  		return nil, nil
   233  	}
   234  	logs := make([][]*types.Log, len(receipts))
   235  	for i, receipt := range receipts {
   236  		logs[i] = receipt.Logs
   237  	}
   238  	return logs, nil
   239  }
   240  
   241  func (b *QuaiAPIBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error) {
   242  	vmError := func() error { return nil }
   243  	nodeCtx := common.NodeLocation.Context()
   244  	if nodeCtx != common.ZONE_CTX {
   245  		return nil, vmError, errors.New("getEvm can only be called in zone chain")
   246  	}
   247  	if vmConfig == nil {
   248  		vmConfig = b.eth.core.GetVMConfig()
   249  	}
   250  	txContext := core.NewEVMTxContext(msg)
   251  	context := core.NewEVMBlockContext(header, b.eth.Core(), nil)
   252  	return vm.NewEVM(context, txContext, state, b.eth.core.Config(), *vmConfig), vmError, nil
   253  }
   254  
   255  func (b *QuaiAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
   256  	nodeCtx := common.NodeLocation.Context()
   257  	if nodeCtx != common.ZONE_CTX {
   258  		return nil
   259  	}
   260  	return b.eth.Core().SubscribeRemovedLogsEvent(ch)
   261  }
   262  
   263  func (b *QuaiAPIBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription {
   264  	nodeCtx := common.NodeLocation.Context()
   265  	if nodeCtx != common.ZONE_CTX {
   266  		return nil
   267  	}
   268  	return b.eth.core.SubscribePendingLogs(ch)
   269  }
   270  
   271  func (b *QuaiAPIBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
   272  	return b.eth.Core().SubscribeChainEvent(ch)
   273  }
   274  
   275  func (b *QuaiAPIBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription {
   276  	return b.eth.Core().SubscribeChainHeadEvent(ch)
   277  }
   278  
   279  func (b *QuaiAPIBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription {
   280  	return b.eth.Core().SubscribeChainSideEvent(ch)
   281  }
   282  
   283  func (b *QuaiAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
   284  	nodeCtx := common.NodeLocation.Context()
   285  	if nodeCtx != common.ZONE_CTX {
   286  		return nil
   287  	}
   288  	return b.eth.Core().SubscribeLogsEvent(ch)
   289  }
   290  
   291  func (b *QuaiAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
   292  	nodeCtx := common.NodeLocation.Context()
   293  	if nodeCtx != common.ZONE_CTX {
   294  		return errors.New("sendTx can only be called in zone chain")
   295  	}
   296  	return b.eth.Core().AddLocal(signedTx)
   297  }
   298  
   299  func (b *QuaiAPIBackend) GetPoolTransactions() (types.Transactions, error) {
   300  	nodeCtx := common.NodeLocation.Context()
   301  	if nodeCtx != common.ZONE_CTX {
   302  		return nil, errors.New("getPoolTransactions can only be called in zone chain")
   303  	}
   304  	pending, err := b.eth.core.TxPoolPending(false)
   305  	if err != nil {
   306  		return nil, err
   307  	}
   308  	var txs types.Transactions
   309  	for _, batch := range pending {
   310  		txs = append(txs, batch...)
   311  	}
   312  	return txs, nil
   313  }
   314  
   315  func (b *QuaiAPIBackend) GetPoolTransaction(hash common.Hash) *types.Transaction {
   316  	nodeCtx := common.NodeLocation.Context()
   317  	if nodeCtx != common.ZONE_CTX {
   318  		return nil
   319  	}
   320  	return b.eth.core.Get(hash)
   321  }
   322  
   323  func (b *QuaiAPIBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
   324  	nodeCtx := common.NodeLocation.Context()
   325  	if nodeCtx != common.ZONE_CTX {
   326  		return nil, common.Hash{}, 0, 0, errors.New("getTransaction can only be called in zone chain")
   327  	}
   328  	tx, blockHash, blockNumber, index := rawdb.ReadTransaction(b.eth.ChainDb(), txHash)
   329  	return tx, blockHash, blockNumber, index, nil
   330  }
   331  
   332  func (b *QuaiAPIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
   333  	nodeCtx := common.NodeLocation.Context()
   334  	if nodeCtx != common.ZONE_CTX {
   335  		return 0, errors.New("getPoolNonce can only be called in zone chain")
   336  	}
   337  	return b.eth.core.Nonce(addr), nil
   338  }
   339  
   340  func (b *QuaiAPIBackend) Stats() (pending int, queued int) {
   341  	return b.eth.core.Stats()
   342  }
   343  
   344  func (b *QuaiAPIBackend) TxPoolContent() (map[common.InternalAddress]types.Transactions, map[common.InternalAddress]types.Transactions) {
   345  	nodeCtx := common.NodeLocation.Context()
   346  	if nodeCtx != common.ZONE_CTX {
   347  		return nil, nil
   348  	}
   349  	return b.eth.core.Content()
   350  }
   351  
   352  func (b *QuaiAPIBackend) TxPoolContentFrom(addr common.Address) (types.Transactions, types.Transactions) {
   353  	nodeCtx := common.NodeLocation.Context()
   354  	if nodeCtx != common.ZONE_CTX {
   355  		return nil, nil
   356  	}
   357  	return b.eth.core.ContentFrom(addr)
   358  }
   359  
   360  func (b *QuaiAPIBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
   361  	nodeCtx := common.NodeLocation.Context()
   362  	if nodeCtx != common.ZONE_CTX {
   363  		return nil
   364  	}
   365  	return b.eth.core.SubscribeNewTxsEvent(ch)
   366  }
   367  
   368  func (b *QuaiAPIBackend) Downloader() *downloader.Downloader {
   369  	return b.eth.Downloader()
   370  }
   371  
   372  func (b *QuaiAPIBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
   373  	nodeCtx := common.NodeLocation.Context()
   374  	if nodeCtx != common.ZONE_CTX {
   375  		return nil, errors.New("suggestTipCap can only be called in zone chain")
   376  	}
   377  	return b.gpo.SuggestTipCap(ctx)
   378  }
   379  
   380  func (b *QuaiAPIBackend) FeeHistory(ctx context.Context, blockCount int, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (firstBlock *big.Int, reward [][]*big.Int, baseFee []*big.Int, gasUsedRatio []float64, err error) {
   381  	return b.gpo.FeeHistory(ctx, blockCount, lastBlock, rewardPercentiles)
   382  }
   383  
   384  func (b *QuaiAPIBackend) ChainDb() ethdb.Database {
   385  	return b.eth.ChainDb()
   386  }
   387  
   388  func (b *QuaiAPIBackend) EventMux() *event.TypeMux {
   389  	return b.eth.EventMux()
   390  }
   391  
   392  func (b *QuaiAPIBackend) ExtRPCEnabled() bool {
   393  	return b.extRPCEnabled
   394  }
   395  
   396  func (b *QuaiAPIBackend) RPCGasCap() uint64 {
   397  	nodeCtx := common.NodeLocation.Context()
   398  	if nodeCtx != common.ZONE_CTX {
   399  		return 0
   400  	}
   401  	return b.eth.config.RPCGasCap
   402  }
   403  
   404  func (b *QuaiAPIBackend) RPCTxFeeCap() float64 {
   405  	nodeCtx := common.NodeLocation.Context()
   406  	if nodeCtx != common.ZONE_CTX {
   407  		return 0
   408  	}
   409  	return b.eth.config.RPCTxFeeCap
   410  }
   411  
   412  func (b *QuaiAPIBackend) BloomStatus() (uint64, uint64) {
   413  	sections, _, _ := b.eth.bloomIndexer.Sections()
   414  	return params.BloomBitsBlocks, sections
   415  }
   416  
   417  func (b *QuaiAPIBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) {
   418  	for i := 0; i < bloomFilterThreads; i++ {
   419  		go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests)
   420  	}
   421  }
   422  
   423  func (b *QuaiAPIBackend) Engine() consensus.Engine {
   424  	return b.eth.engine
   425  }
   426  
   427  func (b *QuaiAPIBackend) CurrentHeader() *types.Header {
   428  	return b.eth.core.CurrentHeader()
   429  }
   430  
   431  func (b *QuaiAPIBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, checkLive bool) (*state.StateDB, error) {
   432  	nodeCtx := common.NodeLocation.Context()
   433  	if nodeCtx != common.ZONE_CTX {
   434  		return nil, errors.New("stateAtBlock can only be called in zone chain")
   435  	}
   436  	return b.eth.core.StateAtBlock(block, reexec, base, checkLive)
   437  }
   438  
   439  func (b *QuaiAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, error) {
   440  	nodeCtx := common.NodeLocation.Context()
   441  	if nodeCtx != common.ZONE_CTX {
   442  		return nil, vm.BlockContext{}, nil, errors.New("stateAtTransaction can only be called in zone chain")
   443  	}
   444  	return b.eth.core.StateAtTransaction(block, txIndex, reexec)
   445  }
   446  
   447  func (b *QuaiAPIBackend) SyncProgress() quai.SyncProgress {
   448  	return b.eth.Downloader().Progress()
   449  }
   450  
   451  func (b *QuaiAPIBackend) Append(header *types.Header, manifest types.BlockManifest, domPendingHeader *types.Header, domTerminus common.Hash, domOrigin bool, newInboundEtxs types.Transactions) (types.Transactions, bool, bool, error) {
   452  	return b.eth.core.Append(header, manifest, domPendingHeader, domTerminus, domOrigin, newInboundEtxs)
   453  }
   454  
   455  func (b *QuaiAPIBackend) DownloadBlocksInManifest(hash common.Hash, manifest types.BlockManifest, entropy *big.Int) {
   456  	b.eth.core.DownloadBlocksInManifest(hash, manifest, entropy)
   457  }
   458  
   459  func (b *QuaiAPIBackend) ConstructLocalMinedBlock(header *types.Header) (*types.Block, error) {
   460  	return b.eth.core.ConstructLocalMinedBlock(header)
   461  }
   462  
   463  func (b *QuaiAPIBackend) InsertBlock(ctx context.Context, block *types.Block) (int, error) {
   464  	return b.eth.core.InsertChain([]*types.Block{block})
   465  }
   466  
   467  func (b *QuaiAPIBackend) WriteBlock(block *types.Block) {
   468  	b.eth.core.WriteBlock(block)
   469  }
   470  
   471  func (b *QuaiAPIBackend) PendingBlock() *types.Block {
   472  	return b.eth.core.PendingBlock()
   473  }
   474  
   475  func (b *QuaiAPIBackend) SubRelayPendingHeader(pendingHeader types.PendingHeader, newEntropy *big.Int, location common.Location, subReorg bool, order int) {
   476  	b.eth.core.SubRelayPendingHeader(pendingHeader, newEntropy, location, subReorg, order)
   477  }
   478  
   479  func (b *QuaiAPIBackend) UpdateDom(oldTerminus common.Hash, pendingHeader types.PendingHeader, location common.Location) {
   480  	b.eth.core.UpdateDom(oldTerminus, pendingHeader, location)
   481  }
   482  
   483  func (b *QuaiAPIBackend) RequestDomToAppendOrFetch(hash common.Hash, entropy *big.Int, order int) {
   484  	b.eth.core.RequestDomToAppendOrFetch(hash, entropy, order)
   485  }
   486  
   487  func (b *QuaiAPIBackend) ProcessingState() bool {
   488  	return b.eth.core.ProcessingState()
   489  }
   490  
   491  func (b *QuaiAPIBackend) NewGenesisPendingHeader(pendingHeader *types.Header) {
   492  	b.eth.core.NewGenesisPendigHeader(pendingHeader)
   493  }
   494  
   495  func (b *QuaiAPIBackend) GetPendingHeader() (*types.Header, error) {
   496  	return b.eth.core.GetPendingHeader()
   497  }
   498  
   499  func (b *QuaiAPIBackend) GetManifest(blockHash common.Hash) (types.BlockManifest, error) {
   500  	return b.eth.core.GetManifest(blockHash)
   501  }
   502  
   503  func (b *QuaiAPIBackend) GetSubManifest(slice common.Location, blockHash common.Hash) (types.BlockManifest, error) {
   504  	return b.eth.core.GetSubManifest(slice, blockHash)
   505  }
   506  
   507  func (b *QuaiAPIBackend) AddPendingEtxs(pEtxs types.PendingEtxs) error {
   508  	return b.eth.core.AddPendingEtxs(pEtxs)
   509  }
   510  
   511  func (b *QuaiAPIBackend) AddPendingEtxsRollup(pEtxsRollup types.PendingEtxsRollup) error {
   512  	return b.eth.core.AddPendingEtxsRollup(pEtxsRollup)
   513  }
   514  
   515  func (b *QuaiAPIBackend) SubscribePendingHeaderEvent(ch chan<- *types.Header) event.Subscription {
   516  	return b.eth.core.SubscribePendingHeader(ch)
   517  }
   518  
   519  func (b *QuaiAPIBackend) GenerateRecoveryPendingHeader(pendingHeader *types.Header, checkpointHashes types.Termini) error {
   520  	return b.eth.core.GenerateRecoveryPendingHeader(pendingHeader, checkpointHashes)
   521  }
   522  
   523  func (b *QuaiAPIBackend) GetPendingEtxsRollupFromSub(hash common.Hash, location common.Location) (types.PendingEtxsRollup, error) {
   524  	return b.eth.core.GetPendingEtxsRollupFromSub(hash, location)
   525  }
   526  
   527  func (b *QuaiAPIBackend) GetPendingEtxsFromSub(hash common.Hash, location common.Location) (types.PendingEtxs, error) {
   528  	return b.eth.core.GetPendingEtxsFromSub(hash, location)
   529  }
   530  
   531  func (b *QuaiAPIBackend) SetSyncTarget(header *types.Header) {
   532  	b.eth.core.SetSyncTarget(header)
   533  }