mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-15 00:13:46 +00:00
Merge branch 'master' into portal1
This commit is contained in:
commit
d04b685d31
40 changed files with 322 additions and 158 deletions
12
.travis.yml
12
.travis.yml
|
|
@ -9,18 +9,6 @@ jobs:
|
||||||
- azure-osx
|
- azure-osx
|
||||||
|
|
||||||
include:
|
include:
|
||||||
# This builder only tests code linters on latest version of Go
|
|
||||||
- stage: lint
|
|
||||||
os: linux
|
|
||||||
dist: bionic
|
|
||||||
go: 1.21.x
|
|
||||||
env:
|
|
||||||
- lint
|
|
||||||
git:
|
|
||||||
submodules: false # avoid cloning ethereum/tests
|
|
||||||
script:
|
|
||||||
- go run build/ci.go lint
|
|
||||||
|
|
||||||
# These builders create the Docker sub-images for multi-arch push and each
|
# These builders create the Docker sub-images for multi-arch push and each
|
||||||
# will attempt to push the multi-arch image if they are the last builder
|
# will attempt to push the multi-arch image if they are the last builder
|
||||||
- stage: build
|
- stage: build
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,9 @@ func NewManager(config *Config, backends ...Backend) *Manager {
|
||||||
|
|
||||||
// Close terminates the account manager's internal notification processes.
|
// Close terminates the account manager's internal notification processes.
|
||||||
func (am *Manager) Close() error {
|
func (am *Manager) Close() error {
|
||||||
|
for _, w := range am.wallets {
|
||||||
|
w.Close()
|
||||||
|
}
|
||||||
errc := make(chan error)
|
errc := make(chan error)
|
||||||
am.quit <- errc
|
am.quit <- errc
|
||||||
return <-errc
|
return <-errc
|
||||||
|
|
|
||||||
|
|
@ -483,6 +483,10 @@ func (w *wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Accoun
|
||||||
w.stateLock.Lock()
|
w.stateLock.Lock()
|
||||||
defer w.stateLock.Unlock()
|
defer w.stateLock.Unlock()
|
||||||
|
|
||||||
|
if w.device == nil {
|
||||||
|
return accounts.Account{}, accounts.ErrWalletClosed
|
||||||
|
}
|
||||||
|
|
||||||
if _, ok := w.paths[address]; !ok {
|
if _, ok := w.paths[address]; !ok {
|
||||||
w.accounts = append(w.accounts, account)
|
w.accounts = append(w.accounts, account)
|
||||||
w.paths[address] = make(accounts.DerivationPath, len(path))
|
w.paths[address] = make(accounts.DerivationPath, len(path))
|
||||||
|
|
|
||||||
|
|
@ -366,7 +366,7 @@ func doLint(cmdline []string) {
|
||||||
|
|
||||||
linter := downloadLinter(*cachedir)
|
linter := downloadLinter(*cachedir)
|
||||||
lflags := []string{"run", "--config", ".golangci.yml"}
|
lflags := []string{"run", "--config", ".golangci.yml"}
|
||||||
build.MustRunCommand(linter, append(lflags, packages...)...)
|
build.MustRunCommandWithOutput(linter, append(lflags, packages...)...)
|
||||||
fmt.Println("You have achieved perfection.")
|
fmt.Println("You have achieved perfection.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||||
"github.com/ethereum/go-ethereum/p2p/netutil"
|
"github.com/ethereum/go-ethereum/p2p/netutil"
|
||||||
"golang.org/x/exp/slog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
@ -45,7 +44,7 @@ func main() {
|
||||||
natdesc = flag.String("nat", "none", "port mapping mechanism (any|none|upnp|pmp|pmp:<IP>|extip:<IP>)")
|
natdesc = flag.String("nat", "none", "port mapping mechanism (any|none|upnp|pmp|pmp:<IP>|extip:<IP>)")
|
||||||
netrestrict = flag.String("netrestrict", "", "restrict network communication to the given IP networks (CIDR masks)")
|
netrestrict = flag.String("netrestrict", "", "restrict network communication to the given IP networks (CIDR masks)")
|
||||||
runv5 = flag.Bool("v5", false, "run a v5 topic discovery bootnode")
|
runv5 = flag.Bool("v5", false, "run a v5 topic discovery bootnode")
|
||||||
verbosity = flag.Int("verbosity", int(log.LvlInfo), "log verbosity (0-5)")
|
verbosity = flag.Int("verbosity", 3, "log verbosity (0-5)")
|
||||||
vmodule = flag.String("vmodule", "", "log verbosity pattern")
|
vmodule = flag.String("vmodule", "", "log verbosity pattern")
|
||||||
|
|
||||||
nodeKey *ecdsa.PrivateKey
|
nodeKey *ecdsa.PrivateKey
|
||||||
|
|
@ -54,7 +53,8 @@ func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, false))
|
glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, false))
|
||||||
glogger.Verbosity(slog.Level(*verbosity))
|
slogVerbosity := log.FromLegacyLevel(*verbosity)
|
||||||
|
glogger.Verbosity(slogVerbosity)
|
||||||
glogger.Vmodule(*vmodule)
|
glogger.Vmodule(*vmodule)
|
||||||
log.SetDefault(log.NewLogger(glogger))
|
log.SetDefault(log.NewLogger(glogger))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,6 @@ import (
|
||||||
"github.com/mattn/go-colorable"
|
"github.com/mattn/go-colorable"
|
||||||
"github.com/mattn/go-isatty"
|
"github.com/mattn/go-isatty"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"golang.org/x/exp/slog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const legalWarning = `
|
const legalWarning = `
|
||||||
|
|
@ -493,7 +492,8 @@ func initialize(c *cli.Context) error {
|
||||||
if usecolor {
|
if usecolor {
|
||||||
output = colorable.NewColorable(logOutput)
|
output = colorable.NewColorable(logOutput)
|
||||||
}
|
}
|
||||||
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(output, slog.Level(c.Int(logLevelFlag.Name)), usecolor)))
|
verbosity := log.FromLegacyLevel(c.Int(logLevelFlag.Name))
|
||||||
|
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(output, verbosity, usecolor)))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -704,6 +704,7 @@ func signer(c *cli.Context) error {
|
||||||
log.Info("Starting signer", "chainid", chainId, "keystore", ksLoc,
|
log.Info("Starting signer", "chainid", chainId, "keystore", ksLoc,
|
||||||
"light-kdf", lightKdf, "advanced", advanced)
|
"light-kdf", lightKdf, "advanced", advanced)
|
||||||
am := core.StartClefAccountManager(ksLoc, nousb, lightKdf, scpath)
|
am := core.StartClefAccountManager(ksLoc, nousb, lightKdf, scpath)
|
||||||
|
defer am.Close()
|
||||||
apiImpl := core.NewSignerAPI(am, chainId, nousb, ui, db, advanced, pwStorage)
|
apiImpl := core.NewSignerAPI(am, chainId, nousb, ui, db, advanced, pwStorage)
|
||||||
|
|
||||||
// Establish the bidirectional communication, by creating a new UI backend and registering
|
// Establish the bidirectional communication, by creating a new UI backend and registering
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ class StdIOHandler:
|
||||||
{"jsonrpc":"2.0","id":20,"method":"ui_approveTx","params":[{"transaction":{"from":"0xDEADbEeF000000000000000000000000DeaDbeEf","to":"0xDEADbEeF000000000000000000000000DeaDbeEf","gas":"0x3e8","gasPrice":"0x5","maxFeePerGas":null,"maxPriorityFeePerGas":null,"value":"0x6","nonce":"0x1","data":"0x"},"call_info":null,"meta":{"remote":"clef binary","local":"main","scheme":"in-proc","User-Agent":"","Origin":""}}]}
|
{"jsonrpc":"2.0","id":20,"method":"ui_approveTx","params":[{"transaction":{"from":"0xDEADbEeF000000000000000000000000DeaDbeEf","to":"0xDEADbEeF000000000000000000000000DeaDbeEf","gas":"0x3e8","gasPrice":"0x5","maxFeePerGas":null,"maxPriorityFeePerGas":null,"value":"0x6","nonce":"0x1","data":"0x"},"call_info":null,"meta":{"remote":"clef binary","local":"main","scheme":"in-proc","User-Agent":"","Origin":""}}]}
|
||||||
|
|
||||||
:param transaction: transaction info
|
:param transaction: transaction info
|
||||||
:param call_info: info abou the call, e.g. if ABI info could not be
|
:param call_info: info about the call, e.g. if ABI info could not be
|
||||||
:param meta: metadata about the request, e.g. where the call comes from
|
:param meta: metadata about the request, e.g. where the call comes from
|
||||||
:return:
|
:return:
|
||||||
""" # noqa: E501
|
""" # noqa: E501
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,8 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/consensus/clique"
|
"github.com/ethereum/go-ethereum/consensus/clique"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"golang.org/x/exp/slog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run github.com/fjl/gencodec -type header -field-override headerMarshaling -out gen_header.go
|
//go:generate go run github.com/fjl/gencodec -type header -field-override headerMarshaling -out gen_header.go
|
||||||
|
|
@ -216,11 +214,6 @@ func (i *bbInput) sealClique(block *types.Block) (*types.Block, error) {
|
||||||
|
|
||||||
// BuildBlock constructs a block from the given inputs.
|
// BuildBlock constructs a block from the given inputs.
|
||||||
func BuildBlock(ctx *cli.Context) error {
|
func BuildBlock(ctx *cli.Context) error {
|
||||||
// Configure the go-ethereum logger
|
|
||||||
glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, false))
|
|
||||||
glogger.Verbosity(slog.Level(ctx.Int(VerbosityFlag.Name)))
|
|
||||||
log.SetDefault(log.NewLogger(glogger))
|
|
||||||
|
|
||||||
baseDir, err := createBasedir(ctx)
|
baseDir, err := createBasedir(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewError(ErrorIO, fmt.Errorf("failed creating output basedir: %v", err))
|
return NewError(ErrorIO, fmt.Errorf("failed creating output basedir: %v", err))
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ type rejectedTx struct {
|
||||||
// Apply applies a set of transactions to a pre-state
|
// Apply applies a set of transactions to a pre-state
|
||||||
func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
txIt txIterator, miningReward int64,
|
txIt txIterator, miningReward int64,
|
||||||
getTracerFn func(txIndex int, txHash common.Hash) (tracer vm.EVMLogger, err error)) (*state.StateDB, *ExecutionResult, []byte, error) {
|
getTracerFn func(txIndex int, txHash common.Hash) (vm.EVMLogger, error)) (*state.StateDB, *ExecutionResult, []byte, error) {
|
||||||
// Capture errors for BLOCKHASH operation, if we haven't been supplied the
|
// Capture errors for BLOCKHASH operation, if we haven't been supplied the
|
||||||
// required blockhashes
|
// required blockhashes
|
||||||
var hashError error
|
var hashError error
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,15 @@ import (
|
||||||
var (
|
var (
|
||||||
TraceFlag = &cli.BoolFlag{
|
TraceFlag = &cli.BoolFlag{
|
||||||
Name: "trace",
|
Name: "trace",
|
||||||
Usage: "Output full trace logs to files <txhash>.jsonl",
|
Usage: "Configures the use of the JSON opcode tracer. This tracer emits traces to files as trace-<txIndex>-<txHash>.jsonl",
|
||||||
}
|
}
|
||||||
TraceDisableMemoryFlag = &cli.BoolFlag{
|
TraceTracerFlag = &cli.StringFlag{
|
||||||
Name: "trace.nomemory",
|
Name: "trace.tracer",
|
||||||
Value: true,
|
Usage: "Configures the use of a custom tracer, e.g native or js tracers. Examples are callTracer and 4byteTracer. These tracers emit results into files as trace-<txIndex>-<txHash>.json",
|
||||||
Usage: "Disable full memory dump in traces (deprecated)",
|
}
|
||||||
|
TraceTracerConfigFlag = &cli.StringFlag{
|
||||||
|
Name: "trace.jsonconfig",
|
||||||
|
Usage: "The configurations for the custom tracer specified by --trace.tracer. If provided, must be in JSON format",
|
||||||
}
|
}
|
||||||
TraceEnableMemoryFlag = &cli.BoolFlag{
|
TraceEnableMemoryFlag = &cli.BoolFlag{
|
||||||
Name: "trace.memory",
|
Name: "trace.memory",
|
||||||
|
|
@ -43,11 +46,6 @@ var (
|
||||||
Name: "trace.nostack",
|
Name: "trace.nostack",
|
||||||
Usage: "Disable stack output in traces",
|
Usage: "Disable stack output in traces",
|
||||||
}
|
}
|
||||||
TraceDisableReturnDataFlag = &cli.BoolFlag{
|
|
||||||
Name: "trace.noreturndata",
|
|
||||||
Value: true,
|
|
||||||
Usage: "Disable return data output in traces (deprecated)",
|
|
||||||
}
|
|
||||||
TraceEnableReturnDataFlag = &cli.BoolFlag{
|
TraceEnableReturnDataFlag = &cli.BoolFlag{
|
||||||
Name: "trace.returndata",
|
Name: "trace.returndata",
|
||||||
Usage: "Enable return data output in traces",
|
Usage: "Enable return data output in traces",
|
||||||
|
|
|
||||||
81
cmd/evm/internal/t8ntool/tracewriter.go
Normal file
81
cmd/evm/internal/t8ntool/tracewriter.go
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
// Copyright 2020 The go-ethereum Authors
|
||||||
|
// This file is part of go-ethereum.
|
||||||
|
//
|
||||||
|
// go-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// go-ethereum 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 General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package t8ntool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// traceWriter is an vm.EVMLogger which also holds an inner logger/tracer.
|
||||||
|
// When the TxEnd event happens, the inner tracer result is written to the file, and
|
||||||
|
// the file is closed.
|
||||||
|
type traceWriter struct {
|
||||||
|
inner vm.EVMLogger
|
||||||
|
f io.WriteCloser
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile-time interface check
|
||||||
|
var _ = vm.EVMLogger((*traceWriter)(nil))
|
||||||
|
|
||||||
|
func (t *traceWriter) CaptureTxEnd(restGas uint64) {
|
||||||
|
t.inner.CaptureTxEnd(restGas)
|
||||||
|
defer t.f.Close()
|
||||||
|
|
||||||
|
if tracer, ok := t.inner.(tracers.Tracer); ok {
|
||||||
|
result, err := tracer.GetResult()
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("Error in tracer", "err", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = json.NewEncoder(t.f).Encode(result)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("Error writing tracer output", "err", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *traceWriter) CaptureTxStart(gasLimit uint64) { t.inner.CaptureTxStart(gasLimit) }
|
||||||
|
func (t *traceWriter) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
|
||||||
|
t.inner.CaptureStart(env, from, to, create, input, gas, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *traceWriter) CaptureEnd(output []byte, gasUsed uint64, err error) {
|
||||||
|
t.inner.CaptureEnd(output, gasUsed, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *traceWriter) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
|
||||||
|
t.inner.CaptureEnter(typ, from, to, input, gas, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *traceWriter) CaptureExit(output []byte, gasUsed uint64, err error) {
|
||||||
|
t.inner.CaptureExit(output, gasUsed, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *traceWriter) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
|
||||||
|
t.inner.CaptureState(pc, op, gas, cost, scope, rData, depth, err)
|
||||||
|
}
|
||||||
|
func (t *traceWriter) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
|
||||||
|
t.inner.CaptureFault(pc, op, gas, cost, scope, depth, err)
|
||||||
|
}
|
||||||
|
|
@ -28,12 +28,10 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/tests"
|
"github.com/ethereum/go-ethereum/tests"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"golang.org/x/exp/slog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type result struct {
|
type result struct {
|
||||||
|
|
@ -66,11 +64,6 @@ func (r *result) MarshalJSON() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Transaction(ctx *cli.Context) error {
|
func Transaction(ctx *cli.Context) error {
|
||||||
// Configure the go-ethereum logger
|
|
||||||
glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, false))
|
|
||||||
glogger.Verbosity(slog.Level(ctx.Int(VerbosityFlag.Name)))
|
|
||||||
log.SetDefault(log.NewLogger(glogger))
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"golang.org/x/exp/slog"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
||||||
|
|
@ -33,6 +31,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
@ -82,62 +81,43 @@ type input struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Transition(ctx *cli.Context) error {
|
func Transition(ctx *cli.Context) error {
|
||||||
// Configure the go-ethereum logger
|
var getTracer = func(txIndex int, txHash common.Hash) (vm.EVMLogger, error) { return nil, nil }
|
||||||
glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, false))
|
|
||||||
glogger.Verbosity(slog.Level(ctx.Int(VerbosityFlag.Name)))
|
|
||||||
log.SetDefault(log.NewLogger(glogger))
|
|
||||||
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
tracer vm.EVMLogger
|
|
||||||
)
|
|
||||||
var getTracer func(txIndex int, txHash common.Hash) (vm.EVMLogger, error)
|
|
||||||
|
|
||||||
baseDir, err := createBasedir(ctx)
|
baseDir, err := createBasedir(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewError(ErrorIO, fmt.Errorf("failed creating output basedir: %v", err))
|
return NewError(ErrorIO, fmt.Errorf("failed creating output basedir: %v", err))
|
||||||
}
|
}
|
||||||
if ctx.Bool(TraceFlag.Name) {
|
|
||||||
if ctx.IsSet(TraceDisableMemoryFlag.Name) && ctx.IsSet(TraceEnableMemoryFlag.Name) {
|
if ctx.Bool(TraceFlag.Name) { // JSON opcode tracing
|
||||||
return NewError(ErrorConfig, fmt.Errorf("can't use both flags --%s and --%s", TraceDisableMemoryFlag.Name, TraceEnableMemoryFlag.Name))
|
|
||||||
}
|
|
||||||
if ctx.IsSet(TraceDisableReturnDataFlag.Name) && ctx.IsSet(TraceEnableReturnDataFlag.Name) {
|
|
||||||
return NewError(ErrorConfig, fmt.Errorf("can't use both flags --%s and --%s", TraceDisableReturnDataFlag.Name, TraceEnableReturnDataFlag.Name))
|
|
||||||
}
|
|
||||||
if ctx.IsSet(TraceDisableMemoryFlag.Name) {
|
|
||||||
log.Warn(fmt.Sprintf("--%s has been deprecated in favour of --%s", TraceDisableMemoryFlag.Name, TraceEnableMemoryFlag.Name))
|
|
||||||
}
|
|
||||||
if ctx.IsSet(TraceDisableReturnDataFlag.Name) {
|
|
||||||
log.Warn(fmt.Sprintf("--%s has been deprecated in favour of --%s", TraceDisableReturnDataFlag.Name, TraceEnableReturnDataFlag.Name))
|
|
||||||
}
|
|
||||||
// Configure the EVM logger
|
// Configure the EVM logger
|
||||||
logConfig := &logger.Config{
|
logConfig := &logger.Config{
|
||||||
DisableStack: ctx.Bool(TraceDisableStackFlag.Name),
|
DisableStack: ctx.Bool(TraceDisableStackFlag.Name),
|
||||||
EnableMemory: !ctx.Bool(TraceDisableMemoryFlag.Name) || ctx.Bool(TraceEnableMemoryFlag.Name),
|
EnableMemory: ctx.Bool(TraceEnableMemoryFlag.Name),
|
||||||
EnableReturnData: !ctx.Bool(TraceDisableReturnDataFlag.Name) || ctx.Bool(TraceEnableReturnDataFlag.Name),
|
EnableReturnData: ctx.Bool(TraceEnableReturnDataFlag.Name),
|
||||||
Debug: true,
|
Debug: true,
|
||||||
}
|
}
|
||||||
var prevFile *os.File
|
|
||||||
// This one closes the last file
|
|
||||||
defer func() {
|
|
||||||
if prevFile != nil {
|
|
||||||
prevFile.Close()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
getTracer = func(txIndex int, txHash common.Hash) (vm.EVMLogger, error) {
|
getTracer = func(txIndex int, txHash common.Hash) (vm.EVMLogger, error) {
|
||||||
if prevFile != nil {
|
|
||||||
prevFile.Close()
|
|
||||||
}
|
|
||||||
traceFile, err := os.Create(path.Join(baseDir, fmt.Sprintf("trace-%d-%v.jsonl", txIndex, txHash.String())))
|
traceFile, err := os.Create(path.Join(baseDir, fmt.Sprintf("trace-%d-%v.jsonl", txIndex, txHash.String())))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err))
|
return nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err))
|
||||||
}
|
}
|
||||||
prevFile = traceFile
|
return &traceWriter{logger.NewJSONLogger(logConfig, traceFile), traceFile}, nil
|
||||||
return logger.NewJSONLogger(logConfig, traceFile), nil
|
|
||||||
}
|
}
|
||||||
} else {
|
} else if ctx.IsSet(TraceTracerFlag.Name) {
|
||||||
getTracer = func(txIndex int, txHash common.Hash) (tracer vm.EVMLogger, err error) {
|
var config json.RawMessage
|
||||||
return nil, nil
|
if ctx.IsSet(TraceTracerConfigFlag.Name) {
|
||||||
|
config = []byte(ctx.String(TraceTracerConfigFlag.Name))
|
||||||
|
}
|
||||||
|
getTracer = func(txIndex int, txHash common.Hash) (vm.EVMLogger, error) {
|
||||||
|
traceFile, err := os.Create(path.Join(baseDir, fmt.Sprintf("trace-%d-%v.json", txIndex, txHash.String())))
|
||||||
|
if err != nil {
|
||||||
|
return nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err))
|
||||||
|
}
|
||||||
|
tracer, err := tracers.DefaultDirectory.New(ctx.String(TraceTracerFlag.Name), nil, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, NewError(ErrorConfig, fmt.Errorf("failed instantiating tracer: %w", err))
|
||||||
|
}
|
||||||
|
return &traceWriter{tracer, traceFile}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We need to load three things: alloc, env and transactions. May be either in
|
// We need to load three things: alloc, env and transactions. May be either in
|
||||||
|
|
@ -176,9 +156,7 @@ func Transition(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
prestate.Env = *inputData.Env
|
prestate.Env = *inputData.Env
|
||||||
|
|
||||||
vmConfig := vm.Config{
|
vmConfig := vm.Config{}
|
||||||
Tracer: tracer,
|
|
||||||
}
|
|
||||||
// Construct the chainconfig
|
// Construct the chainconfig
|
||||||
var chainConfig *params.ChainConfig
|
var chainConfig *params.ChainConfig
|
||||||
if cConf, extraEips, err := tests.GetChainConfig(ctx.String(ForknameFlag.Name)); err != nil {
|
if cConf, extraEips, err := tests.GetChainConfig(ctx.String(ForknameFlag.Name)); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/internal/debug"
|
"github.com/ethereum/go-ethereum/internal/debug"
|
||||||
"github.com/ethereum/go-ethereum/internal/flags"
|
"github.com/ethereum/go-ethereum/internal/flags"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
|
// Force-load the tracer engines to trigger registration
|
||||||
|
_ "github.com/ethereum/go-ethereum/eth/tracers/js"
|
||||||
|
_ "github.com/ethereum/go-ethereum/eth/tracers/native"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -143,10 +147,10 @@ var stateTransitionCommand = &cli.Command{
|
||||||
Action: t8ntool.Transition,
|
Action: t8ntool.Transition,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
t8ntool.TraceFlag,
|
t8ntool.TraceFlag,
|
||||||
t8ntool.TraceDisableMemoryFlag,
|
t8ntool.TraceTracerFlag,
|
||||||
|
t8ntool.TraceTracerConfigFlag,
|
||||||
t8ntool.TraceEnableMemoryFlag,
|
t8ntool.TraceEnableMemoryFlag,
|
||||||
t8ntool.TraceDisableStackFlag,
|
t8ntool.TraceDisableStackFlag,
|
||||||
t8ntool.TraceDisableReturnDataFlag,
|
|
||||||
t8ntool.TraceEnableReturnDataFlag,
|
t8ntool.TraceEnableReturnDataFlag,
|
||||||
t8ntool.OutputBasedir,
|
t8ntool.OutputBasedir,
|
||||||
t8ntool.OutputAllocFlag,
|
t8ntool.OutputAllocFlag,
|
||||||
|
|
@ -158,7 +162,6 @@ var stateTransitionCommand = &cli.Command{
|
||||||
t8ntool.ForknameFlag,
|
t8ntool.ForknameFlag,
|
||||||
t8ntool.ChainIDFlag,
|
t8ntool.ChainIDFlag,
|
||||||
t8ntool.RewardFlag,
|
t8ntool.RewardFlag,
|
||||||
t8ntool.VerbosityFlag,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,7 +174,6 @@ var transactionCommand = &cli.Command{
|
||||||
t8ntool.InputTxsFlag,
|
t8ntool.InputTxsFlag,
|
||||||
t8ntool.ChainIDFlag,
|
t8ntool.ChainIDFlag,
|
||||||
t8ntool.ForknameFlag,
|
t8ntool.ForknameFlag,
|
||||||
t8ntool.VerbosityFlag,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,7 +190,6 @@ var blockBuilderCommand = &cli.Command{
|
||||||
t8ntool.InputWithdrawalsFlag,
|
t8ntool.InputWithdrawalsFlag,
|
||||||
t8ntool.InputTxsRlpFlag,
|
t8ntool.InputTxsRlpFlag,
|
||||||
t8ntool.SealCliqueFlag,
|
t8ntool.SealCliqueFlag,
|
||||||
t8ntool.VerbosityFlag,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ func runCmd(ctx *cli.Context) error {
|
||||||
initialGas = genesisConfig.GasLimit
|
initialGas = genesisConfig.GasLimit
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
genesisConfig.Config = params.AllEthashProtocolChanges
|
genesisConfig.Config = params.AllDevChainProtocolChanges
|
||||||
}
|
}
|
||||||
|
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
|
|
|
||||||
|
|
@ -467,6 +467,20 @@ func (t *freezerTable) truncateHead(items uint64) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sizeHidden returns the total data size of hidden items in the freezer table.
|
||||||
|
// This function assumes the lock is already held.
|
||||||
|
func (t *freezerTable) sizeHidden() (uint64, error) {
|
||||||
|
hidden, offset := t.itemHidden.Load(), t.itemOffset.Load()
|
||||||
|
if hidden <= offset {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
indices, err := t.getIndices(hidden-1, 1)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return uint64(indices[1].offset), nil
|
||||||
|
}
|
||||||
|
|
||||||
// truncateTail discards any recent data before the provided threshold number.
|
// truncateTail discards any recent data before the provided threshold number.
|
||||||
func (t *freezerTable) truncateTail(items uint64) error {
|
func (t *freezerTable) truncateTail(items uint64) error {
|
||||||
t.lock.Lock()
|
t.lock.Lock()
|
||||||
|
|
@ -495,6 +509,12 @@ func (t *freezerTable) truncateTail(items uint64) error {
|
||||||
newTail.unmarshalBinary(buffer)
|
newTail.unmarshalBinary(buffer)
|
||||||
newTailId = newTail.filenum
|
newTailId = newTail.filenum
|
||||||
}
|
}
|
||||||
|
// Save the old size for metrics tracking. This needs to be done
|
||||||
|
// before any updates to either itemHidden or itemOffset.
|
||||||
|
oldSize, err := t.sizeNolock()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// Update the virtual tail marker and hidden these entries in table.
|
// Update the virtual tail marker and hidden these entries in table.
|
||||||
t.itemHidden.Store(items)
|
t.itemHidden.Store(items)
|
||||||
if err := writeMetadata(t.meta, newMetadata(items)); err != nil {
|
if err := writeMetadata(t.meta, newMetadata(items)); err != nil {
|
||||||
|
|
@ -509,18 +529,12 @@ func (t *freezerTable) truncateTail(items uint64) error {
|
||||||
if t.tailId > newTailId {
|
if t.tailId > newTailId {
|
||||||
return fmt.Errorf("invalid index, tail-file %d, item-file %d", t.tailId, newTailId)
|
return fmt.Errorf("invalid index, tail-file %d, item-file %d", t.tailId, newTailId)
|
||||||
}
|
}
|
||||||
// Hidden items exceed the current tail file, drop the relevant
|
|
||||||
// data files. We need to truncate, save the old size for metrics
|
|
||||||
// tracking.
|
|
||||||
oldSize, err := t.sizeNolock()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Count how many items can be deleted from the file.
|
// Count how many items can be deleted from the file.
|
||||||
var (
|
var (
|
||||||
newDeleted = items
|
newDeleted = items
|
||||||
deleted = t.itemOffset.Load()
|
deleted = t.itemOffset.Load()
|
||||||
)
|
)
|
||||||
|
// Hidden items exceed the current tail file, drop the relevant data files.
|
||||||
for current := items - 1; current >= deleted; current -= 1 {
|
for current := items - 1; current >= deleted; current -= 1 {
|
||||||
if _, err := t.index.ReadAt(buffer, int64((current-deleted+1)*indexEntrySize)); err != nil {
|
if _, err := t.index.ReadAt(buffer, int64((current-deleted+1)*indexEntrySize)); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -680,6 +694,7 @@ func (t *freezerTable) releaseFilesBefore(num uint32, remove bool) {
|
||||||
func (t *freezerTable) getIndices(from, count uint64) ([]*indexEntry, error) {
|
func (t *freezerTable) getIndices(from, count uint64) ([]*indexEntry, error) {
|
||||||
// Apply the table-offset
|
// Apply the table-offset
|
||||||
from = from - t.itemOffset.Load()
|
from = from - t.itemOffset.Load()
|
||||||
|
|
||||||
// For reading N items, we need N+1 indices.
|
// For reading N items, we need N+1 indices.
|
||||||
buffer := make([]byte, (count+1)*indexEntrySize)
|
buffer := make([]byte, (count+1)*indexEntrySize)
|
||||||
if _, err := t.index.ReadAt(buffer, int64(from*indexEntrySize)); err != nil {
|
if _, err := t.index.ReadAt(buffer, int64(from*indexEntrySize)); err != nil {
|
||||||
|
|
@ -870,14 +885,18 @@ func (t *freezerTable) size() (uint64, error) {
|
||||||
return t.sizeNolock()
|
return t.sizeNolock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// sizeNolock returns the total data size in the freezer table without obtaining
|
// sizeNolock returns the total data size in the freezer table. This function
|
||||||
// the mutex first.
|
// assumes the lock is already held.
|
||||||
func (t *freezerTable) sizeNolock() (uint64, error) {
|
func (t *freezerTable) sizeNolock() (uint64, error) {
|
||||||
stat, err := t.index.Stat()
|
stat, err := t.index.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
total := uint64(t.maxFileSize)*uint64(t.headId-t.tailId) + uint64(t.headBytes) + uint64(stat.Size())
|
hidden, err := t.sizeHidden()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
total := uint64(t.maxFileSize)*uint64(t.headId-t.tailId) + uint64(t.headBytes) + uint64(stat.Size()) - hidden
|
||||||
return total, nil
|
return total, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -658,6 +658,13 @@ func TestFreezerOffset(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func assertTableSize(t *testing.T, f *freezerTable, size int) {
|
||||||
|
t.Helper()
|
||||||
|
if got, err := f.size(); got != uint64(size) {
|
||||||
|
t.Fatalf("expected size of %d bytes, got %d, err: %v", size, got, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestTruncateTail(t *testing.T) {
|
func TestTruncateTail(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
rm, wm, sg := metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge()
|
rm, wm, sg := metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge()
|
||||||
|
|
@ -692,6 +699,9 @@ func TestTruncateTail(t *testing.T) {
|
||||||
5: getChunk(20, 0xaa),
|
5: getChunk(20, 0xaa),
|
||||||
6: getChunk(20, 0x11),
|
6: getChunk(20, 0x11),
|
||||||
})
|
})
|
||||||
|
// maxFileSize*fileCount + headBytes + indexFileSize - hiddenBytes
|
||||||
|
expected := 20*7 + 48 - 0
|
||||||
|
assertTableSize(t, f, expected)
|
||||||
|
|
||||||
// truncate single element( item 0 ), deletion is only supported at file level
|
// truncate single element( item 0 ), deletion is only supported at file level
|
||||||
f.truncateTail(1)
|
f.truncateTail(1)
|
||||||
|
|
@ -707,6 +717,8 @@ func TestTruncateTail(t *testing.T) {
|
||||||
5: getChunk(20, 0xaa),
|
5: getChunk(20, 0xaa),
|
||||||
6: getChunk(20, 0x11),
|
6: getChunk(20, 0x11),
|
||||||
})
|
})
|
||||||
|
expected = 20*7 + 48 - 20
|
||||||
|
assertTableSize(t, f, expected)
|
||||||
|
|
||||||
// Reopen the table, the deletion information should be persisted as well
|
// Reopen the table, the deletion information should be persisted as well
|
||||||
f.Close()
|
f.Close()
|
||||||
|
|
@ -739,6 +751,8 @@ func TestTruncateTail(t *testing.T) {
|
||||||
5: getChunk(20, 0xaa),
|
5: getChunk(20, 0xaa),
|
||||||
6: getChunk(20, 0x11),
|
6: getChunk(20, 0x11),
|
||||||
})
|
})
|
||||||
|
expected = 20*5 + 36 - 0
|
||||||
|
assertTableSize(t, f, expected)
|
||||||
|
|
||||||
// Reopen the table, the above testing should still pass
|
// Reopen the table, the above testing should still pass
|
||||||
f.Close()
|
f.Close()
|
||||||
|
|
@ -760,6 +774,23 @@ func TestTruncateTail(t *testing.T) {
|
||||||
6: getChunk(20, 0x11),
|
6: getChunk(20, 0x11),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// truncate 3 more elements( item 2, 3, 4), the file 1 should be deleted
|
||||||
|
// file 2 should only contain item 5
|
||||||
|
f.truncateTail(5)
|
||||||
|
checkRetrieveError(t, f, map[uint64]error{
|
||||||
|
0: errOutOfBounds,
|
||||||
|
1: errOutOfBounds,
|
||||||
|
2: errOutOfBounds,
|
||||||
|
3: errOutOfBounds,
|
||||||
|
4: errOutOfBounds,
|
||||||
|
})
|
||||||
|
checkRetrieve(t, f, map[uint64][]byte{
|
||||||
|
5: getChunk(20, 0xaa),
|
||||||
|
6: getChunk(20, 0x11),
|
||||||
|
})
|
||||||
|
expected = 20*3 + 24 - 20
|
||||||
|
assertTableSize(t, f, expected)
|
||||||
|
|
||||||
// truncate all, the entire freezer should be deleted
|
// truncate all, the entire freezer should be deleted
|
||||||
f.truncateTail(7)
|
f.truncateTail(7)
|
||||||
checkRetrieveError(t, f, map[uint64]error{
|
checkRetrieveError(t, f, map[uint64]error{
|
||||||
|
|
@ -771,6 +802,8 @@ func TestTruncateTail(t *testing.T) {
|
||||||
5: errOutOfBounds,
|
5: errOutOfBounds,
|
||||||
6: errOutOfBounds,
|
6: errOutOfBounds,
|
||||||
})
|
})
|
||||||
|
expected = 12
|
||||||
|
assertTableSize(t, f, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTruncateHead(t *testing.T) {
|
func TestTruncateHead(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -738,7 +738,7 @@ func (p *BlobPool) offload(addr common.Address, nonce uint64, id uint64, inclusi
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset implements txpool.SubPool, allowing the blob pool's internal state to be
|
// Reset implements txpool.SubPool, allowing the blob pool's internal state to be
|
||||||
// kept in sync with the main transacion pool's internal state.
|
// kept in sync with the main transaction pool's internal state.
|
||||||
func (p *BlobPool) Reset(oldHead, newHead *types.Header) {
|
func (p *BlobPool) Reset(oldHead, newHead *types.Header) {
|
||||||
waitStart := time.Now()
|
waitStart := time.Now()
|
||||||
p.lock.Lock()
|
p.lock.Lock()
|
||||||
|
|
@ -972,7 +972,7 @@ func (p *BlobPool) reinject(addr common.Address, txhash common.Hash) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetGasTip implements txpool.SubPool, allowing the blob pool's gas requirements
|
// SetGasTip implements txpool.SubPool, allowing the blob pool's gas requirements
|
||||||
// to be kept in sync with the main transacion pool's gas requirements.
|
// to be kept in sync with the main transaction pool's gas requirements.
|
||||||
func (p *BlobPool) SetGasTip(tip *big.Int) {
|
func (p *BlobPool) SetGasTip(tip *big.Int) {
|
||||||
p.lock.Lock()
|
p.lock.Lock()
|
||||||
defer p.lock.Unlock()
|
defer p.lock.Unlock()
|
||||||
|
|
|
||||||
|
|
@ -594,7 +594,7 @@ func TestOpenDrops(t *testing.T) {
|
||||||
verifyPoolInternals(t, pool)
|
verifyPoolInternals(t, pool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that transactions loaded from disk are indexed corrently.
|
// Tests that transactions loaded from disk are indexed correctly.
|
||||||
//
|
//
|
||||||
// - 1. Transactions must be groupped by sender, sorted by nonce
|
// - 1. Transactions must be groupped by sender, sorted by nonce
|
||||||
// - 2. Eviction thresholds are calculated correctly for the sequences
|
// - 2. Eviction thresholds are calculated correctly for the sequences
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ var (
|
||||||
pooltipGauge = metrics.NewRegisteredGauge("blobpool/pooltip", nil)
|
pooltipGauge = metrics.NewRegisteredGauge("blobpool/pooltip", nil)
|
||||||
|
|
||||||
// addwait/time, resetwait/time and getwait/time track the rough health of
|
// addwait/time, resetwait/time and getwait/time track the rough health of
|
||||||
// the pool and wether or not it's capable of keeping up with the load from
|
// the pool and whether or not it's capable of keeping up with the load from
|
||||||
// the network.
|
// the network.
|
||||||
addwaitHist = metrics.NewRegisteredHistogram("blobpool/addwait", nil, metrics.NewExpDecaySample(1028, 0.015))
|
addwaitHist = metrics.NewRegisteredHistogram("blobpool/addwait", nil, metrics.NewExpDecaySample(1028, 0.015))
|
||||||
addtimeHist = metrics.NewRegisteredHistogram("blobpool/addtime", nil, metrics.NewExpDecaySample(1028, 0.015))
|
addtimeHist = metrics.NewRegisteredHistogram("blobpool/addtime", nil, metrics.NewExpDecaySample(1028, 0.015))
|
||||||
|
|
|
||||||
|
|
@ -671,7 +671,7 @@ func TestColdAccountAccessCost(t *testing.T) {
|
||||||
for ii, op := range tracer.StructLogs() {
|
for ii, op := range tracer.StructLogs() {
|
||||||
t.Logf("%d: %v %d", ii, op.OpName(), op.GasCost)
|
t.Logf("%d: %v %d", ii, op.OpName(), op.GasCost)
|
||||||
}
|
}
|
||||||
t.Fatalf("tescase %d, gas report wrong, step %d, have %d want %d", i, tc.step, have, want)
|
t.Fatalf("testcase %d, gas report wrong, step %d, have %d want %d", i, tc.step, have, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -576,7 +576,7 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td, ttd *
|
||||||
// For non-merged networks, if there is a checkpoint available, then calculate
|
// For non-merged networks, if there is a checkpoint available, then calculate
|
||||||
// the ancientLimit through that. Otherwise calculate the ancient limit through
|
// the ancientLimit through that. Otherwise calculate the ancient limit through
|
||||||
// the advertised height of the remote peer. This most is mostly a fallback for
|
// the advertised height of the remote peer. This most is mostly a fallback for
|
||||||
// legacy networks, but should eventually be droppped. TODO(karalabe).
|
// legacy networks, but should eventually be dropped. TODO(karalabe).
|
||||||
if beaconMode {
|
if beaconMode {
|
||||||
// Beacon sync, use the latest finalized block as the ancient limit
|
// Beacon sync, use the latest finalized block as the ancient limit
|
||||||
// or a reasonable height if no finalized block is yet announced.
|
// or a reasonable height if no finalized block is yet announced.
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ func (r *resultStore) HasCompletedItems() bool {
|
||||||
// countCompleted returns the number of items ready for delivery, stopping at
|
// countCompleted returns the number of items ready for delivery, stopping at
|
||||||
// the first non-complete item.
|
// the first non-complete item.
|
||||||
//
|
//
|
||||||
// The mthod assumes (at least) rlock is held.
|
// The method assumes (at least) rlock is held.
|
||||||
func (r *resultStore) countCompleted() int {
|
func (r *resultStore) countCompleted() int {
|
||||||
// We iterate from the already known complete point, and see
|
// We iterate from the already known complete point, and see
|
||||||
// if any more has completed since last count
|
// if any more has completed since last count
|
||||||
|
|
|
||||||
|
|
@ -450,7 +450,7 @@ func testCallContract(t *testing.T, client *rpc.Client) {
|
||||||
func TestOverrideAccountMarshal(t *testing.T) {
|
func TestOverrideAccountMarshal(t *testing.T) {
|
||||||
om := map[common.Address]OverrideAccount{
|
om := map[common.Address]OverrideAccount{
|
||||||
{0x11}: {
|
{0x11}: {
|
||||||
// Zero-valued nonce is not overriddden, but simply dropped by the encoder.
|
// Zero-valued nonce is not overridden, but simply dropped by the encoder.
|
||||||
Nonce: 0,
|
Nonce: 0,
|
||||||
},
|
},
|
||||||
{0xaa}: {
|
{0xaa}: {
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -68,7 +68,7 @@ require (
|
||||||
github.com/urfave/cli/v2 v2.25.7
|
github.com/urfave/cli/v2 v2.25.7
|
||||||
go.uber.org/automaxprocs v1.5.2
|
go.uber.org/automaxprocs v1.5.2
|
||||||
go.uber.org/zap v1.26.0
|
go.uber.org/zap v1.26.0
|
||||||
golang.org/x/crypto v0.15.0
|
golang.org/x/crypto v0.17.0
|
||||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
||||||
golang.org/x/sync v0.5.0
|
golang.org/x/sync v0.5.0
|
||||||
golang.org/x/sys v0.15.0
|
golang.org/x/sys v0.15.0
|
||||||
|
|
|
||||||
6
go.sum
6
go.sum
|
|
@ -567,7 +567,6 @@ github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobt
|
||||||
github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg=
|
github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
|
@ -618,7 +617,6 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
|
||||||
go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME=
|
go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME=
|
||||||
go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
||||||
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||||
|
|
@ -637,8 +635,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
|
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||||
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
|
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,20 @@ func MustRunCommand(cmd string, args ...string) {
|
||||||
MustRun(exec.Command(cmd, args...))
|
MustRun(exec.Command(cmd, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MustRunCommandWithOutput runs the given command, and ensures that some output will be
|
||||||
|
// printed while it runs. This is useful for CI builds where the process will be stopped
|
||||||
|
// when there is no output.
|
||||||
|
func MustRunCommandWithOutput(cmd string, args ...string) {
|
||||||
|
interval := time.NewTicker(time.Minute)
|
||||||
|
defer interval.Stop()
|
||||||
|
go func() {
|
||||||
|
for range interval.C {
|
||||||
|
fmt.Printf("Waiting for command %q\n", cmd)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
MustRun(exec.Command(cmd, args...))
|
||||||
|
}
|
||||||
|
|
||||||
var warnedAboutGit bool
|
var warnedAboutGit bool
|
||||||
|
|
||||||
// RunGit runs a git subcommand and returns its output.
|
// RunGit runs a git subcommand and returns its output.
|
||||||
|
|
|
||||||
|
|
@ -137,20 +137,35 @@ func (args *TransactionArgs) setFeeDefaults(ctx context.Context, b Backend) erro
|
||||||
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
|
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
|
||||||
return errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
return errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||||
}
|
}
|
||||||
// If the tx has completely specified a fee mechanism, no default is needed. This allows users
|
// If the tx has completely specified a fee mechanism, no default is needed.
|
||||||
// who are not yet synced past London to get defaults for other tx values. See
|
// This allows users who are not yet synced past London to get defaults for
|
||||||
// https://github.com/ethereum/go-ethereum/pull/23274 for more information.
|
// other tx values. See https://github.com/ethereum/go-ethereum/pull/23274
|
||||||
|
// for more information.
|
||||||
eip1559ParamsSet := args.MaxFeePerGas != nil && args.MaxPriorityFeePerGas != nil
|
eip1559ParamsSet := args.MaxFeePerGas != nil && args.MaxPriorityFeePerGas != nil
|
||||||
if (args.GasPrice != nil && !eip1559ParamsSet) || (args.GasPrice == nil && eip1559ParamsSet) {
|
|
||||||
// Sanity check the EIP-1559 fee parameters if present.
|
// Sanity check the EIP-1559 fee parameters if present.
|
||||||
if args.GasPrice == nil && args.MaxFeePerGas.ToInt().Cmp(args.MaxPriorityFeePerGas.ToInt()) < 0 {
|
if args.GasPrice == nil && eip1559ParamsSet {
|
||||||
|
if args.MaxFeePerGas.ToInt().Sign() == 0 {
|
||||||
|
return errors.New("maxFeePerGas must be non-zero")
|
||||||
|
}
|
||||||
|
if args.MaxFeePerGas.ToInt().Cmp(args.MaxPriorityFeePerGas.ToInt()) < 0 {
|
||||||
return fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", args.MaxFeePerGas, args.MaxPriorityFeePerGas)
|
return fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", args.MaxFeePerGas, args.MaxPriorityFeePerGas)
|
||||||
}
|
}
|
||||||
return nil
|
return nil // No need to set anything, user already set MaxFeePerGas and MaxPriorityFeePerGas
|
||||||
}
|
}
|
||||||
// Now attempt to fill in default value depending on whether London is active or not.
|
// Sanity check the non-EIP-1559 fee parameters.
|
||||||
head := b.CurrentHeader()
|
head := b.CurrentHeader()
|
||||||
if b.ChainConfig().IsLondon(head.Number) {
|
isLondon := b.ChainConfig().IsLondon(head.Number)
|
||||||
|
if args.GasPrice != nil && !eip1559ParamsSet {
|
||||||
|
// Zero gas-price is not allowed after London fork
|
||||||
|
if args.GasPrice.ToInt().Sign() == 0 && isLondon {
|
||||||
|
return errors.New("gasPrice must be non-zero after london fork")
|
||||||
|
}
|
||||||
|
return nil // No need to set anything, user already set GasPrice
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now attempt to fill in default value depending on whether London is active or not.
|
||||||
|
if isLondon {
|
||||||
// London is active, set maxPriorityFeePerGas and maxFeePerGas.
|
// London is active, set maxPriorityFeePerGas and maxFeePerGas.
|
||||||
if err := args.setLondonFeeDefaults(ctx, head, b); err != nil {
|
if err := args.setLondonFeeDefaults(ctx, head, b); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ func TestSetFeeDefaults(t *testing.T) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
b = newBackendMock()
|
b = newBackendMock()
|
||||||
|
zero = (*hexutil.Big)(big.NewInt(0))
|
||||||
fortytwo = (*hexutil.Big)(big.NewInt(42))
|
fortytwo = (*hexutil.Big)(big.NewInt(42))
|
||||||
maxFee = (*hexutil.Big)(new(big.Int).Add(new(big.Int).Mul(b.current.BaseFee, big.NewInt(2)), fortytwo.ToInt()))
|
maxFee = (*hexutil.Big)(new(big.Int).Add(new(big.Int).Mul(b.current.BaseFee, big.NewInt(2)), fortytwo.ToInt()))
|
||||||
al = &types.AccessList{types.AccessTuple{Address: common.Address{0xaa}, StorageKeys: []common.Hash{{0x01}}}}
|
al = &types.AccessList{types.AccessTuple{Address: common.Address{0xaa}, StorageKeys: []common.Hash{{0x01}}}}
|
||||||
|
|
@ -66,6 +67,13 @@ func TestSetFeeDefaults(t *testing.T) {
|
||||||
&TransactionArgs{GasPrice: fortytwo},
|
&TransactionArgs{GasPrice: fortytwo},
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"legacy tx pre-London with zero price",
|
||||||
|
false,
|
||||||
|
&TransactionArgs{GasPrice: zero},
|
||||||
|
&TransactionArgs{GasPrice: zero},
|
||||||
|
nil,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"legacy tx post-London, explicit gas price",
|
"legacy tx post-London, explicit gas price",
|
||||||
true,
|
true,
|
||||||
|
|
@ -73,6 +81,13 @@ func TestSetFeeDefaults(t *testing.T) {
|
||||||
&TransactionArgs{GasPrice: fortytwo},
|
&TransactionArgs{GasPrice: fortytwo},
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"legacy tx post-London with zero price",
|
||||||
|
true,
|
||||||
|
&TransactionArgs{GasPrice: zero},
|
||||||
|
nil,
|
||||||
|
errors.New("gasPrice must be non-zero after london fork"),
|
||||||
|
},
|
||||||
|
|
||||||
// Access list txs
|
// Access list txs
|
||||||
{
|
{
|
||||||
|
|
@ -161,6 +176,13 @@ func TestSetFeeDefaults(t *testing.T) {
|
||||||
nil,
|
nil,
|
||||||
errors.New("maxFeePerGas (0x7) < maxPriorityFeePerGas (0x2a)"),
|
errors.New("maxFeePerGas (0x7) < maxPriorityFeePerGas (0x2a)"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"dynamic fee tx post-London, explicit gas price",
|
||||||
|
true,
|
||||||
|
&TransactionArgs{MaxFeePerGas: zero, MaxPriorityFeePerGas: zero},
|
||||||
|
nil,
|
||||||
|
errors.New("maxFeePerGas must be non-zero"),
|
||||||
|
},
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ func MigrateGlobalFlags(ctx *cli.Context) {
|
||||||
func doMigrateFlags(ctx *cli.Context) {
|
func doMigrateFlags(ctx *cli.Context) {
|
||||||
// Figure out if there are any aliases of commands. If there are, we want
|
// Figure out if there are any aliases of commands. If there are, we want
|
||||||
// to ignore them when iterating over the flags.
|
// to ignore them when iterating over the flags.
|
||||||
var aliases = make(map[string]bool)
|
aliases := make(map[string]bool)
|
||||||
for _, fl := range ctx.Command.Flags {
|
for _, fl := range ctx.Command.Flags {
|
||||||
for _, alias := range fl.Names()[1:] {
|
for _, alias := range fl.Names()[1:] {
|
||||||
aliases[alias] = true
|
aliases[alias] = true
|
||||||
|
|
@ -239,15 +239,24 @@ func AutoEnvVars(flags []cli.Flag, prefix string) {
|
||||||
case *cli.StringFlag:
|
case *cli.StringFlag:
|
||||||
flag.EnvVars = append(flag.EnvVars, envvar)
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
|
case *cli.StringSliceFlag:
|
||||||
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
case *cli.BoolFlag:
|
case *cli.BoolFlag:
|
||||||
flag.EnvVars = append(flag.EnvVars, envvar)
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
case *cli.IntFlag:
|
case *cli.IntFlag:
|
||||||
flag.EnvVars = append(flag.EnvVars, envvar)
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
|
case *cli.Int64Flag:
|
||||||
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
case *cli.Uint64Flag:
|
case *cli.Uint64Flag:
|
||||||
flag.EnvVars = append(flag.EnvVars, envvar)
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
|
case *cli.Float64Flag:
|
||||||
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
case *cli.DurationFlag:
|
case *cli.DurationFlag:
|
||||||
flag.EnvVars = append(flag.EnvVars, envvar)
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -459,6 +459,26 @@ func (tab *Table) findnodeByID(target enode.ID, nresults int, preferLive bool) *
|
||||||
return nodes
|
return nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// appendLiveNodes adds nodes at the given distance to the result slice.
|
||||||
|
func (tab *Table) appendLiveNodes(dist uint, result []*enode.Node) []*enode.Node {
|
||||||
|
if dist > 256 {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
if dist == 0 {
|
||||||
|
return append(result, tab.self())
|
||||||
|
}
|
||||||
|
|
||||||
|
tab.mutex.Lock()
|
||||||
|
defer tab.mutex.Unlock()
|
||||||
|
for _, n := range tab.bucketAtDistance(int(dist)).entries {
|
||||||
|
if n.livenessChecks >= 1 {
|
||||||
|
node := n.Node // avoid handing out pointer to struct field
|
||||||
|
result = append(result, &node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// len returns the number of nodes in the table.
|
// len returns the number of nodes in the table.
|
||||||
func (tab *Table) len() (n int) {
|
func (tab *Table) len() (n int) {
|
||||||
tab.mutex.Lock()
|
tab.mutex.Lock()
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ func TestTable_findnodeByID(t *testing.T) {
|
||||||
tab, db := newTestTable(transport)
|
tab, db := newTestTable(transport)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
defer tab.close()
|
defer tab.close()
|
||||||
fillTable(tab, test.All)
|
fillTable(tab, test.All, true)
|
||||||
|
|
||||||
// check that closest(Target, N) returns nodes
|
// check that closest(Target, N) returns nodes
|
||||||
result := tab.findnodeByID(test.Target, test.N, false).entries
|
result := tab.findnodeByID(test.Target, test.N, false).entries
|
||||||
|
|
|
||||||
|
|
@ -109,8 +109,11 @@ func fillBucket(tab *Table, n *node) (last *node) {
|
||||||
|
|
||||||
// fillTable adds nodes the table to the end of their corresponding bucket
|
// fillTable adds nodes the table to the end of their corresponding bucket
|
||||||
// if the bucket is not full. The caller must not hold tab.mutex.
|
// if the bucket is not full. The caller must not hold tab.mutex.
|
||||||
func fillTable(tab *Table, nodes []*node) {
|
func fillTable(tab *Table, nodes []*node, setLive bool) {
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
|
if setLive {
|
||||||
|
n.livenessChecks = 1
|
||||||
|
}
|
||||||
tab.addSeenNode(n)
|
tab.addSeenNode(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,8 @@ func TestUDPv4_Lookup(t *testing.T) {
|
||||||
t.Fatalf("lookup on empty table returned %d results: %#v", len(results), results)
|
t.Fatalf("lookup on empty table returned %d results: %#v", len(results), results)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seed table with initial Node.
|
// Seed table with initial node.
|
||||||
fillTable(test.table, []*node{wrapNode(lookupTestnet.node(256, 0))})
|
fillTable(test.table, []*node{wrapNode(lookupTestnet.node(256, 0))}, true)
|
||||||
|
|
||||||
// Start the lookup.
|
// Start the lookup.
|
||||||
resultC := make(chan []*enode.Node, 1)
|
resultC := make(chan []*enode.Node, 1)
|
||||||
|
|
@ -74,7 +74,7 @@ func TestUDPv4_LookupIterator(t *testing.T) {
|
||||||
for i := range lookupTestnet.dists[256] {
|
for i := range lookupTestnet.dists[256] {
|
||||||
bootnodes[i] = wrapNode(lookupTestnet.node(256, i))
|
bootnodes[i] = wrapNode(lookupTestnet.node(256, i))
|
||||||
}
|
}
|
||||||
fillTable(test.table, bootnodes)
|
fillTable(test.table, bootnodes, true)
|
||||||
go serveTestnet(test, lookupTestnet)
|
go serveTestnet(test, lookupTestnet)
|
||||||
|
|
||||||
// Create the iterator and collect the nodes it yields.
|
// Create the iterator and collect the nodes it yields.
|
||||||
|
|
@ -109,12 +109,12 @@ func TestUDPv4_LookupIteratorClose(t *testing.T) {
|
||||||
for i := range lookupTestnet.dists[256] {
|
for i := range lookupTestnet.dists[256] {
|
||||||
bootnodes[i] = wrapNode(lookupTestnet.node(256, i))
|
bootnodes[i] = wrapNode(lookupTestnet.node(256, i))
|
||||||
}
|
}
|
||||||
fillTable(test.table, bootnodes)
|
fillTable(test.table, bootnodes, true)
|
||||||
go serveTestnet(test, lookupTestnet)
|
go serveTestnet(test, lookupTestnet)
|
||||||
|
|
||||||
it := test.udp.RandomNodes()
|
it := test.udp.RandomNodes()
|
||||||
if ok := it.Next(); !ok || it.Node() == nil {
|
if ok := it.Next(); !ok || it.Node() == nil {
|
||||||
t.Fatalf("iterator didn't return any Node")
|
t.Fatalf("iterator didn't return any node")
|
||||||
}
|
}
|
||||||
|
|
||||||
it.Close()
|
it.Close()
|
||||||
|
|
@ -122,7 +122,7 @@ func TestUDPv4_LookupIteratorClose(t *testing.T) {
|
||||||
ncalls := 0
|
ncalls := 0
|
||||||
for ; ncalls < 100 && it.Next(); ncalls++ {
|
for ; ncalls < 100 && it.Next(); ncalls++ {
|
||||||
if it.Node() == nil {
|
if it.Node() == nil {
|
||||||
t.Error("iterator returned Node() == nil Node after Next() == true")
|
t.Error("iterator returned Node() == nil node after Next() == true")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.Logf("iterator returned %d nodes after close", ncalls)
|
t.Logf("iterator returned %d nodes after close", ncalls)
|
||||||
|
|
@ -130,7 +130,7 @@ func TestUDPv4_LookupIteratorClose(t *testing.T) {
|
||||||
t.Errorf("Next() == true after close and %d more calls", ncalls)
|
t.Errorf("Next() == true after close and %d more calls", ncalls)
|
||||||
}
|
}
|
||||||
if n := it.Node(); n != nil {
|
if n := it.Node(); n != nil {
|
||||||
t.Errorf("iterator returned non-nil Node after close and %d more calls", ncalls)
|
t.Errorf("iterator returned non-nil node after close and %d more calls", ncalls)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,7 @@ func TestUDPv4_findnode(t *testing.T) {
|
||||||
}
|
}
|
||||||
nodes.push(n, numCandidates)
|
nodes.push(n, numCandidates)
|
||||||
}
|
}
|
||||||
fillTable(test.table, nodes.entries)
|
fillTable(test.table, nodes.entries, false)
|
||||||
|
|
||||||
// ensure there's a bond with the test Node,
|
// ensure there's a bond with the test Node,
|
||||||
// findnode won't be accepted otherwise.
|
// findnode won't be accepted otherwise.
|
||||||
|
|
|
||||||
|
|
@ -891,6 +891,7 @@ func (t *UDPv5) handleFindnode(p *v5wire.Findnode, fromID enode.ID, fromAddr *ne
|
||||||
|
|
||||||
// collectTableNodes creates a FINDNODE result set for the given distances.
|
// collectTableNodes creates a FINDNODE result set for the given distances.
|
||||||
func (t *UDPv5) collectTableNodes(rip net.IP, distances []uint, limit int) []*enode.Node {
|
func (t *UDPv5) collectTableNodes(rip net.IP, distances []uint, limit int) []*enode.Node {
|
||||||
|
var bn []*enode.Node
|
||||||
var nodes []*enode.Node
|
var nodes []*enode.Node
|
||||||
var processed = make(map[uint]struct{})
|
var processed = make(map[uint]struct{})
|
||||||
for _, dist := range distances {
|
for _, dist := range distances {
|
||||||
|
|
@ -899,21 +900,11 @@ func (t *UDPv5) collectTableNodes(rip net.IP, distances []uint, limit int) []*en
|
||||||
if seen || dist > 256 {
|
if seen || dist > 256 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the nodes.
|
|
||||||
var bn []*enode.Node
|
|
||||||
if dist == 0 {
|
|
||||||
bn = []*enode.Node{t.Self()}
|
|
||||||
} else if dist <= 256 {
|
|
||||||
t.tab.mutex.Lock()
|
|
||||||
bn = unwrapNodes(t.tab.bucketAtDistance(int(dist)).entries)
|
|
||||||
t.tab.mutex.Unlock()
|
|
||||||
}
|
|
||||||
processed[dist] = struct{}{}
|
processed[dist] = struct{}{}
|
||||||
|
|
||||||
// Apply some pre-checks to avoid sending invalid nodes.
|
for _, n := range t.tab.appendLiveNodes(dist, bn[:0]) {
|
||||||
for _, n := range bn {
|
// Apply some pre-checks to avoid sending invalid nodes.
|
||||||
// TODO livenessChecks > 1
|
// Note liveness is checked by appendLiveNodes.
|
||||||
if netutil.CheckRelayIP(rip, n.IP()) != nil {
|
if netutil.CheckRelayIP(rip, n.IP()) != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -159,9 +159,9 @@ func TestUDPv5_findnodeHandling(t *testing.T) {
|
||||||
nodes253 := nodesAtDistance(test.table.self().ID(), 253, 16)
|
nodes253 := nodesAtDistance(test.table.self().ID(), 253, 16)
|
||||||
nodes249 := nodesAtDistance(test.table.self().ID(), 249, 4)
|
nodes249 := nodesAtDistance(test.table.self().ID(), 249, 4)
|
||||||
nodes248 := nodesAtDistance(test.table.self().ID(), 248, 10)
|
nodes248 := nodesAtDistance(test.table.self().ID(), 248, 10)
|
||||||
fillTable(test.table, wrapNodes(nodes253))
|
fillTable(test.table, wrapNodes(nodes253), true)
|
||||||
fillTable(test.table, wrapNodes(nodes249))
|
fillTable(test.table, wrapNodes(nodes249), true)
|
||||||
fillTable(test.table, wrapNodes(nodes248))
|
fillTable(test.table, wrapNodes(nodes248), true)
|
||||||
|
|
||||||
// Requesting with distance zero should return the Node's own record.
|
// Requesting with distance zero should return the Node's own record.
|
||||||
test.packetIn(&v5wire.Findnode{ReqID: []byte{0}, Distances: []uint{0}})
|
test.packetIn(&v5wire.Findnode{ReqID: []byte{0}, Distances: []uint{0}})
|
||||||
|
|
@ -589,7 +589,7 @@ func TestUDPv5_lookup(t *testing.T) {
|
||||||
|
|
||||||
// Seed table with initial Node.
|
// Seed table with initial Node.
|
||||||
initialNode := lookupTestnet.node(256, 0)
|
initialNode := lookupTestnet.node(256, 0)
|
||||||
fillTable(test.table, []*node{wrapNode(initialNode)})
|
fillTable(test.table, []*node{wrapNode(initialNode)}, true)
|
||||||
|
|
||||||
// Start the lookup.
|
// Start the lookup.
|
||||||
resultC := make(chan []*enode.Node, 1)
|
resultC := make(chan []*enode.Node, 1)
|
||||||
|
|
|
||||||
|
|
@ -421,7 +421,7 @@ func BenchmarkThroughput(b *testing.B) {
|
||||||
}
|
}
|
||||||
conn2.SetSnappy(true)
|
conn2.SetSnappy(true)
|
||||||
if err := <-handshakeDone; err != nil {
|
if err := <-handshakeDone; err != nil {
|
||||||
b.Fatal("server hanshake error:", err)
|
b.Fatal("server handshake error:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read N messages.
|
// Read N messages.
|
||||||
|
|
|
||||||
|
|
@ -683,7 +683,7 @@ func triggerChecks(ctx context.Context, ids []enode.ID, trigger chan enode.ID, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// \todo: refactor to implement shapshots
|
// \todo: refactor to implement snapshots
|
||||||
// and connect configuration methods once these are moved from
|
// and connect configuration methods once these are moved from
|
||||||
// swarm/network/simulations/connect.go
|
// swarm/network/simulations/connect.go
|
||||||
func BenchmarkMinimalService(b *testing.B) {
|
func BenchmarkMinimalService(b *testing.B) {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import (
|
||||||
const (
|
const (
|
||||||
VersionMajor = 1 // Major version component of the current release
|
VersionMajor = 1 // Major version component of the current release
|
||||||
VersionMinor = 13 // Minor version component of the current release
|
VersionMinor = 13 // Minor version component of the current release
|
||||||
VersionPatch = 5 // Patch version component of the current release
|
VersionPatch = 8 // Patch version component of the current release
|
||||||
VersionMeta = "unstable" // Version metadata to append to the version string
|
VersionMeta = "unstable" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue