mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-30 08:33:45 +00:00
Merge pull request #8 from DeBankDeFi/pre-exec
State node: implement pre-execution API
This commit is contained in:
commit
8e1cc27b62
12 changed files with 315 additions and 16 deletions
|
|
@ -18,7 +18,6 @@ package core
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||
|
|
@ -148,3 +147,9 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
|
|||
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg)
|
||||
return applyTransaction(msg, config, bc, author, gp, statedb, header, tx, usedGas, vmenv)
|
||||
}
|
||||
|
||||
func ApplyTransactionForPreExec(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, msg types.Message, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) {
|
||||
blockContext := NewEVMBlockContext(header, bc, author)
|
||||
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg)
|
||||
return applyTransaction(msg, config, bc, author, gp, statedb, header, tx, usedGas, vmenv)
|
||||
}
|
||||
|
|
@ -482,6 +482,25 @@ func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common
|
|||
return pending, queued
|
||||
}
|
||||
|
||||
// ContentByAccount retrieves the data content of the transaction pool with a specific account,
|
||||
// returning the pending as well as queued transaction.
|
||||
func (pool *TxPool) ContentByAccount(addr common.Address) (pending, queued types.Transactions) {
|
||||
pool.mu.Lock()
|
||||
defer pool.mu.Unlock()
|
||||
|
||||
list, ok := pool.pending[addr]
|
||||
if ok {
|
||||
pending = list.Flatten()
|
||||
}
|
||||
|
||||
list, ok = pool.queue[addr]
|
||||
if ok {
|
||||
queued = list.Flatten()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Pending retrieves all currently processable transactions, grouped by origin
|
||||
// account and sorted by nonce. The returned transaction set is a copy and can be
|
||||
// freely modified by calling code.
|
||||
|
|
|
|||
|
|
@ -263,6 +263,10 @@ func (b *EthAPIBackend) TxPoolContent() (map[common.Address]types.Transactions,
|
|||
return b.eth.TxPool().Content()
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) TxPoolContentByAccount(addr common.Address) (pending, queued types.Transactions) {
|
||||
return b.eth.TxPool().ContentByAccount(addr)
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) TxPool() *core.TxPool {
|
||||
return b.eth.TxPool()
|
||||
}
|
||||
|
|
|
|||
230
eth/api_pre_exec.go
Normal file
230
eth/api_pre_exec.go
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
package eth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
"github.com/DeBankDeFi/eth/txtrace"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"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/tracers"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
type helpHash struct {
|
||||
hashed hash.Hash
|
||||
}
|
||||
|
||||
func newHash() *helpHash {
|
||||
|
||||
return &helpHash{hashed: sha3.NewLegacyKeccak256()}
|
||||
}
|
||||
|
||||
func (h *helpHash) Reset() {
|
||||
h.hashed.Reset()
|
||||
}
|
||||
|
||||
func (h *helpHash) Update(key, val []byte) {
|
||||
h.hashed.Write(key)
|
||||
h.hashed.Write(val)
|
||||
}
|
||||
|
||||
func (h *helpHash) Hash() common.Hash {
|
||||
return common.BytesToHash(h.hashed.Sum(nil))
|
||||
}
|
||||
|
||||
type PreExecTx struct {
|
||||
ChainId *big.Int
|
||||
From, To, Data, Value, Gas, GasPrice, Nonce string
|
||||
}
|
||||
|
||||
type preData struct {
|
||||
block *types.Block
|
||||
tx *types.Transaction
|
||||
msg types.Message
|
||||
stateDb *state.StateDB
|
||||
header *types.Header
|
||||
}
|
||||
|
||||
// PreExecAPI provides pre exec info for rpc
|
||||
type PreExecAPI struct {
|
||||
e *Ethereum
|
||||
}
|
||||
|
||||
func NewPreExecAPI(e *Ethereum) *PreExecAPI {
|
||||
return &PreExecAPI{e: e}
|
||||
}
|
||||
|
||||
func (api *PreExecAPI) getBlockAndMsg(origin *PreExecTx, number *big.Int) (*types.Block, types.Message) {
|
||||
fromAddr := common.HexToAddress(origin.From)
|
||||
toAddr := common.HexToAddress(origin.To)
|
||||
|
||||
tx := types.NewTx(&types.LegacyTx{
|
||||
Nonce: hexutil.MustDecodeUint64(origin.Nonce),
|
||||
To: &toAddr,
|
||||
Value: hexutil.MustDecodeBig(origin.Value),
|
||||
Gas: hexutil.MustDecodeUint64(origin.Gas),
|
||||
GasPrice: hexutil.MustDecodeBig(origin.GasPrice),
|
||||
Data: hexutil.MustDecode(origin.Data),
|
||||
})
|
||||
|
||||
number.Add(number, big.NewInt(1))
|
||||
block := types.NewBlock(
|
||||
&types.Header{Number: number},
|
||||
[]*types.Transaction{tx}, nil, nil, newHash())
|
||||
|
||||
msg := types.NewMessage(
|
||||
fromAddr,
|
||||
&toAddr,
|
||||
hexutil.MustDecodeUint64(origin.Nonce),
|
||||
hexutil.MustDecodeBig(origin.Value),
|
||||
hexutil.MustDecodeUint64(origin.Gas),
|
||||
hexutil.MustDecodeBig(origin.GasPrice),
|
||||
hexutil.MustDecode(origin.Data),
|
||||
nil, false,
|
||||
)
|
||||
|
||||
return block, msg
|
||||
}
|
||||
|
||||
func (api *PreExecAPI) prepareData(ctx context.Context, origin *PreExecTx) (*preData, error) {
|
||||
var (
|
||||
d preData
|
||||
err error
|
||||
)
|
||||
bc := api.e.blockchain
|
||||
d.header, err = api.e.APIBackend.HeaderByNumber(ctx, rpc.LatestBlockNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
latestNumber := d.header.Number
|
||||
parent := api.e.blockchain.GetBlockByNumber(latestNumber.Uint64())
|
||||
d.stateDb, err = state.New(parent.Header().Root, bc.StateCache(), bc.Snapshots())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d.block, d.msg = api.getBlockAndMsg(origin, latestNumber)
|
||||
d.tx = d.block.Transactions()[0]
|
||||
return &d, nil
|
||||
}
|
||||
|
||||
func (api *PreExecAPI) GetLogs(ctx context.Context, origin *PreExecTx) (*types.Receipt, error) {
|
||||
var (
|
||||
bc = api.e.blockchain
|
||||
)
|
||||
d, err := api.prepareData(ctx, origin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gas := d.tx.Gas()
|
||||
gp := new(core.GasPool).AddGas(gas)
|
||||
|
||||
d.stateDb.Prepare(d.tx.Hash(), d.block.Hash(), 0)
|
||||
receipt, err := core.ApplyTransactionForPreExec(
|
||||
bc.Config(), bc, nil, gp, d.stateDb, d.header, d.tx, d.msg, &gas, *bc.GetVMConfig())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return receipt, nil
|
||||
}
|
||||
|
||||
// TraceTransaction tracing pre-exec transaction object.
|
||||
func (api *PreExecAPI) TraceTransaction(ctx context.Context, origin *PreExecTx, config *tracers.TraceConfig) (interface{}, error) {
|
||||
var (
|
||||
bc = api.e.blockchain
|
||||
tracer vm.Tracer
|
||||
err error
|
||||
)
|
||||
d, err := api.prepareData(ctx, origin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
txContext := core.NewEVMTxContext(d.msg)
|
||||
|
||||
switch {
|
||||
case config != nil && config.Tracer != nil:
|
||||
// Define a meaningful timeout of a single transaction trace
|
||||
timeout := 5 * time.Second
|
||||
if config.Timeout != nil {
|
||||
if timeout, err = time.ParseDuration(*config.Timeout); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// Constuct the JavaScript tracer to execute with
|
||||
if tracer, err = tracers.New(*config.Tracer, txContext); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Handle timeouts and RPC cancellations
|
||||
deadlineCtx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
go func() {
|
||||
<-deadlineCtx.Done()
|
||||
if deadlineCtx.Err() == context.DeadlineExceeded {
|
||||
tracer.(*tracers.Tracer).Stop(errors.New("execution timeout"))
|
||||
}
|
||||
}()
|
||||
case config == nil:
|
||||
fallthrough
|
||||
default:
|
||||
// Constuct the txtrace.StructLogger tracer to execute with
|
||||
tracer = txtrace.NewTraceStructLogger(nil)
|
||||
}
|
||||
// Run the transaction with tracing enabled.
|
||||
vmenv := vm.NewEVM(core.NewEVMBlockContext(d.header, bc, nil), txContext, d.stateDb, bc.Config(), vm.Config{Debug: true, Tracer: tracer})
|
||||
|
||||
txIndex := 0
|
||||
// Call Prepare to clear out the statedb access list
|
||||
d.stateDb.Prepare(d.tx.Hash(), d.block.Hash(), txIndex)
|
||||
|
||||
// check if type of tracer is txtrace.StructLogger, in that case, fill info.
|
||||
var traceLogger *txtrace.StructLogger
|
||||
switch tracer.(type) {
|
||||
case *txtrace.StructLogger:
|
||||
traceLogger = tracer.(*txtrace.StructLogger)
|
||||
traceLogger.SetFrom(d.msg.From())
|
||||
traceLogger.SetTo(d.msg.To())
|
||||
traceLogger.SetValue(*d.msg.Value())
|
||||
traceLogger.SetGasUsed(d.tx.Gas())
|
||||
traceLogger.SetBlockHash(d.block.Hash())
|
||||
traceLogger.SetBlockNumber(d.block.Number())
|
||||
traceLogger.SetTx(d.tx.Hash())
|
||||
traceLogger.SetTxIndex(uint(txIndex))
|
||||
}
|
||||
|
||||
result, err := core.ApplyMessage(vmenv, d.msg, new(core.GasPool).AddGas(d.msg.Gas()))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tracing failed: %v", err)
|
||||
}
|
||||
// Depending on the tracer type, format and return the output.
|
||||
switch tracer := tracer.(type) {
|
||||
case *vm.StructLogger:
|
||||
// If the result contains a revert reason, return it.
|
||||
returnVal := fmt.Sprintf("%x", result.Return())
|
||||
if len(result.Revert()) > 0 {
|
||||
returnVal = fmt.Sprintf("%x", result.Revert())
|
||||
}
|
||||
return ðapi.ExecutionResult{
|
||||
Gas: result.UsedGas,
|
||||
Failed: result.Failed(),
|
||||
ReturnValue: returnVal,
|
||||
StructLogs: ethapi.FormatLogs(tracer.StructLogs()),
|
||||
}, nil
|
||||
case *tracers.Tracer:
|
||||
return tracer.GetResult()
|
||||
case *txtrace.StructLogger:
|
||||
tracer.Finalize()
|
||||
return tracer.GetResult(), nil
|
||||
default:
|
||||
panic(fmt.Sprintf("bad tracer type %T", tracer))
|
||||
}
|
||||
}
|
||||
|
|
@ -345,6 +345,12 @@ func (s *Ethereum) APIs() []rpc.API {
|
|||
Service: s.netRPCService,
|
||||
Public: true,
|
||||
},
|
||||
{
|
||||
Namespace: "pre",
|
||||
Version: "1.0",
|
||||
Service: NewPreExecAPI(s),
|
||||
Public: true,
|
||||
},
|
||||
}...)
|
||||
}
|
||||
|
||||
|
|
|
|||
11
go.mod
11
go.mod
|
|
@ -3,10 +3,8 @@ module github.com/ethereum/go-ethereum
|
|||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-pipeline-go v0.2.2 // indirect
|
||||
github.com/Azure/azure-storage-blob-go v0.7.0
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0 // indirect
|
||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
|
||||
github.com/DeBankDeFi/eth v1.10.3
|
||||
github.com/VictoriaMetrics/fastcache v1.5.7
|
||||
github.com/aws/aws-sdk-go-v2 v1.2.0
|
||||
github.com/aws/aws-sdk-go-v2/config v1.1.1
|
||||
|
|
@ -18,15 +16,12 @@ require (
|
|||
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea
|
||||
github.com/dlclark/regexp2 v1.2.0 // indirect
|
||||
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf
|
||||
github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498
|
||||
github.com/edsrzf/mmap-go v1.0.0
|
||||
github.com/fatih/color v1.7.0
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff
|
||||
github.com/go-ole/go-ole v1.2.1 // indirect
|
||||
github.com/go-sourcemap/sourcemap v2.1.2+incompatible // indirect
|
||||
github.com/go-stack/stack v1.8.0
|
||||
github.com/golang/protobuf v1.4.3
|
||||
github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3
|
||||
|
|
@ -43,10 +38,8 @@ require (
|
|||
github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e
|
||||
github.com/julienschmidt/httprouter v1.2.0
|
||||
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.0
|
||||
github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035
|
||||
github.com/naoina/go-stringutil v0.1.0 // indirect
|
||||
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7
|
||||
|
|
@ -57,7 +50,6 @@ require (
|
|||
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954
|
||||
github.com/tklauser/go-sysconf v0.3.5 // indirect
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
|
|
@ -67,5 +59,4 @@ require (
|
|||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6
|
||||
gopkg.in/urfave/cli.v1 v1.20.0
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
)
|
||||
|
|
|
|||
5
go.sum
5
go.sum
|
|
@ -42,6 +42,10 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt
|
|||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DeBankDeFi/eth v1.10.3-rc1 h1:c/JTocFaCThfMdq/R3dCENWBYj0VQ8YhpCAqEcLKsyA=
|
||||
github.com/DeBankDeFi/eth v1.10.3-rc1/go.mod h1:UAiugF3perbugrqRhIGYBzh4Rl930XLXkmHlqh0YcQs=
|
||||
github.com/DeBankDeFi/eth v1.10.3 h1:Niun1jAilCbYaYNOvbiMg3iyochzyFK8zt1VCsH27kk=
|
||||
github.com/DeBankDeFi/eth v1.10.3/go.mod h1:UAiugF3perbugrqRhIGYBzh4Rl930XLXkmHlqh0YcQs=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
|
||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
|
|
@ -126,6 +130,7 @@ github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
|
|||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/ethereum/go-ethereum v1.10.3/go.mod h1:99onQmSd1GRGOziyGldI41YQb7EESX3Q4H41IfJgIQQ=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=
|
||||
|
|
|
|||
|
|
@ -99,6 +99,31 @@ func NewPublicTxPoolAPI(b Backend) *PublicTxPoolAPI {
|
|||
return &PublicTxPoolAPI{b}
|
||||
}
|
||||
|
||||
// ContentByAccount returns the transactions contained within the tx pool by given account address.
|
||||
func (s *PublicTxPoolAPI) ContentByAccount(addr common.Address) map[string]map[string]*RPCTransaction {
|
||||
// map[(queued|pending)]map[tx.Nonce()]tx
|
||||
content := map[string]map[string]*RPCTransaction{
|
||||
"pending": make(map[string]*RPCTransaction),
|
||||
"queued": make(map[string]*RPCTransaction),
|
||||
}
|
||||
|
||||
pending, queued := s.b.TxPoolContentByAccount(addr)
|
||||
|
||||
dump := make(map[string]*RPCTransaction)
|
||||
for _, tx := range pending {
|
||||
dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx)
|
||||
}
|
||||
content["pending"] = dump
|
||||
|
||||
dump = make(map[string]*RPCTransaction)
|
||||
for _, tx := range queued {
|
||||
dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx)
|
||||
}
|
||||
content["queued"] = dump
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
// Content returns the transactions contained within the transaction pool.
|
||||
func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction {
|
||||
content := map[string]map[string]map[string]*RPCTransaction{
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ type Backend interface {
|
|||
GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error)
|
||||
Stats() (pending int, queued int)
|
||||
TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions)
|
||||
TxPoolContentByAccount(address common.Address) (pending, queued types.Transactions)
|
||||
SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
|
||||
|
||||
// Filter API
|
||||
|
|
|
|||
|
|
@ -773,7 +773,15 @@ web3._extend({
|
|||
const TxpoolJs = `
|
||||
web3._extend({
|
||||
property: 'txpool',
|
||||
methods: [],
|
||||
methods:
|
||||
[
|
||||
new web3._extend.Method({
|
||||
name: 'contentByAccount',
|
||||
call: 'txpool_contentByAccount',
|
||||
params: 1,
|
||||
inputFormatter: [null]
|
||||
}),
|
||||
],
|
||||
properties:
|
||||
[
|
||||
new web3._extend.Property({
|
||||
|
|
|
|||
|
|
@ -212,6 +212,11 @@ func (b *LesApiBackend) TxPoolContent() (map[common.Address]types.Transactions,
|
|||
return b.eth.txPool.Content()
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) TxPoolContentByAccount(addr common.Address) (pending, queued types.Transactions) {
|
||||
// TODO(barryz) not implement for light node.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
|
||||
return b.eth.txPool.SubscribeNewTxsEvent(ch)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
VersionMajor = 1 // Major version component of the current release
|
||||
VersionMinor = 10 // Minor version component of the current release
|
||||
VersionPatch = 3 // Patch version component of the current release
|
||||
VersionMeta = "stable" // Version metadata to append to the version string
|
||||
VersionMajor = 1 // Major version component of the current release
|
||||
VersionMinor = 10 // Minor version component of the current release
|
||||
VersionPatch = 3 // Patch version component of the current release
|
||||
VersionMeta = "unstable-pre-exec" // Version metadata to append to the version string
|
||||
)
|
||||
|
||||
// Version holds the textual version string.
|
||||
|
|
|
|||
Loading…
Reference in a new issue