Merge branch 'master' into parity-noCreationMethod

This commit is contained in:
Sina Mahmoodi 2024-11-04 12:22:11 +01:00
commit de1625ddf5
50 changed files with 239 additions and 1057 deletions

View file

@ -53,6 +53,7 @@ import (
"path" "path"
"path/filepath" "path/filepath"
"runtime" "runtime"
"slices"
"strings" "strings"
"time" "time"
@ -226,8 +227,7 @@ func doInstall(cmdline []string) {
// Do the build! // Do the build!
for _, pkg := range packages { for _, pkg := range packages {
args := make([]string, len(gobuild.Args)) args := slices.Clone(gobuild.Args)
copy(args, gobuild.Args)
args = append(args, "-o", executablePath(path.Base(pkg))) args = append(args, "-o", executablePath(path.Base(pkg)))
args = append(args, pkg) args = append(args, pkg)
build.MustRun(&exec.Cmd{Path: gobuild.Path, Args: args, Env: gobuild.Env}) build.MustRun(&exec.Cmd{Path: gobuild.Path, Args: args, Env: gobuild.Env})

View file

@ -20,6 +20,7 @@ import (
"context" "context"
"fmt" "fmt"
"os" "os"
"slices"
"github.com/ethereum/go-ethereum/beacon/blsync" "github.com/ethereum/go-ethereum/beacon/blsync"
"github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/cmd/utils"
@ -33,7 +34,7 @@ import (
func main() { func main() {
app := flags.NewApp("beacon light syncer tool") app := flags.NewApp("beacon light syncer tool")
app.Flags = flags.Merge([]cli.Flag{ app.Flags = slices.Concat([]cli.Flag{
utils.BeaconApiFlag, utils.BeaconApiFlag,
utils.BeaconApiHeaderFlag, utils.BeaconApiHeaderFlag,
utils.BeaconThresholdFlag, utils.BeaconThresholdFlag,

View file

@ -21,6 +21,7 @@ import (
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
"slices"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -28,7 +29,6 @@ import (
"github.com/ethereum/go-ethereum/cmd/devp2p/internal/v4test" "github.com/ethereum/go-ethereum/cmd/devp2p/internal/v4test"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enode"
@ -83,7 +83,7 @@ var (
Name: "listen", Name: "listen",
Usage: "Runs a discovery node", Usage: "Runs a discovery node",
Action: discv4Listen, Action: discv4Listen,
Flags: flags.Merge(discoveryNodeFlags, []cli.Flag{ Flags: slices.Concat(discoveryNodeFlags, []cli.Flag{
httpAddrFlag, httpAddrFlag,
}), }),
} }
@ -91,7 +91,7 @@ var (
Name: "crawl", Name: "crawl",
Usage: "Updates a nodes.json file with random nodes found in the DHT", Usage: "Updates a nodes.json file with random nodes found in the DHT",
Action: discv4Crawl, Action: discv4Crawl,
Flags: flags.Merge(discoveryNodeFlags, []cli.Flag{crawlTimeoutFlag, crawlParallelismFlag}), Flags: slices.Concat(discoveryNodeFlags, []cli.Flag{crawlTimeoutFlag, crawlParallelismFlag}),
} }
discv4TestCommand = &cli.Command{ discv4TestCommand = &cli.Command{
Name: "test", Name: "test",

View file

@ -19,11 +19,11 @@ package main
import ( import (
"errors" "errors"
"fmt" "fmt"
"slices"
"time" "time"
"github.com/ethereum/go-ethereum/cmd/devp2p/internal/v5test" "github.com/ethereum/go-ethereum/cmd/devp2p/internal/v5test"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/p2p/discover"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
@ -56,7 +56,7 @@ var (
Name: "crawl", Name: "crawl",
Usage: "Updates a nodes.json file with random nodes found in the DHT", Usage: "Updates a nodes.json file with random nodes found in the DHT",
Action: discv5Crawl, Action: discv5Crawl,
Flags: flags.Merge(discoveryNodeFlags, []cli.Flag{ Flags: slices.Concat(discoveryNodeFlags, []cli.Flag{
crawlTimeoutFlag, crawlTimeoutFlag,
}), }),
} }

View file

@ -21,6 +21,7 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"os" "os"
"slices"
"github.com/ethereum/go-ethereum/cmd/evm/internal/t8ntool" "github.com/ethereum/go-ethereum/cmd/evm/internal/t8ntool"
"github.com/ethereum/go-ethereum/internal/debug" "github.com/ethereum/go-ethereum/internal/debug"
@ -254,7 +255,7 @@ var traceFlags = []cli.Flag{
var app = flags.NewApp("the evm command line interface") var app = flags.NewApp("the evm command line interface")
func init() { func init() {
app.Flags = flags.Merge(vmFlags, traceFlags, debug.Flags) app.Flags = slices.Concat(vmFlags, traceFlags, debug.Flags)
app.Commands = []*cli.Command{ app.Commands = []*cli.Command{
compileCommand, compileCommand,
disasmCommand, disasmCommand,

View file

@ -24,6 +24,7 @@ import (
"math/big" "math/big"
"os" "os"
goruntime "runtime" goruntime "runtime"
"slices"
"testing" "testing"
"time" "time"
@ -50,7 +51,7 @@ var runCommand = &cli.Command{
Usage: "Run arbitrary evm binary", Usage: "Run arbitrary evm binary",
ArgsUsage: "<code>", ArgsUsage: "<code>",
Description: `The run command runs arbitrary EVM code.`, Description: `The run command runs arbitrary EVM code.`,
Flags: flags.Merge(vmFlags, traceFlags), Flags: slices.Concat(vmFlags, traceFlags),
} }
// readGenesis will read the given JSON format genesis file and return // readGenesis will read the given JSON format genesis file and return

View file

@ -22,6 +22,7 @@ import (
"fmt" "fmt"
"os" "os"
"runtime" "runtime"
"slices"
"strconv" "strconv"
"sync/atomic" "sync/atomic"
"time" "time"
@ -36,7 +37,6 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/internal/era" "github.com/ethereum/go-ethereum/internal/era"
"github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
@ -49,7 +49,7 @@ var (
Name: "init", Name: "init",
Usage: "Bootstrap and initialize a new genesis block", Usage: "Bootstrap and initialize a new genesis block",
ArgsUsage: "<genesisPath>", ArgsUsage: "<genesisPath>",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.CachePreimagesFlag, utils.CachePreimagesFlag,
utils.OverrideCancun, utils.OverrideCancun,
utils.OverrideVerkle, utils.OverrideVerkle,
@ -76,7 +76,7 @@ if one is set. Otherwise it prints the genesis from the datadir.`,
Name: "import", Name: "import",
Usage: "Import a blockchain file", Usage: "Import a blockchain file",
ArgsUsage: "<filename> (<filename 2> ... <filename N>) ", ArgsUsage: "<filename> (<filename 2> ... <filename N>) ",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.CacheFlag, utils.CacheFlag,
utils.SyncModeFlag, utils.SyncModeFlag,
utils.GCModeFlag, utils.GCModeFlag,
@ -115,7 +115,7 @@ processing will proceed even if an individual RLP-file import failure occurs.`,
Name: "export", Name: "export",
Usage: "Export blockchain into file", Usage: "Export blockchain into file",
ArgsUsage: "<filename> [<blockNumFirst> <blockNumLast>]", ArgsUsage: "<filename> [<blockNumFirst> <blockNumLast>]",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.CacheFlag, utils.CacheFlag,
utils.SyncModeFlag, utils.SyncModeFlag,
}, utils.DatabaseFlags), }, utils.DatabaseFlags),
@ -131,7 +131,7 @@ be gzipped.`,
Name: "import-history", Name: "import-history",
Usage: "Import an Era archive", Usage: "Import an Era archive",
ArgsUsage: "<dir>", ArgsUsage: "<dir>",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.TxLookupLimitFlag, utils.TxLookupLimitFlag,
}, },
utils.DatabaseFlags, utils.DatabaseFlags,
@ -147,7 +147,7 @@ from Era archives.
Name: "export-history", Name: "export-history",
Usage: "Export blockchain history to Era archives", Usage: "Export blockchain history to Era archives",
ArgsUsage: "<dir> <first> <last>", ArgsUsage: "<dir> <first> <last>",
Flags: flags.Merge(utils.DatabaseFlags), Flags: slices.Concat(utils.DatabaseFlags),
Description: ` Description: `
The export-history command will export blocks and their corresponding receipts The export-history command will export blocks and their corresponding receipts
into Era archives. Eras are typically packaged in steps of 8192 blocks. into Era archives. Eras are typically packaged in steps of 8192 blocks.
@ -158,7 +158,7 @@ into Era archives. Eras are typically packaged in steps of 8192 blocks.
Name: "import-preimages", Name: "import-preimages",
Usage: "Import the preimage database from an RLP stream", Usage: "Import the preimage database from an RLP stream",
ArgsUsage: "<datafile>", ArgsUsage: "<datafile>",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.CacheFlag, utils.CacheFlag,
utils.SyncModeFlag, utils.SyncModeFlag,
}, utils.DatabaseFlags), }, utils.DatabaseFlags),
@ -173,7 +173,7 @@ It's deprecated, please use "geth db import" instead.
Name: "dump", Name: "dump",
Usage: "Dump a specific block from storage", Usage: "Dump a specific block from storage",
ArgsUsage: "[? <blockHash> | <blockNum>]", ArgsUsage: "[? <blockHash> | <blockNum>]",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.CacheFlag, utils.CacheFlag,
utils.IterativeOutputFlag, utils.IterativeOutputFlag,
utils.ExcludeCodeFlag, utils.ExcludeCodeFlag,

View file

@ -23,6 +23,7 @@ import (
"os" "os"
"reflect" "reflect"
"runtime" "runtime"
"slices"
"strings" "strings"
"unicode" "unicode"
@ -53,7 +54,7 @@ var (
Name: "dumpconfig", Name: "dumpconfig",
Usage: "Export configuration values in a TOML format", Usage: "Export configuration values in a TOML format",
ArgsUsage: "<dumpfile (optional)>", ArgsUsage: "<dumpfile (optional)>",
Flags: flags.Merge(nodeFlags, rpcFlags), Flags: slices.Concat(nodeFlags, rpcFlags),
Description: `Export configuration values in TOML format (to stdout by default).`, Description: `Export configuration values in TOML format (to stdout by default).`,
} }

View file

@ -18,11 +18,11 @@ package main
import ( import (
"fmt" "fmt"
"slices"
"strings" "strings"
"github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/console" "github.com/ethereum/go-ethereum/console"
"github.com/ethereum/go-ethereum/internal/flags"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
@ -33,7 +33,7 @@ var (
Action: localConsole, Action: localConsole,
Name: "console", Name: "console",
Usage: "Start an interactive JavaScript environment", Usage: "Start an interactive JavaScript environment",
Flags: flags.Merge(nodeFlags, rpcFlags, consoleFlags), Flags: slices.Concat(nodeFlags, rpcFlags, consoleFlags),
Description: ` Description: `
The Geth console is an interactive shell for the JavaScript runtime environment The Geth console is an interactive shell for the JavaScript runtime environment
which exposes a node admin interface as well as the Ðapp JavaScript API. which exposes a node admin interface as well as the Ðapp JavaScript API.
@ -45,7 +45,7 @@ See https://geth.ethereum.org/docs/interacting-with-geth/javascript-console.`,
Name: "attach", Name: "attach",
Usage: "Start an interactive JavaScript environment (connect to node)", Usage: "Start an interactive JavaScript environment (connect to node)",
ArgsUsage: "[endpoint]", ArgsUsage: "[endpoint]",
Flags: flags.Merge([]cli.Flag{utils.DataDirFlag, utils.HttpHeaderFlag}, consoleFlags), Flags: slices.Concat([]cli.Flag{utils.DataDirFlag, utils.HttpHeaderFlag}, consoleFlags),
Description: ` Description: `
The Geth console is an interactive shell for the JavaScript runtime environment The Geth console is an interactive shell for the JavaScript runtime environment
which exposes a node admin interface as well as the Ðapp JavaScript API. which exposes a node admin interface as well as the Ðapp JavaScript API.
@ -58,7 +58,7 @@ This command allows to open a console on a running geth node.`,
Name: "js", Name: "js",
Usage: "(DEPRECATED) Execute the specified JavaScript files", Usage: "(DEPRECATED) Execute the specified JavaScript files",
ArgsUsage: "<jsfile> [jsfile...]", ArgsUsage: "<jsfile> [jsfile...]",
Flags: flags.Merge(nodeFlags, consoleFlags), Flags: slices.Concat(nodeFlags, consoleFlags),
Description: ` Description: `
The JavaScript VM exposes a node admin interface as well as the Ðapp The JavaScript VM exposes a node admin interface as well as the Ðapp
JavaScript API. See https://geth.ethereum.org/docs/interacting-with-geth/javascript-console`, JavaScript API. See https://geth.ethereum.org/docs/interacting-with-geth/javascript-console`,

View file

@ -22,6 +22,7 @@ import (
"os" "os"
"os/signal" "os/signal"
"path/filepath" "path/filepath"
"slices"
"strconv" "strconv"
"strings" "strings"
"syscall" "syscall"
@ -36,7 +37,6 @@ import (
"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/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
@ -60,7 +60,7 @@ var (
Name: "removedb", Name: "removedb",
Usage: "Remove blockchain and state databases", Usage: "Remove blockchain and state databases",
ArgsUsage: "", ArgsUsage: "",
Flags: flags.Merge(utils.DatabaseFlags, Flags: slices.Concat(utils.DatabaseFlags,
[]cli.Flag{removeStateDataFlag, removeChainDataFlag}), []cli.Flag{removeStateDataFlag, removeChainDataFlag}),
Description: ` Description: `
Remove blockchain and state databases`, Remove blockchain and state databases`,
@ -89,7 +89,7 @@ Remove blockchain and state databases`,
Action: inspect, Action: inspect,
Name: "inspect", Name: "inspect",
ArgsUsage: "<prefix> <start>", ArgsUsage: "<prefix> <start>",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag, utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags), }, utils.NetworkFlags, utils.DatabaseFlags),
Usage: "Inspect the storage size for each type of data in the database", Usage: "Inspect the storage size for each type of data in the database",
@ -99,7 +99,7 @@ Remove blockchain and state databases`,
Action: checkStateContent, Action: checkStateContent,
Name: "check-state-content", Name: "check-state-content",
ArgsUsage: "<start (optional)>", ArgsUsage: "<start (optional)>",
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags), Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Usage: "Verify that state data is cryptographically correct", Usage: "Verify that state data is cryptographically correct",
Description: `This command iterates the entire database for 32-byte keys, looking for rlp-encoded trie nodes. Description: `This command iterates the entire database for 32-byte keys, looking for rlp-encoded trie nodes.
For each trie node encountered, it checks that the key corresponds to the keccak256(value). If this is not true, this indicates For each trie node encountered, it checks that the key corresponds to the keccak256(value). If this is not true, this indicates
@ -109,7 +109,7 @@ a data corruption.`,
Action: dbStats, Action: dbStats,
Name: "stats", Name: "stats",
Usage: "Print leveldb statistics", Usage: "Print leveldb statistics",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag, utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags), }, utils.NetworkFlags, utils.DatabaseFlags),
} }
@ -117,7 +117,7 @@ a data corruption.`,
Action: dbCompact, Action: dbCompact,
Name: "compact", Name: "compact",
Usage: "Compact leveldb database. WARNING: May take a very long time", Usage: "Compact leveldb database. WARNING: May take a very long time",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag, utils.SyncModeFlag,
utils.CacheFlag, utils.CacheFlag,
utils.CacheDatabaseFlag, utils.CacheDatabaseFlag,
@ -131,7 +131,7 @@ corruption if it is aborted during execution'!`,
Name: "get", Name: "get",
Usage: "Show the value of a database key", Usage: "Show the value of a database key",
ArgsUsage: "<hex-encoded key>", ArgsUsage: "<hex-encoded key>",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag, utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags), }, utils.NetworkFlags, utils.DatabaseFlags),
Description: "This command looks up the specified database key from the database.", Description: "This command looks up the specified database key from the database.",
@ -141,7 +141,7 @@ corruption if it is aborted during execution'!`,
Name: "delete", Name: "delete",
Usage: "Delete a database key (WARNING: may corrupt your database)", Usage: "Delete a database key (WARNING: may corrupt your database)",
ArgsUsage: "<hex-encoded key>", ArgsUsage: "<hex-encoded key>",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag, utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags), }, utils.NetworkFlags, utils.DatabaseFlags),
Description: `This command deletes the specified database key from the database. Description: `This command deletes the specified database key from the database.
@ -152,7 +152,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Name: "put", Name: "put",
Usage: "Set the value of a database key (WARNING: may corrupt your database)", Usage: "Set the value of a database key (WARNING: may corrupt your database)",
ArgsUsage: "<hex-encoded key> <hex-encoded value>", ArgsUsage: "<hex-encoded key> <hex-encoded value>",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag, utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags), }, utils.NetworkFlags, utils.DatabaseFlags),
Description: `This command sets a given database key to the given value. Description: `This command sets a given database key to the given value.
@ -163,7 +163,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Name: "dumptrie", Name: "dumptrie",
Usage: "Show the storage key/values of a given storage trie", Usage: "Show the storage key/values of a given storage trie",
ArgsUsage: "<hex-encoded state root> <hex-encoded account hash> <hex-encoded storage trie root> <hex-encoded start (optional)> <int max elements (optional)>", ArgsUsage: "<hex-encoded state root> <hex-encoded account hash> <hex-encoded storage trie root> <hex-encoded start (optional)> <int max elements (optional)>",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag, utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags), }, utils.NetworkFlags, utils.DatabaseFlags),
Description: "This command looks up the specified database key from the database.", Description: "This command looks up the specified database key from the database.",
@ -173,7 +173,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Name: "freezer-index", Name: "freezer-index",
Usage: "Dump out the index of a specific freezer table", Usage: "Dump out the index of a specific freezer table",
ArgsUsage: "<freezer-type> <table-type> <start (int)> <end (int)>", ArgsUsage: "<freezer-type> <table-type> <start (int)> <end (int)>",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag, utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags), }, utils.NetworkFlags, utils.DatabaseFlags),
Description: "This command displays information about the freezer index.", Description: "This command displays information about the freezer index.",
@ -183,7 +183,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Name: "import", Name: "import",
Usage: "Imports leveldb-data from an exported RLP dump.", Usage: "Imports leveldb-data from an exported RLP dump.",
ArgsUsage: "<dumpfile> <start (optional)", ArgsUsage: "<dumpfile> <start (optional)",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag, utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags), }, utils.NetworkFlags, utils.DatabaseFlags),
Description: "The import command imports the specific chain data from an RLP encoded stream.", Description: "The import command imports the specific chain data from an RLP encoded stream.",
@ -193,7 +193,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Name: "export", Name: "export",
Usage: "Exports the chain data into an RLP dump. If the <dumpfile> has .gz suffix, gzip compression will be used.", Usage: "Exports the chain data into an RLP dump. If the <dumpfile> has .gz suffix, gzip compression will be used.",
ArgsUsage: "<type> <dumpfile>", ArgsUsage: "<type> <dumpfile>",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag, utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags), }, utils.NetworkFlags, utils.DatabaseFlags),
Description: "Exports the specified chain data to an RLP encoded stream, optionally gzip-compressed.", Description: "Exports the specified chain data to an RLP encoded stream, optionally gzip-compressed.",
@ -202,7 +202,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Action: showMetaData, Action: showMetaData,
Name: "metadata", Name: "metadata",
Usage: "Shows metadata about the chain status.", Usage: "Shows metadata about the chain status.",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag, utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags), }, utils.NetworkFlags, utils.DatabaseFlags),
Description: "Shows metadata about the chain status.", Description: "Shows metadata about the chain status.",
@ -212,7 +212,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Name: "inspect-history", Name: "inspect-history",
Usage: "Inspect the state history within block range", Usage: "Inspect the state history within block range",
ArgsUsage: "<address> [OPTIONAL <storage-slot>]", ArgsUsage: "<address> [OPTIONAL <storage-slot>]",
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.SyncModeFlag, utils.SyncModeFlag,
&cli.Uint64Flag{ &cli.Uint64Flag{
Name: "start", Name: "start",

View file

@ -20,6 +20,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"slices"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@ -53,7 +54,7 @@ const (
var ( var (
// flags that configure the node // flags that configure the node
nodeFlags = flags.Merge([]cli.Flag{ nodeFlags = slices.Concat([]cli.Flag{
utils.IdentityFlag, utils.IdentityFlag,
utils.UnlockedAccountFlag, utils.UnlockedAccountFlag,
utils.PasswordFileFlag, utils.PasswordFileFlag,
@ -66,7 +67,7 @@ var (
utils.SmartCardDaemonPathFlag, utils.SmartCardDaemonPathFlag,
utils.OverrideCancun, utils.OverrideCancun,
utils.OverrideVerkle, utils.OverrideVerkle,
utils.EnablePersonal, utils.EnablePersonal, // deprecated
utils.TxPoolLocalsFlag, utils.TxPoolLocalsFlag,
utils.TxPoolNoLocalsFlag, utils.TxPoolNoLocalsFlag,
utils.TxPoolJournalFlag, utils.TxPoolJournalFlag,
@ -251,7 +252,7 @@ func init() {
} }
sort.Sort(cli.CommandsByName(app.Commands)) sort.Sort(cli.CommandsByName(app.Commands))
app.Flags = flags.Merge( app.Flags = slices.Concat(
nodeFlags, nodeFlags,
rpcFlags, rpcFlags,
consoleFlags, consoleFlags,

View file

@ -22,6 +22,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"slices"
"time" "time"
"github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/cmd/utils"
@ -32,7 +33,6 @@ import (
"github.com/ethereum/go-ethereum/core/state/snapshot" "github.com/ethereum/go-ethereum/core/state/snapshot"
"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/internal/flags"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
@ -50,7 +50,7 @@ var (
Usage: "Prune stale ethereum state data based on the snapshot", Usage: "Prune stale ethereum state data based on the snapshot",
ArgsUsage: "<root>", ArgsUsage: "<root>",
Action: pruneState, Action: pruneState,
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.BloomFilterSizeFlag, utils.BloomFilterSizeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags), }, utils.NetworkFlags, utils.DatabaseFlags),
Description: ` Description: `
@ -70,7 +70,7 @@ WARNING: it's only supported in hash mode(--state.scheme=hash)".
Usage: "Recalculate state hash based on the snapshot for verification", Usage: "Recalculate state hash based on the snapshot for verification",
ArgsUsage: "<root>", ArgsUsage: "<root>",
Action: verifyState, Action: verifyState,
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags), Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Description: ` Description: `
geth snapshot verify-state <state-root> geth snapshot verify-state <state-root>
will traverse the whole accounts and storages set based on the specified will traverse the whole accounts and storages set based on the specified
@ -83,7 +83,7 @@ In other words, this command does the snapshot to trie conversion.
Usage: "Check that there is no 'dangling' snap storage", Usage: "Check that there is no 'dangling' snap storage",
ArgsUsage: "<root>", ArgsUsage: "<root>",
Action: checkDanglingStorage, Action: checkDanglingStorage,
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags), Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Description: ` Description: `
geth snapshot check-dangling-storage <state-root> traverses the snap storage geth snapshot check-dangling-storage <state-root> traverses the snap storage
data, and verifies that all snapshot storage data has a corresponding account. data, and verifies that all snapshot storage data has a corresponding account.
@ -94,7 +94,7 @@ data, and verifies that all snapshot storage data has a corresponding account.
Usage: "Check all snapshot layers for the specific account", Usage: "Check all snapshot layers for the specific account",
ArgsUsage: "<address | hash>", ArgsUsage: "<address | hash>",
Action: checkAccount, Action: checkAccount,
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags), Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Description: ` Description: `
geth snapshot inspect-account <address | hash> checks all snapshot layers and prints out geth snapshot inspect-account <address | hash> checks all snapshot layers and prints out
information about the specified address. information about the specified address.
@ -105,7 +105,7 @@ information about the specified address.
Usage: "Traverse the state with given root hash and perform quick verification", Usage: "Traverse the state with given root hash and perform quick verification",
ArgsUsage: "<root>", ArgsUsage: "<root>",
Action: traverseState, Action: traverseState,
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags), Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Description: ` Description: `
geth snapshot traverse-state <state-root> geth snapshot traverse-state <state-root>
will traverse the whole state from the given state root and will abort if any will traverse the whole state from the given state root and will abort if any
@ -120,7 +120,7 @@ It's also usable without snapshot enabled.
Usage: "Traverse the state with given root hash and perform detailed verification", Usage: "Traverse the state with given root hash and perform detailed verification",
ArgsUsage: "<root>", ArgsUsage: "<root>",
Action: traverseRawState, Action: traverseRawState,
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags), Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Description: ` Description: `
geth snapshot traverse-rawstate <state-root> geth snapshot traverse-rawstate <state-root>
will traverse the whole state from the given root and will abort if any referenced will traverse the whole state from the given root and will abort if any referenced
@ -136,7 +136,7 @@ It's also usable without snapshot enabled.
Usage: "Dump a specific block from storage (same as 'geth dump' but using snapshots)", Usage: "Dump a specific block from storage (same as 'geth dump' but using snapshots)",
ArgsUsage: "[? <blockHash> | <blockNum>]", ArgsUsage: "[? <blockHash> | <blockNum>]",
Action: dumpState, Action: dumpState,
Flags: flags.Merge([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
utils.ExcludeCodeFlag, utils.ExcludeCodeFlag,
utils.ExcludeStorageFlag, utils.ExcludeStorageFlag,
utils.StartKeyFlag, utils.StartKeyFlag,

View file

@ -22,11 +22,11 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"slices"
"github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-verkle" "github.com/ethereum/go-verkle"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
@ -45,7 +45,7 @@ var (
Usage: "verify the conversion of a MPT into a verkle tree", Usage: "verify the conversion of a MPT into a verkle tree",
ArgsUsage: "<root>", ArgsUsage: "<root>",
Action: verifyVerkle, Action: verifyVerkle,
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags), Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Description: ` Description: `
geth verkle verify <state-root> geth verkle verify <state-root>
This command takes a root commitment and attempts to rebuild the tree. This command takes a root commitment and attempts to rebuild the tree.
@ -56,7 +56,7 @@ This command takes a root commitment and attempts to rebuild the tree.
Usage: "Dump a verkle tree to a DOT file", Usage: "Dump a verkle tree to a DOT file",
ArgsUsage: "<root> <key1> [<key 2> ...]", ArgsUsage: "<root> <key1> [<key 2> ...]",
Action: expandVerkle, Action: expandVerkle,
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags), Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
Description: ` Description: `
geth verkle dump <state-root> <key 1> [<key 2> ...] geth verkle dump <state-root> <key 1> [<key 2> ...]
This command will produce a dot file representing the tree, rooted at <root>. This command will produce a dot file representing the tree, rooted at <root>.

View file

@ -176,12 +176,6 @@ var (
Usage: "Custom node name", Usage: "Custom node name",
Category: flags.NetworkingCategory, Category: flags.NetworkingCategory,
} }
DocRootFlag = &flags.DirectoryFlag{
Name: "docroot",
Usage: "Document Root for HTTPClient file scheme",
Value: flags.DirectoryString(flags.HomeDir()),
Category: flags.APICategory,
}
ExitWhenSyncedFlag = &cli.BoolFlag{ ExitWhenSyncedFlag = &cli.BoolFlag{
Name: "exitwhensynced", Name: "exitwhensynced",
Usage: "Exits after block synchronisation completes", Usage: "Exits after block synchronisation completes",
@ -217,8 +211,7 @@ var (
Value: 0, Value: 0,
} }
defaultSyncMode = ethconfig.Defaults.SyncMode SnapshotFlag = &cli.BoolFlag{
SnapshotFlag = &cli.BoolFlag{
Name: "snapshot", Name: "snapshot",
Usage: `Enables snapshot-database mode (default = enable)`, Usage: `Enables snapshot-database mode (default = enable)`,
Value: true, Value: true,
@ -250,10 +243,10 @@ var (
Usage: "Manually specify the Verkle fork timestamp, overriding the bundled setting", Usage: "Manually specify the Verkle fork timestamp, overriding the bundled setting",
Category: flags.EthCategory, Category: flags.EthCategory,
} }
SyncModeFlag = &flags.TextMarshalerFlag{ SyncModeFlag = &cli.StringFlag{
Name: "syncmode", Name: "syncmode",
Usage: `Blockchain sync mode ("snap" or "full")`, Usage: `Blockchain sync mode ("snap" or "full")`,
Value: &defaultSyncMode, Value: ethconfig.Defaults.SyncMode.String(),
Category: flags.StateCategory, Category: flags.StateCategory,
} }
GCModeFlag = &cli.StringFlag{ GCModeFlag = &cli.StringFlag{
@ -741,11 +734,6 @@ var (
Value: node.DefaultConfig.BatchResponseMaxSize, Value: node.DefaultConfig.BatchResponseMaxSize,
Category: flags.APICategory, Category: flags.APICategory,
} }
EnablePersonal = &cli.BoolFlag{
Name: "rpc.enabledeprecatedpersonal",
Usage: "Enables the (deprecated) personal namespace",
Category: flags.APICategory,
}
// Network Settings // Network Settings
MaxPeersFlag = &cli.IntFlag{ MaxPeersFlag = &cli.IntFlag{
@ -1399,9 +1387,8 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
if ctx.IsSet(JWTSecretFlag.Name) { if ctx.IsSet(JWTSecretFlag.Name) {
cfg.JWTSecret = ctx.String(JWTSecretFlag.Name) cfg.JWTSecret = ctx.String(JWTSecretFlag.Name)
} }
if ctx.IsSet(EnablePersonal.Name) { if ctx.IsSet(EnablePersonal.Name) {
cfg.EnablePersonal = true log.Warn(fmt.Sprintf("Option --%s is deprecated. The 'personal' RPC namespace has been removed.", EnablePersonal.Name))
} }
if ctx.IsSet(ExternalSignerFlag.Name) { if ctx.IsSet(ExternalSignerFlag.Name) {
@ -1675,7 +1662,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
if ctx.IsSet(SyncTargetFlag.Name) { if ctx.IsSet(SyncTargetFlag.Name) {
cfg.SyncMode = downloader.FullSync // dev sync target forces full sync cfg.SyncMode = downloader.FullSync // dev sync target forces full sync
} else if ctx.IsSet(SyncModeFlag.Name) { } else if ctx.IsSet(SyncModeFlag.Name) {
cfg.SyncMode = *flags.GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode) if err = cfg.SyncMode.UnmarshalText([]byte(ctx.String(SyncModeFlag.Name))); err != nil {
Fatalf("invalid --syncmode flag: %v", err)
}
} }
if ctx.IsSet(NetworkIdFlag.Name) { if ctx.IsSet(NetworkIdFlag.Name) {
cfg.NetworkId = ctx.Uint64(NetworkIdFlag.Name) cfg.NetworkId = ctx.Uint64(NetworkIdFlag.Name)
@ -1755,9 +1744,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
cfg.SnapshotCache = 0 // Disabled cfg.SnapshotCache = 0 // Disabled
} }
} }
if ctx.IsSet(DocRootFlag.Name) {
cfg.DocRoot = ctx.String(DocRootFlag.Name)
}
if ctx.IsSet(VMEnableDebugFlag.Name) { if ctx.IsSet(VMEnableDebugFlag.Name) {
// TODO(fjl): force-enable this in --dev mode // TODO(fjl): force-enable this in --dev mode
cfg.EnablePreimageRecording = ctx.Bool(VMEnableDebugFlag.Name) cfg.EnablePreimageRecording = ctx.Bool(VMEnableDebugFlag.Name)

View file

@ -153,6 +153,12 @@ var (
Usage: "Enable expensive metrics collection and reporting (deprecated)", Usage: "Enable expensive metrics collection and reporting (deprecated)",
Category: flags.DeprecatedCategory, Category: flags.DeprecatedCategory,
} }
// Deprecated Oct 2024
EnablePersonal = &cli.BoolFlag{
Name: "rpc.enabledeprecatedpersonal",
Usage: "This used to enable the 'personal' namespace.",
Category: flags.DeprecatedCategory,
}
) )
// showDeprecated displays deprecated flags that will be soon removed from the codebase. // showDeprecated displays deprecated flags that will be soon removed from the codebase.

View file

@ -19,15 +19,12 @@ package console
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"io" "io"
"reflect" "reflect"
"strings" "strings"
"time" "time"
"github.com/dop251/goja" "github.com/dop251/goja"
"github.com/ethereum/go-ethereum/accounts/scwallet"
"github.com/ethereum/go-ethereum/accounts/usbwallet"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/console/prompt" "github.com/ethereum/go-ethereum/console/prompt"
"github.com/ethereum/go-ethereum/internal/jsre" "github.com/ethereum/go-ethereum/internal/jsre"
@ -51,268 +48,6 @@ func newBridge(client *rpc.Client, prompter prompt.UserPrompter, printer io.Writ
} }
} }
func getJeth(vm *goja.Runtime) *goja.Object {
jeth := vm.Get("jeth")
if jeth == nil {
panic(vm.ToValue("jeth object does not exist"))
}
return jeth.ToObject(vm)
}
// NewAccount is a wrapper around the personal.newAccount RPC method that uses a
// non-echoing password prompt to acquire the passphrase and executes the original
// RPC method (saved in jeth.newAccount) with it to actually execute the RPC call.
func (b *bridge) NewAccount(call jsre.Call) (goja.Value, error) {
var (
password string
confirm string
err error
)
switch {
// No password was specified, prompt the user for it
case len(call.Arguments) == 0:
if password, err = b.prompter.PromptPassword("Passphrase: "); err != nil {
return nil, err
}
if confirm, err = b.prompter.PromptPassword("Repeat passphrase: "); err != nil {
return nil, err
}
if password != confirm {
return nil, errors.New("passwords don't match")
}
// A single string password was specified, use that
case len(call.Arguments) == 1 && call.Argument(0).ToString() != nil:
password = call.Argument(0).ToString().String()
default:
return nil, errors.New("expected 0 or 1 string argument")
}
// Password acquired, execute the call and return
newAccount, callable := goja.AssertFunction(getJeth(call.VM).Get("newAccount"))
if !callable {
return nil, errors.New("jeth.newAccount is not callable")
}
ret, err := newAccount(goja.Null(), call.VM.ToValue(password))
if err != nil {
return nil, err
}
return ret, nil
}
// OpenWallet is a wrapper around personal.openWallet which can interpret and
// react to certain error messages, such as the Trezor PIN matrix request.
func (b *bridge) OpenWallet(call jsre.Call) (goja.Value, error) {
// Make sure we have a wallet specified to open
if call.Argument(0).ToObject(call.VM).ClassName() != "String" {
return nil, errors.New("first argument must be the wallet URL to open")
}
wallet := call.Argument(0)
var passwd goja.Value
if goja.IsUndefined(call.Argument(1)) || goja.IsNull(call.Argument(1)) {
passwd = call.VM.ToValue("")
} else {
passwd = call.Argument(1)
}
// Open the wallet and return if successful in itself
openWallet, callable := goja.AssertFunction(getJeth(call.VM).Get("openWallet"))
if !callable {
return nil, errors.New("jeth.openWallet is not callable")
}
val, err := openWallet(goja.Null(), wallet, passwd)
if err == nil {
return val, nil
}
// Wallet open failed, report error unless it's a PIN or PUK entry
switch {
case strings.HasSuffix(err.Error(), usbwallet.ErrTrezorPINNeeded.Error()):
val, err = b.readPinAndReopenWallet(call)
if err == nil {
return val, nil
}
val, err = b.readPassphraseAndReopenWallet(call)
if err != nil {
return nil, err
}
case strings.HasSuffix(err.Error(), scwallet.ErrPairingPasswordNeeded.Error()):
// PUK input requested, fetch from the user and call open again
input, err := b.prompter.PromptPassword("Please enter the pairing password: ")
if err != nil {
return nil, err
}
passwd = call.VM.ToValue(input)
if val, err = openWallet(goja.Null(), wallet, passwd); err != nil {
if !strings.HasSuffix(err.Error(), scwallet.ErrPINNeeded.Error()) {
return nil, err
}
// PIN input requested, fetch from the user and call open again
input, err := b.prompter.PromptPassword("Please enter current PIN: ")
if err != nil {
return nil, err
}
if val, err = openWallet(goja.Null(), wallet, call.VM.ToValue(input)); err != nil {
return nil, err
}
}
case strings.HasSuffix(err.Error(), scwallet.ErrPINUnblockNeeded.Error()):
// PIN unblock requested, fetch PUK and new PIN from the user
var pukpin string
input, err := b.prompter.PromptPassword("Please enter current PUK: ")
if err != nil {
return nil, err
}
pukpin = input
input, err = b.prompter.PromptPassword("Please enter new PIN: ")
if err != nil {
return nil, err
}
pukpin += input
if val, err = openWallet(goja.Null(), wallet, call.VM.ToValue(pukpin)); err != nil {
return nil, err
}
case strings.HasSuffix(err.Error(), scwallet.ErrPINNeeded.Error()):
// PIN input requested, fetch from the user and call open again
input, err := b.prompter.PromptPassword("Please enter current PIN: ")
if err != nil {
return nil, err
}
if val, err = openWallet(goja.Null(), wallet, call.VM.ToValue(input)); err != nil {
return nil, err
}
default:
// Unknown error occurred, drop to the user
return nil, err
}
return val, nil
}
func (b *bridge) readPassphraseAndReopenWallet(call jsre.Call) (goja.Value, error) {
wallet := call.Argument(0)
input, err := b.prompter.PromptPassword("Please enter your passphrase: ")
if err != nil {
return nil, err
}
openWallet, callable := goja.AssertFunction(getJeth(call.VM).Get("openWallet"))
if !callable {
return nil, errors.New("jeth.openWallet is not callable")
}
return openWallet(goja.Null(), wallet, call.VM.ToValue(input))
}
func (b *bridge) readPinAndReopenWallet(call jsre.Call) (goja.Value, error) {
wallet := call.Argument(0)
// Trezor PIN matrix input requested, display the matrix to the user and fetch the data
fmt.Fprintf(b.printer, "Look at the device for number positions\n\n")
fmt.Fprintf(b.printer, "7 | 8 | 9\n")
fmt.Fprintf(b.printer, "--+---+--\n")
fmt.Fprintf(b.printer, "4 | 5 | 6\n")
fmt.Fprintf(b.printer, "--+---+--\n")
fmt.Fprintf(b.printer, "1 | 2 | 3\n\n")
input, err := b.prompter.PromptPassword("Please enter current PIN: ")
if err != nil {
return nil, err
}
openWallet, callable := goja.AssertFunction(getJeth(call.VM).Get("openWallet"))
if !callable {
return nil, errors.New("jeth.openWallet is not callable")
}
return openWallet(goja.Null(), wallet, call.VM.ToValue(input))
}
// UnlockAccount is a wrapper around the personal.unlockAccount RPC method that
// uses a non-echoing password prompt to acquire the passphrase and executes the
// original RPC method (saved in jeth.unlockAccount) with it to actually execute
// the RPC call.
func (b *bridge) UnlockAccount(call jsre.Call) (goja.Value, error) {
if len(call.Arguments) < 1 {
return nil, errors.New("usage: unlockAccount(account, [ password, duration ])")
}
account := call.Argument(0)
// Make sure we have an account specified to unlock.
if goja.IsUndefined(account) || goja.IsNull(account) || account.ExportType().Kind() != reflect.String {
return nil, errors.New("first argument must be the account to unlock")
}
// If password is not given or is the null value, prompt the user for it.
var passwd goja.Value
if goja.IsUndefined(call.Argument(1)) || goja.IsNull(call.Argument(1)) {
fmt.Fprintf(b.printer, "Unlock account %s\n", account)
input, err := b.prompter.PromptPassword("Passphrase: ")
if err != nil {
return nil, err
}
passwd = call.VM.ToValue(input)
} else {
if call.Argument(1).ExportType().Kind() != reflect.String {
return nil, errors.New("password must be a string")
}
passwd = call.Argument(1)
}
// Third argument is the duration how long the account should be unlocked.
duration := goja.Null()
if !goja.IsUndefined(call.Argument(2)) && !goja.IsNull(call.Argument(2)) {
if !isNumber(call.Argument(2)) {
return nil, errors.New("unlock duration must be a number")
}
duration = call.Argument(2)
}
// Send the request to the backend and return.
unlockAccount, callable := goja.AssertFunction(getJeth(call.VM).Get("unlockAccount"))
if !callable {
return nil, errors.New("jeth.unlockAccount is not callable")
}
return unlockAccount(goja.Null(), account, passwd, duration)
}
// Sign is a wrapper around the personal.sign RPC method that uses a non-echoing password
// prompt to acquire the passphrase and executes the original RPC method (saved in
// jeth.sign) with it to actually execute the RPC call.
func (b *bridge) Sign(call jsre.Call) (goja.Value, error) {
if nArgs := len(call.Arguments); nArgs < 2 {
return nil, errors.New("usage: sign(message, account, [ password ])")
}
var (
message = call.Argument(0)
account = call.Argument(1)
passwd = call.Argument(2)
)
if goja.IsUndefined(message) || message.ExportType().Kind() != reflect.String {
return nil, errors.New("first argument must be the message to sign")
}
if goja.IsUndefined(account) || account.ExportType().Kind() != reflect.String {
return nil, errors.New("second argument must be the account to sign with")
}
// if the password is not given or null ask the user and ensure password is a string
if goja.IsUndefined(passwd) || goja.IsNull(passwd) {
fmt.Fprintf(b.printer, "Give password for account %s\n", account)
input, err := b.prompter.PromptPassword("Password: ")
if err != nil {
return nil, err
}
passwd = call.VM.ToValue(input)
} else if passwd.ExportType().Kind() != reflect.String {
return nil, errors.New("third argument must be the password to unlock the account")
}
// Send the request to the backend and return
sign, callable := goja.AssertFunction(getJeth(call.VM).Get("sign"))
if !callable {
return nil, errors.New("jeth.sign is not callable")
}
return sign(goja.Null(), message, account, passwd)
}
// Sleep will block the console for the specified number of seconds. // Sleep will block the console for the specified number of seconds.
func (b *bridge) Sleep(call jsre.Call) (goja.Value, error) { func (b *bridge) Sleep(call jsre.Call) (goja.Value, error) {
if nArgs := len(call.Arguments); nArgs < 1 { if nArgs := len(call.Arguments); nArgs < 1 {

View file

@ -1,48 +0,0 @@
// Copyright 2020 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package console
import (
"testing"
"github.com/dop251/goja"
"github.com/ethereum/go-ethereum/internal/jsre"
)
// TestUndefinedAsParam ensures that personal functions can receive
// `undefined` as a parameter.
func TestUndefinedAsParam(t *testing.T) {
b := bridge{}
call := jsre.Call{}
call.Arguments = []goja.Value{goja.Undefined()}
b.UnlockAccount(call)
b.Sign(call)
b.Sleep(call)
}
// TestNullAsParam ensures that personal functions can receive
// `null` as a parameter.
func TestNullAsParam(t *testing.T) {
b := bridge{}
call := jsre.Call{}
call.Arguments = []goja.Value{goja.Null()}
b.UnlockAccount(call)
b.Sign(call)
b.Sleep(call)
}

View file

@ -142,7 +142,6 @@ func (c *Console) init(preload []string) error {
// Add bridge overrides for web3.js functionality. // Add bridge overrides for web3.js functionality.
c.jsre.Do(func(vm *goja.Runtime) { c.jsre.Do(func(vm *goja.Runtime) {
c.initAdmin(vm, bridge) c.initAdmin(vm, bridge)
c.initPersonal(vm, bridge)
}) })
// Preload JavaScript files. // Preload JavaScript files.
@ -249,30 +248,6 @@ func (c *Console) initAdmin(vm *goja.Runtime, bridge *bridge) {
} }
} }
// initPersonal redirects account-related API methods through the bridge.
//
// If the console is in interactive mode and the 'personal' API is available, override
// the openWallet, unlockAccount, newAccount and sign methods since these require user
// interaction. The original web3 callbacks are stored in 'jeth'. These will be called
// by the bridge after the prompt and send the original web3 request to the backend.
func (c *Console) initPersonal(vm *goja.Runtime, bridge *bridge) {
personal := getObject(vm, "personal")
if personal == nil || c.prompter == nil {
return
}
log.Warn("Enabling deprecated personal namespace")
jeth := vm.NewObject()
vm.Set("jeth", jeth)
jeth.Set("openWallet", personal.Get("openWallet"))
jeth.Set("unlockAccount", personal.Get("unlockAccount"))
jeth.Set("newAccount", personal.Get("newAccount"))
jeth.Set("sign", personal.Get("sign"))
personal.Set("openWallet", jsre.MakeCallback(vm, bridge.OpenWallet))
personal.Set("unlockAccount", jsre.MakeCallback(vm, bridge.UnlockAccount))
personal.Set("newAccount", jsre.MakeCallback(vm, bridge.NewAccount))
personal.Set("sign", jsre.MakeCallback(vm, bridge.Sign))
}
func (c *Console) clearHistory() { func (c *Console) clearHistory() {
c.history = nil c.history = nil
c.prompter.ClearHistory() c.prompter.ClearHistory()

View file

@ -341,6 +341,9 @@ func (s *StateDB) TxIndex() int {
func (s *StateDB) GetCode(addr common.Address) []byte { func (s *StateDB) GetCode(addr common.Address) []byte {
stateObject := s.getStateObject(addr) stateObject := s.getStateObject(addr)
if stateObject != nil { if stateObject != nil {
if s.witness != nil {
s.witness.AddCode(stateObject.Code())
}
return stateObject.Code() return stateObject.Code()
} }
return nil return nil
@ -349,6 +352,9 @@ func (s *StateDB) GetCode(addr common.Address) []byte {
func (s *StateDB) GetCodeSize(addr common.Address) int { func (s *StateDB) GetCodeSize(addr common.Address) int {
stateObject := s.getStateObject(addr) stateObject := s.getStateObject(addr)
if stateObject != nil { if stateObject != nil {
if s.witness != nil {
s.witness.AddCode(stateObject.Code())
}
return stateObject.CodeSize() return stateObject.CodeSize()
} }
return 0 return 0

View file

@ -358,7 +358,7 @@ func (p *TxPool) Add(txs []*types.Transaction, local bool, sync bool) []error {
for i, split := range splits { for i, split := range splits {
// If the transaction was rejected by all subpools, mark it unsupported // If the transaction was rejected by all subpools, mark it unsupported
if split == -1 { if split == -1 {
errs[i] = core.ErrTxTypeNotSupported errs[i] = fmt.Errorf("%w: received type %d", core.ErrTxTypeNotSupported, txs[i].Type())
continue continue
} }
// Find which subpool handled it and pull in the corresponding error // Find which subpool handled it and pull in the corresponding error

View file

@ -99,7 +99,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
} }
// Make sure the transaction is signed properly // Make sure the transaction is signed properly
if _, err := types.Sender(signer, tx); err != nil { if _, err := types.Sender(signer, tx); err != nil {
return ErrInvalidSender return fmt.Errorf("%w: %v", ErrInvalidSender, err)
} }
// Ensure the transaction has more gas than the bare minimum needed to cover // Ensure the transaction has more gas than the bare minimum needed to cover
// the transaction metadata // the transaction metadata

View file

@ -213,9 +213,6 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
// Initialise a new contract and set the code that is to be used by the EVM. // Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only. // The contract is a scoped environment for this execution context only.
code := evm.StateDB.GetCode(addr) code := evm.StateDB.GetCode(addr)
if witness := evm.StateDB.Witness(); witness != nil {
witness.AddCode(code)
}
if len(code) == 0 { if len(code) == 0 {
ret, err = nil, nil // gas is unchanged ret, err = nil, nil // gas is unchanged
} else { } else {
@ -283,9 +280,6 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
// Initialise a new contract and set the code that is to be used by the EVM. // Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only. // The contract is a scoped environment for this execution context only.
contract := NewContract(caller, AccountRef(caller.Address()), value, gas) contract := NewContract(caller, AccountRef(caller.Address()), value, gas)
if witness := evm.StateDB.Witness(); witness != nil {
witness.AddCode(evm.StateDB.GetCode(addrCopy))
}
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
ret, err = evm.interpreter.Run(contract, input, false) ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas gas = contract.Gas
@ -333,9 +327,6 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
addrCopy := addr addrCopy := addr
// Initialise a new contract and make initialise the delegate values // Initialise a new contract and make initialise the delegate values
contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate() contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate()
if witness := evm.StateDB.Witness(); witness != nil {
witness.AddCode(evm.StateDB.GetCode(addrCopy))
}
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
ret, err = evm.interpreter.Run(contract, input, false) ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas gas = contract.Gas
@ -391,9 +382,6 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
// Initialise a new contract and set the code that is to be used by the EVM. // Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only. // The contract is a scoped environment for this execution context only.
contract := NewContract(caller, AccountRef(addrCopy), new(uint256.Int), gas) contract := NewContract(caller, AccountRef(addrCopy), new(uint256.Int), gas)
if witness := evm.StateDB.Witness(); witness != nil {
witness.AddCode(evm.StateDB.GetCode(addrCopy))
}
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
// When an error was returned by the EVM or when setting the creation code // When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally // above we revert to the snapshot and consume any gas remaining. Additionally

View file

@ -340,10 +340,6 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte
func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
slot := scope.Stack.peek() slot := scope.Stack.peek()
address := slot.Bytes20()
if witness := interpreter.evm.StateDB.Witness(); witness != nil {
witness.AddCode(interpreter.evm.StateDB.GetCode(address))
}
slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(slot.Bytes20()))) slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(slot.Bytes20())))
return nil, nil return nil, nil
} }
@ -383,9 +379,6 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
} }
addr := common.Address(a.Bytes20()) addr := common.Address(a.Bytes20())
code := interpreter.evm.StateDB.GetCode(addr) code := interpreter.evm.StateDB.GetCode(addr)
if witness := interpreter.evm.StateDB.Witness(); witness != nil {
witness.AddCode(code)
}
codeCopy := getData(code, uint64CodeOffset, length.Uint64()) codeCopy := getData(code, uint64CodeOffset, length.Uint64())
scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)

View file

@ -142,13 +142,16 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
// set the receiver's (the executing contract) code for execution. // set the receiver's (the executing contract) code for execution.
cfg.State.SetCode(address, code) cfg.State.SetCode(address, code)
// Call the code with the given configuration. // Call the code with the given configuration.
ret, _, err := vmenv.Call( ret, leftOverGas, err := vmenv.Call(
sender, sender,
common.BytesToAddress([]byte("contract")), common.BytesToAddress([]byte("contract")),
input, input,
cfg.GasLimit, cfg.GasLimit,
uint256.MustFromBig(cfg.Value), uint256.MustFromBig(cfg.Value),
) )
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxEnd != nil {
cfg.EVMConfig.Tracer.OnTxEnd(&types.Receipt{GasUsed: cfg.GasLimit - leftOverGas}, err)
}
return ret, cfg.State, err return ret, cfg.State, err
} }
@ -181,6 +184,9 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
cfg.GasLimit, cfg.GasLimit,
uint256.MustFromBig(cfg.Value), uint256.MustFromBig(cfg.Value),
) )
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxEnd != nil {
cfg.EVMConfig.Tracer.OnTxEnd(&types.Receipt{GasUsed: cfg.GasLimit - leftOverGas}, err)
}
return code, address, leftOverGas, err return code, address, leftOverGas, err
} }
@ -214,5 +220,8 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er
cfg.GasLimit, cfg.GasLimit,
uint256.MustFromBig(cfg.Value), uint256.MustFromBig(cfg.Value),
) )
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxEnd != nil {
cfg.EVMConfig.Tracer.OnTxEnd(&types.Receipt{GasUsed: cfg.GasLimit - leftOverGas}, err)
}
return ret, leftOverGas, err return ret, leftOverGas, err
} }

View file

@ -208,7 +208,6 @@ func TestEth2PrepareAndGetPayload(t *testing.T) {
t.Fatalf("error preparing payload, err=%v", err) t.Fatalf("error preparing payload, err=%v", err)
} }
// give the payload some time to be built // give the payload some time to be built
time.Sleep(100 * time.Millisecond)
payloadID := (&miner.BuildPayloadArgs{ payloadID := (&miner.BuildPayloadArgs{
Parent: fcState.HeadBlockHash, Parent: fcState.HeadBlockHash,
Timestamp: blockParams.Timestamp, Timestamp: blockParams.Timestamp,
@ -217,12 +216,12 @@ func TestEth2PrepareAndGetPayload(t *testing.T) {
BeaconRoot: blockParams.BeaconRoot, BeaconRoot: blockParams.BeaconRoot,
Version: engine.PayloadV1, Version: engine.PayloadV1,
}).Id() }).Id()
execData, err := api.GetPayloadV1(payloadID) execData, err := api.getPayload(payloadID, true)
if err != nil { if err != nil {
t.Fatalf("error getting payload, err=%v", err) t.Fatalf("error getting payload, err=%v", err)
} }
if len(execData.Transactions) != blocks[9].Transactions().Len() { if len(execData.ExecutionPayload.Transactions) != blocks[9].Transactions().Len() {
t.Fatalf("invalid number of transactions %d != 1", len(execData.Transactions)) t.Fatalf("invalid number of transactions %d != 1", len(execData.ExecutionPayload.Transactions))
} }
// Test invalid payloadID // Test invalid payloadID
var invPayload engine.PayloadID var invPayload engine.PayloadID
@ -453,7 +452,6 @@ func startEthService(t *testing.T, genesis *core.Genesis, blocks []*types.Block)
} }
mcfg := miner.DefaultConfig mcfg := miner.DefaultConfig
mcfg.PendingFeeRecipient = testAddr
ethcfg := &ethconfig.Config{Genesis: genesis, SyncMode: downloader.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256, Miner: mcfg} ethcfg := &ethconfig.Config{Genesis: genesis, SyncMode: downloader.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256, Miner: mcfg}
ethservice, err := eth.New(n, ethcfg) ethservice, err := eth.New(n, ethcfg)
if err != nil { if err != nil {
@ -628,7 +626,7 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
SafeBlockHash: common.Hash{}, SafeBlockHash: common.Hash{},
FinalizedBlockHash: common.Hash{}, FinalizedBlockHash: common.Hash{},
} }
payload *engine.ExecutableData payload *engine.ExecutionPayloadEnvelope
resp engine.ForkChoiceResponse resp engine.ForkChoiceResponse
err error err error
) )
@ -640,11 +638,10 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
t.Fatalf("error preparing payload, invalid status: %v", resp.PayloadStatus.Status) t.Fatalf("error preparing payload, invalid status: %v", resp.PayloadStatus.Status)
} }
// give the payload some time to be built // give the payload some time to be built
time.Sleep(50 * time.Millisecond) if payload, err = api.getPayload(*resp.PayloadID, true); err != nil {
if payload, err = api.GetPayloadV1(*resp.PayloadID); err != nil {
t.Fatalf("can't get payload: %v", err) t.Fatalf("can't get payload: %v", err)
} }
if len(payload.Transactions) > 0 { if len(payload.ExecutionPayload.Transactions) > 0 {
break break
} }
// No luck this time we need to update the params and try again. // No luck this time we need to update the params and try again.
@ -653,7 +650,7 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
t.Fatalf("payload should not be empty") t.Fatalf("payload should not be empty")
} }
} }
execResp, err := api.NewPayloadV1(*payload) execResp, err := api.NewPayloadV1(*payload.ExecutionPayload)
if err != nil { if err != nil {
t.Fatalf("can't execute payload: %v", err) t.Fatalf("can't execute payload: %v", err)
} }
@ -661,14 +658,14 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
t.Fatalf("invalid status: %v", execResp.Status) t.Fatalf("invalid status: %v", execResp.Status)
} }
fcState = engine.ForkchoiceStateV1{ fcState = engine.ForkchoiceStateV1{
HeadBlockHash: payload.BlockHash, HeadBlockHash: payload.ExecutionPayload.BlockHash,
SafeBlockHash: payload.ParentHash, SafeBlockHash: payload.ExecutionPayload.ParentHash,
FinalizedBlockHash: payload.ParentHash, FinalizedBlockHash: payload.ExecutionPayload.ParentHash,
} }
if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil { if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
t.Fatalf("Failed to insert block: %v", err) t.Fatalf("Failed to insert block: %v", err)
} }
if ethservice.BlockChain().CurrentBlock().Number.Uint64() != payload.Number { if ethservice.BlockChain().CurrentBlock().Number.Uint64() != payload.ExecutionPayload.Number {
t.Fatalf("Chain head should be updated") t.Fatalf("Chain head should be updated")
} }
parent = ethservice.BlockChain().CurrentBlock() parent = ethservice.BlockChain().CurrentBlock()
@ -1736,9 +1733,6 @@ func TestWitnessCreationAndConsumption(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("error preparing payload, err=%v", err) t.Fatalf("error preparing payload, err=%v", err)
} }
// Give the payload some time to be built
time.Sleep(100 * time.Millisecond)
payloadID := (&miner.BuildPayloadArgs{ payloadID := (&miner.BuildPayloadArgs{
Parent: fcState.HeadBlockHash, Parent: fcState.HeadBlockHash,
Timestamp: blockParams.Timestamp, Timestamp: blockParams.Timestamp,
@ -1748,7 +1742,7 @@ func TestWitnessCreationAndConsumption(t *testing.T) {
BeaconRoot: blockParams.BeaconRoot, BeaconRoot: blockParams.BeaconRoot,
Version: engine.PayloadV3, Version: engine.PayloadV3,
}).Id() }).Id()
envelope, err := api.GetPayloadV3(payloadID) envelope, err := api.getPayload(payloadID, true)
if err != nil { if err != nil {
t.Fatalf("error getting payload, err=%v", err) t.Fatalf("error getting payload, err=%v", err)
} }

View file

@ -138,9 +138,6 @@ type Config struct {
VMTrace string VMTrace string
VMTraceJsonConfig string VMTraceJsonConfig string
// Miscellaneous options
DocRoot string `toml:"-"`
// RPCGasCap is the global gas cap for eth-call variants. // RPCGasCap is the global gas cap for eth-call variants.
RPCGasCap uint64 RPCGasCap uint64

View file

@ -46,7 +46,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
EnablePreimageRecording bool EnablePreimageRecording bool
VMTrace string VMTrace string
VMTraceJsonConfig string VMTraceJsonConfig string
DocRoot string `toml:"-"`
RPCGasCap uint64 RPCGasCap uint64
RPCEVMTimeout time.Duration RPCEVMTimeout time.Duration
RPCTxFeeCap float64 RPCTxFeeCap float64
@ -83,7 +82,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
enc.EnablePreimageRecording = c.EnablePreimageRecording enc.EnablePreimageRecording = c.EnablePreimageRecording
enc.VMTrace = c.VMTrace enc.VMTrace = c.VMTrace
enc.VMTraceJsonConfig = c.VMTraceJsonConfig enc.VMTraceJsonConfig = c.VMTraceJsonConfig
enc.DocRoot = c.DocRoot
enc.RPCGasCap = c.RPCGasCap enc.RPCGasCap = c.RPCGasCap
enc.RPCEVMTimeout = c.RPCEVMTimeout enc.RPCEVMTimeout = c.RPCEVMTimeout
enc.RPCTxFeeCap = c.RPCTxFeeCap enc.RPCTxFeeCap = c.RPCTxFeeCap
@ -124,7 +122,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
EnablePreimageRecording *bool EnablePreimageRecording *bool
VMTrace *string VMTrace *string
VMTraceJsonConfig *string VMTraceJsonConfig *string
DocRoot *string `toml:"-"`
RPCGasCap *uint64 RPCGasCap *uint64
RPCEVMTimeout *time.Duration RPCEVMTimeout *time.Duration
RPCTxFeeCap *float64 RPCTxFeeCap *float64
@ -222,9 +219,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
if dec.VMTraceJsonConfig != nil { if dec.VMTraceJsonConfig != nil {
c.VMTraceJsonConfig = *dec.VMTraceJsonConfig c.VMTraceJsonConfig = *dec.VMTraceJsonConfig
} }
if dec.DocRoot != nil {
c.DocRoot = *dec.DocRoot
}
if dec.RPCGasCap != nil { if dec.RPCGasCap != nil {
c.RPCGasCap = *dec.RPCGasCap c.RPCGasCap = *dec.RPCGasCap
} }

View file

@ -67,8 +67,7 @@
"transactionPosition": 74, "transactionPosition": 74,
"transactionHash": "0x5ef60b27ac971c22a7d484e546e50093ca62300c8986d165154e47773764b6a4", "transactionHash": "0x5ef60b27ac971c22a7d484e546e50093ca62300c8986d165154e47773764b6a4",
"blockNumber": 1555279, "blockNumber": 1555279,
"blockHash": "0xd6c98d1b87dfa92a210d99bad2873adaf0c9e51fe43addc63fd9cca03a5c6f46", "blockHash": "0xd6c98d1b87dfa92a210d99bad2873adaf0c9e51fe43addc63fd9cca03a5c6f46"
"time": "209.346µs"
}, },
{ {
"action": { "action": {

View file

@ -67,8 +67,7 @@
"transactionPosition": 141, "transactionPosition": 141,
"transactionHash": "0x1592cbda0d928b8d18eed98857942b91ade32d088e55b8bf63418917cb0231f1", "transactionHash": "0x1592cbda0d928b8d18eed98857942b91ade32d088e55b8bf63418917cb0231f1",
"blockNumber": 1555278, "blockNumber": 1555278,
"blockHash": "0x755bd54de4b2f5a7a589a10d69888b4ead48a6311d5d69f2f69ca85ec35fbe0b", "blockHash": "0x755bd54de4b2f5a7a589a10d69888b4ead48a6311d5d69f2f69ca85ec35fbe0b"
"time": "300.9µs"
}, },
{ {
"type": "call", "type": "call",
@ -81,9 +80,7 @@
"callType": "callcode" "callType": "callcode"
}, },
"error": "out of gas", "error": "out of gas",
"traceAddress": [ "traceAddress": [0],
0
],
"subtraces": 0, "subtraces": 0,
"transactionPosition": 141, "transactionPosition": 141,
"transactionHash": "0x1592cbda0d928b8d18eed98857942b91ade32d088e55b8bf63418917cb0231f1", "transactionHash": "0x1592cbda0d928b8d18eed98857942b91ade32d088e55b8bf63418917cb0231f1",

View file

@ -63,8 +63,7 @@
"transactionPosition": 117, "transactionPosition": 117,
"transactionHash": "0x7fe4dec901e1a62c1a1d96b8267bb9ff9dc1f75def43aa45b998743455eff8f9", "transactionHash": "0x7fe4dec901e1a62c1a1d96b8267bb9ff9dc1f75def43aa45b998743455eff8f9",
"blockNumber": 1555275, "blockNumber": 1555275,
"blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd", "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd"
"time": "332.877µs"
}, },
{ {
"type": "call", "type": "call",
@ -77,9 +76,7 @@
"callType": "callcode" "callType": "callcode"
}, },
"error": "invalid input length", "error": "invalid input length",
"traceAddress": [ "traceAddress": [0],
0
],
"subtraces": 0, "subtraces": 0,
"transactionPosition": 117, "transactionPosition": 117,
"transactionHash": "0x7fe4dec901e1a62c1a1d96b8267bb9ff9dc1f75def43aa45b998743455eff8f9", "transactionHash": "0x7fe4dec901e1a62c1a1d96b8267bb9ff9dc1f75def43aa45b998743455eff8f9",

View file

@ -0,0 +1,92 @@
{
"genesis": {
"difficulty": "4639933",
"extraData": "0xd883010b05846765746888676f312e31342e33856c696e7578",
"gasLimit": "9280188",
"hash": "0x9a5f3a98eb1c60f6e3f450658a9cea190157e7021d04f927b752ad6482cf9194",
"miner": "0x73f26d124436b0791169d63a3af29c2ae47765a3",
"mixHash": "0x6b6f8fcaa54b8565c4c1ae7cf0a020e938a53007f4561e758b17bc05c9044d78",
"nonce": "0x773aba50dc51b462",
"number": "1555169",
"stateRoot": "0xc4b9703de3e59ff795baae2c3afa010cf039c37244a7a6af7f3f491a10601348",
"timestamp": "1590794111",
"totalDifficulty": "2242105342155",
"alloc": {
"0x5ac5599fc9df172c89ee7ec55ad9104ccbfed40d": {
"balance": "0x0",
"nonce": "0",
"code": "0x",
"storage": {}
},
"0x877bd459c9b7d8576b44e59e09d076c25946f443": {
"balance": "0x62325b40cbbd0915c4b9",
"nonce": "260875",
"code": "0x",
"storage": {}
}
},
"config": {
"chainId": 63,
"daoForkSupport": true,
"eip150Block": 0,
"eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
"eip155Block": 0,
"eip158Block": 0,
"ethash": {},
"homesteadBlock": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 301243,
"petersburgBlock": 999983,
"istanbulBlock": 999983
}
},
"context": {
"number": "1555170",
"difficulty": "4642198",
"timestamp": "1590794112",
"gasLimit": "9289249",
"miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
},
"input": "0xf8658303fb0b843b9aca0083019ee48080915a600055600060006000f0505a6001550081a2a01a7deb3a16d967b766459ef486b00656c6581e5ad58968184a33701e27e0eb8aa07162ccdfe2018d64360a605310a62c399dd586c7282dd42a88c54f02f51d451f",
"tracerConfig": {
"convertParityErrors": true
},
"result": [
{
"type": "create",
"action": {
"from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
"value": "0x0",
"gas": "0x19ee4",
"init": "0x5a600055600060006000f0505a60015500"
},
"error": "Out of gas",
"traceAddress": [],
"subtraces": 1,
"transactionPosition": 63,
"transactionHash": "0x60e881fae3884657b5430925c5d0053535b45cce0b8188f2a6be1feee8bcc650",
"blockNumber": 1555170,
"blockHash": "0xea46fbf941d51bf1e4180fbf26d22fda3896f49c7f371d109c226de95dd7b02e"
},
{
"type": "create",
"action": {
"from": "0x9c5cfe45b15eaff4ad617af4250189e26024a4f8",
"value": "0x0",
"gas": "0x3cb",
"init": "0x"
},
"result": {
"gasUsed": "0x0",
"code": "0x",
"address": "0x5ac5599fc9df172c89ee7ec55ad9104ccbfed40d"
},
"traceAddress": [0],
"subtraces": 0,
"transactionPosition": 63,
"transactionHash": "0x60e881fae3884657b5430925c5d0053535b45cce0b8188f2a6be1feee8bcc650",
"blockNumber": 1555170,
"blockHash": "0xea46fbf941d51bf1e4180fbf26d22fda3896f49c7f371d109c226de95dd7b02e"
}
]
}

View file

@ -67,8 +67,7 @@
"transactionPosition": 18, "transactionPosition": 18,
"transactionHash": "0xc1c42a325856d513523aec464811923b2e2926f54015c7ba37877064cf889803", "transactionHash": "0xc1c42a325856d513523aec464811923b2e2926f54015c7ba37877064cf889803",
"blockNumber": 1555275, "blockNumber": 1555275,
"blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd", "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd"
"time": "453.925µs"
}, },
{ {
"type": "call", "type": "call",

View file

@ -67,8 +67,7 @@
"transactionPosition": 23, "transactionPosition": 23,
"transactionHash": "0xe267552ce8437a5bc7081385c99f912de5723ad34b958db215dbc41abd5f6c03", "transactionHash": "0xe267552ce8437a5bc7081385c99f912de5723ad34b958db215dbc41abd5f6c03",
"blockNumber": 555462, "blockNumber": 555462,
"blockHash": "0x38bba9e3965b57205097ea5ec53fc403cf3941bec2e4c933faae244de5ca4ba1", "blockHash": "0x38bba9e3965b57205097ea5ec53fc403cf3941bec2e4c933faae244de5ca4ba1"
"time": "1.147715ms"
}, },
{ {
"type": "create", "type": "create",

View file

@ -67,8 +67,7 @@
"transactionPosition": 31, "transactionPosition": 31,
"transactionHash": "0x1257b698c5833c54ce786734087002b097275abc3877af082b5c2a538e894a41", "transactionHash": "0x1257b698c5833c54ce786734087002b097275abc3877af082b5c2a538e894a41",
"blockNumber": 1555161, "blockNumber": 1555161,
"blockHash": "0xb0793dd508dd106a19794b8ce1dfc0ff8d98c76aab61bf32a11799854149a171", "blockHash": "0xb0793dd508dd106a19794b8ce1dfc0ff8d98c76aab61bf32a11799854149a171"
"time": "889.048µs"
}, },
{ {
"type": "create", "type": "create",

View file

@ -63,8 +63,7 @@
"transactionPosition": 63, "transactionPosition": 63,
"transactionHash": "0x60e881fae3884657b5430925c5d0053535b45cce0b8188f2a6be1feee8bcc650", "transactionHash": "0x60e881fae3884657b5430925c5d0053535b45cce0b8188f2a6be1feee8bcc650",
"blockNumber": 1555170, "blockNumber": 1555170,
"blockHash": "0xea46fbf941d51bf1e4180fbf26d22fda3896f49c7f371d109c226de95dd7b02e", "blockHash": "0xea46fbf941d51bf1e4180fbf26d22fda3896f49c7f371d109c226de95dd7b02e"
"time": "952.736µs"
}, },
{ {
"type": "create", "type": "create",

View file

@ -73,8 +73,7 @@
"transactionPosition": 26, "transactionPosition": 26,
"transactionHash": "0xcb1090fa85d2a3da8326b75333e92b3dca89963c895d9c981bfdaa64643135e4", "transactionHash": "0xcb1090fa85d2a3da8326b75333e92b3dca89963c895d9c981bfdaa64643135e4",
"blockNumber": 839247, "blockNumber": 839247,
"blockHash": "0xce7ff7d84ca97f0f89d6065e2c12409a795c9f607cdb14aef0713cad5d7e311c", "blockHash": "0xce7ff7d84ca97f0f89d6065e2c12409a795c9f607cdb14aef0713cad5d7e311c"
"time": "182.267µs"
}, },
{ {
"action": { "action": {

View file

@ -80,8 +80,7 @@
"transactionPosition": 5, "transactionPosition": 5,
"transactionHash": "0x04d2029a5cbbed30969cdc0a2ca9e9fc6b719e323af0802b52466f07ee0ecada", "transactionHash": "0x04d2029a5cbbed30969cdc0a2ca9e9fc6b719e323af0802b52466f07ee0ecada",
"blockNumber": 553416, "blockNumber": 553416,
"blockHash": "0x8df024322173d225a09681d35edeaa528aca60743a11a70f854c158862bf5282", "blockHash": "0x8df024322173d225a09681d35edeaa528aca60743a11a70f854c158862bf5282"
"time": "617.42µs"
}, },
{ {
"type": "call", "type": "call",
@ -97,9 +96,7 @@
"gasUsed": "0x0", "gasUsed": "0x0",
"output": "0x" "output": "0x"
}, },
"traceAddress": [ "traceAddress": [0],
0
],
"subtraces": 0, "subtraces": 0,
"transactionPosition": 5, "transactionPosition": 5,
"transactionHash": "0x04d2029a5cbbed30969cdc0a2ca9e9fc6b719e323af0802b52466f07ee0ecada", "transactionHash": "0x04d2029a5cbbed30969cdc0a2ca9e9fc6b719e323af0802b52466f07ee0ecada",

View file

@ -67,8 +67,7 @@
"transactionPosition": 14, "transactionPosition": 14,
"transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79", "transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79",
"blockNumber": 1555146, "blockNumber": 1555146,
"blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e", "blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e"
"time": "187.145µs"
}, },
{ {
"action": { "action": {
@ -92,9 +91,7 @@
"balance": "0x0" "balance": "0x0"
}, },
"result": null, "result": null,
"traceAddress": [ "traceAddress": [1],
1
],
"subtraces": 0, "subtraces": 0,
"transactionPosition": 14, "transactionPosition": 14,
"transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79", "transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79",

View file

@ -63,8 +63,7 @@
"transactionPosition": 16, "transactionPosition": 16,
"transactionHash": "0x384487e5ae8d2997aece8e28403d393cb9752425e6de358891bed981c5af1c05", "transactionHash": "0x384487e5ae8d2997aece8e28403d393cb9752425e6de358891bed981c5af1c05",
"blockNumber": 1555285, "blockNumber": 1555285,
"blockHash": "0x93231d8e9662adb4c5c703583a92c7b3112cd5448f43ab4fa1f0f00a0183ed3f", "blockHash": "0x93231d8e9662adb4c5c703583a92c7b3112cd5448f43ab4fa1f0f00a0183ed3f"
"time": "665.278µs"
}, },
{ {
"action": { "action": {

View file

@ -55,6 +55,7 @@ var parityErrorMapping = map[string]string{
} }
var parityErrorMappingStartingWith = map[string]string{ var parityErrorMappingStartingWith = map[string]string{
"out of gas:": "Out of gas", // convert OOG wrapped errors, eg `out of gas: not enough gas for reentrancy sentry`
"invalid opcode:": "Bad instruction", "invalid opcode:": "Bad instruction",
"stack underflow": "Stack underflow", "stack underflow": "Stack underflow",
} }
@ -371,6 +372,7 @@ func convertErrorToParity(call *flatCallFrame) {
for gethError, parityError := range parityErrorMappingStartingWith { for gethError, parityError := range parityErrorMappingStartingWith {
if strings.HasPrefix(call.Error, gethError) { if strings.HasPrefix(call.Error, gethError) {
call.Error = parityError call.Error = parityError
break
} }
} }
} }

1
go.mod
View file

@ -63,7 +63,6 @@ require (
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
github.com/supranational/blst v0.3.13 github.com/supranational/blst v0.3.13
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
github.com/tyler-smith/go-bip39 v1.1.0
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
golang.org/x/crypto v0.22.0 golang.org/x/crypto v0.22.0

2
go.sum
View file

@ -499,8 +499,6 @@ github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFA
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=

View file

@ -29,8 +29,6 @@ import (
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/accounts/scwallet"
"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/common/math" "github.com/ethereum/go-ethereum/common/math"
@ -51,7 +49,6 @@ import (
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
"github.com/holiman/uint256" "github.com/holiman/uint256"
"github.com/tyler-smith/go-bip39"
) )
// estimateGasErrorRatio is the amount of overestimation eth_estimateGas is // estimateGasErrorRatio is the amount of overestimation eth_estimateGas is
@ -298,344 +295,6 @@ func (api *EthereumAccountAPI) Accounts() []common.Address {
return api.am.Accounts() return api.am.Accounts()
} }
// PersonalAccountAPI provides an API to access accounts managed by this node.
// It offers methods to create, (un)lock en list accounts. Some methods accept
// passwords and are therefore considered private by default.
type PersonalAccountAPI struct {
am *accounts.Manager
nonceLock *AddrLocker
b Backend
}
// NewPersonalAccountAPI creates a new PersonalAccountAPI.
func NewPersonalAccountAPI(b Backend, nonceLock *AddrLocker) *PersonalAccountAPI {
return &PersonalAccountAPI{
am: b.AccountManager(),
nonceLock: nonceLock,
b: b,
}
}
// ListAccounts will return a list of addresses for accounts this node manages.
func (api *PersonalAccountAPI) ListAccounts() []common.Address {
return api.am.Accounts()
}
// rawWallet is a JSON representation of an accounts.Wallet interface, with its
// data contents extracted into plain fields.
type rawWallet struct {
URL string `json:"url"`
Status string `json:"status"`
Failure string `json:"failure,omitempty"`
Accounts []accounts.Account `json:"accounts,omitempty"`
}
// ListWallets will return a list of wallets this node manages.
func (api *PersonalAccountAPI) ListWallets() []rawWallet {
wallets := make([]rawWallet, 0) // return [] instead of nil if empty
for _, wallet := range api.am.Wallets() {
status, failure := wallet.Status()
raw := rawWallet{
URL: wallet.URL().String(),
Status: status,
Accounts: wallet.Accounts(),
}
if failure != nil {
raw.Failure = failure.Error()
}
wallets = append(wallets, raw)
}
return wallets
}
// OpenWallet initiates a hardware wallet opening procedure, establishing a USB
// connection and attempting to authenticate via the provided passphrase. Note,
// the method may return an extra challenge requiring a second open (e.g. the
// Trezor PIN matrix challenge).
func (api *PersonalAccountAPI) OpenWallet(url string, passphrase *string) error {
wallet, err := api.am.Wallet(url)
if err != nil {
return err
}
pass := ""
if passphrase != nil {
pass = *passphrase
}
return wallet.Open(pass)
}
// DeriveAccount requests an HD wallet to derive a new account, optionally pinning
// it for later reuse.
func (api *PersonalAccountAPI) DeriveAccount(url string, path string, pin *bool) (accounts.Account, error) {
wallet, err := api.am.Wallet(url)
if err != nil {
return accounts.Account{}, err
}
derivPath, err := accounts.ParseDerivationPath(path)
if err != nil {
return accounts.Account{}, err
}
if pin == nil {
pin = new(bool)
}
return wallet.Derive(derivPath, *pin)
}
// NewAccount will create a new account and returns the address for the new account.
func (api *PersonalAccountAPI) NewAccount(password string) (common.AddressEIP55, error) {
ks, err := fetchKeystore(api.am)
if err != nil {
return common.AddressEIP55{}, err
}
acc, err := ks.NewAccount(password)
if err == nil {
addrEIP55 := common.AddressEIP55(acc.Address)
log.Info("Your new key was generated", "address", addrEIP55.String())
log.Warn("Please backup your key file!", "path", acc.URL.Path)
log.Warn("Please remember your password!")
return addrEIP55, nil
}
return common.AddressEIP55{}, err
}
// fetchKeystore retrieves the encrypted keystore from the account manager.
func fetchKeystore(am *accounts.Manager) (*keystore.KeyStore, error) {
if ks := am.Backends(keystore.KeyStoreType); len(ks) > 0 {
return ks[0].(*keystore.KeyStore), nil
}
return nil, errors.New("local keystore not used")
}
// ImportRawKey stores the given hex encoded ECDSA key into the key directory,
// encrypting it with the passphrase.
func (api *PersonalAccountAPI) ImportRawKey(privkey string, password string) (common.Address, error) {
key, err := crypto.HexToECDSA(privkey)
if err != nil {
return common.Address{}, err
}
ks, err := fetchKeystore(api.am)
if err != nil {
return common.Address{}, err
}
acc, err := ks.ImportECDSA(key, password)
return acc.Address, err
}
// UnlockAccount will unlock the account associated with the given address with
// the given password for duration seconds. If duration is nil it will use a
// default of 300 seconds. It returns an indication if the account was unlocked.
func (api *PersonalAccountAPI) UnlockAccount(ctx context.Context, addr common.Address, password string, duration *uint64) (bool, error) {
// When the API is exposed by external RPC(http, ws etc), unless the user
// explicitly specifies to allow the insecure account unlocking, otherwise
// it is disabled.
if api.b.ExtRPCEnabled() && !api.b.AccountManager().Config().InsecureUnlockAllowed {
return false, errors.New("account unlock with HTTP access is forbidden")
}
const max = uint64(time.Duration(gomath.MaxInt64) / time.Second)
var d time.Duration
if duration == nil {
d = 300 * time.Second
} else if *duration > max {
return false, errors.New("unlock duration too large")
} else {
d = time.Duration(*duration) * time.Second
}
ks, err := fetchKeystore(api.am)
if err != nil {
return false, err
}
err = ks.TimedUnlock(accounts.Account{Address: addr}, password, d)
if err != nil {
log.Warn("Failed account unlock attempt", "address", addr, "err", err)
}
return err == nil, err
}
// LockAccount will lock the account associated with the given address when it's unlocked.
func (api *PersonalAccountAPI) LockAccount(addr common.Address) bool {
if ks, err := fetchKeystore(api.am); err == nil {
return ks.Lock(addr) == nil
}
return false
}
// signTransaction sets defaults and signs the given transaction
// NOTE: the caller needs to ensure that the nonceLock is held, if applicable,
// and release it after the transaction has been submitted to the tx pool
func (api *PersonalAccountAPI) signTransaction(ctx context.Context, args *TransactionArgs, passwd string) (*types.Transaction, error) {
// Look up the wallet containing the requested signer
account := accounts.Account{Address: args.from()}
wallet, err := api.am.Find(account)
if err != nil {
return nil, err
}
// Set some sanity defaults and terminate on failure
if err := args.setDefaults(ctx, api.b, false); err != nil {
return nil, err
}
// Assemble the transaction and sign with the wallet
tx := args.ToTransaction(types.LegacyTxType)
return wallet.SignTxWithPassphrase(account, passwd, tx, api.b.ChainConfig().ChainID)
}
// SendTransaction will create a transaction from the given arguments and
// tries to sign it with the key associated with args.From. If the given
// passwd isn't able to decrypt the key it fails.
func (api *PersonalAccountAPI) SendTransaction(ctx context.Context, args TransactionArgs, passwd string) (common.Hash, error) {
if args.Nonce == nil {
// Hold the mutex around signing to prevent concurrent assignment of
// the same nonce to multiple accounts.
api.nonceLock.LockAddr(args.from())
defer api.nonceLock.UnlockAddr(args.from())
}
if args.IsEIP4844() {
return common.Hash{}, errBlobTxNotSupported
}
signed, err := api.signTransaction(ctx, &args, passwd)
if err != nil {
log.Warn("Failed transaction send attempt", "from", args.from(), "to", args.To, "value", args.Value.ToInt(), "err", err)
return common.Hash{}, err
}
return SubmitTransaction(ctx, api.b, signed)
}
// SignTransaction will create a transaction from the given arguments and
// tries to sign it with the key associated with args.From. If the given passwd isn't
// able to decrypt the key it fails. The transaction is returned in RLP-form, not broadcast
// to other nodes
func (api *PersonalAccountAPI) SignTransaction(ctx context.Context, args TransactionArgs, passwd string) (*SignTransactionResult, error) {
// No need to obtain the noncelock mutex, since we won't be sending this
// tx into the transaction pool, but right back to the user
if args.From == nil {
return nil, errors.New("sender not specified")
}
if args.Gas == nil {
return nil, errors.New("gas not specified")
}
if args.GasPrice == nil && (args.MaxFeePerGas == nil || args.MaxPriorityFeePerGas == nil) {
return nil, errors.New("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas")
}
if args.IsEIP4844() {
return nil, errBlobTxNotSupported
}
if args.Nonce == nil {
return nil, errors.New("nonce not specified")
}
// Before actually signing the transaction, ensure the transaction fee is reasonable.
tx := args.ToTransaction(types.LegacyTxType)
if err := checkTxFee(tx.GasPrice(), tx.Gas(), api.b.RPCTxFeeCap()); err != nil {
return nil, err
}
signed, err := api.signTransaction(ctx, &args, passwd)
if err != nil {
log.Warn("Failed transaction sign attempt", "from", args.from(), "to", args.To, "value", args.Value.ToInt(), "err", err)
return nil, err
}
data, err := signed.MarshalBinary()
if err != nil {
return nil, err
}
return &SignTransactionResult{data, signed}, nil
}
// Sign calculates an Ethereum ECDSA signature for:
// keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))
//
// Note, the produced signature conforms to the secp256k1 curve R, S and V values,
// where the V value will be 27 or 28 for legacy reasons.
//
// The key used to calculate the signature is decrypted with the given password.
//
// https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-personal#personal-sign
func (api *PersonalAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr common.Address, passwd string) (hexutil.Bytes, error) {
// Look up the wallet containing the requested signer
account := accounts.Account{Address: addr}
wallet, err := api.b.AccountManager().Find(account)
if err != nil {
return nil, err
}
// Assemble sign the data with the wallet
signature, err := wallet.SignTextWithPassphrase(account, passwd, data)
if err != nil {
log.Warn("Failed data sign attempt", "address", addr, "err", err)
return nil, err
}
signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
return signature, nil
}
// EcRecover returns the address for the account that was used to create the signature.
// Note, this function is compatible with eth_sign and personal_sign. As such it recovers
// the address of:
// hash = keccak256("\x19Ethereum Signed Message:\n"${message length}${message})
// addr = ecrecover(hash, signature)
//
// Note, the signature must conform to the secp256k1 curve R, S and V values, where
// the V value must be 27 or 28 for legacy reasons.
//
// https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-personal#personal-ecrecover
func (api *PersonalAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) {
if len(sig) != crypto.SignatureLength {
return common.Address{}, fmt.Errorf("signature must be %d bytes long", crypto.SignatureLength)
}
if sig[crypto.RecoveryIDOffset] != 27 && sig[crypto.RecoveryIDOffset] != 28 {
return common.Address{}, errors.New("invalid Ethereum signature (V is not 27 or 28)")
}
sig[crypto.RecoveryIDOffset] -= 27 // Transform yellow paper V from 27/28 to 0/1
rpk, err := crypto.SigToPub(accounts.TextHash(data), sig)
if err != nil {
return common.Address{}, err
}
return crypto.PubkeyToAddress(*rpk), nil
}
// InitializeWallet initializes a new wallet at the provided URL, by generating and returning a new private key.
func (api *PersonalAccountAPI) InitializeWallet(ctx context.Context, url string) (string, error) {
wallet, err := api.am.Wallet(url)
if err != nil {
return "", err
}
entropy, err := bip39.NewEntropy(256)
if err != nil {
return "", err
}
mnemonic, err := bip39.NewMnemonic(entropy)
if err != nil {
return "", err
}
seed := bip39.NewSeed(mnemonic, "")
switch wallet := wallet.(type) {
case *scwallet.Wallet:
return mnemonic, wallet.Initialize(seed)
default:
return "", errors.New("specified wallet does not support initialization")
}
}
// Unpair deletes a pairing between wallet and geth.
func (api *PersonalAccountAPI) Unpair(ctx context.Context, url string, pin string) error {
wallet, err := api.am.Wallet(url)
if err != nil {
return err
}
switch wallet := wallet.(type) {
case *scwallet.Wallet:
return wallet.Unpair([]byte(pin))
default:
return errors.New("specified wallet does not support pairing")
}
}
// BlockChainAPI provides an API to access Ethereum blockchain data. // BlockChainAPI provides an API to access Ethereum blockchain data.
type BlockChainAPI struct { type BlockChainAPI struct {
b Backend b Backend

View file

@ -118,9 +118,6 @@ func GetAPIs(apiBackend Backend) []rpc.API {
}, { }, {
Namespace: "eth", Namespace: "eth",
Service: NewEthereumAccountAPI(apiBackend.AccountManager()), Service: NewEthereumAccountAPI(apiBackend.AccountManager()),
}, {
Namespace: "personal",
Service: NewPersonalAccountAPI(apiBackend, nonceLock),
}, },
} }
} }

View file

@ -17,7 +17,6 @@
package flags package flags
import ( import (
"encoding"
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
@ -122,119 +121,6 @@ func (f *DirectoryFlag) GetDefaultText() string {
return f.GetValue() return f.GetValue()
} }
type TextMarshaler interface {
encoding.TextMarshaler
encoding.TextUnmarshaler
}
// textMarshalerVal turns a TextMarshaler into a flag.Value
type textMarshalerVal struct {
v TextMarshaler
}
func (v textMarshalerVal) String() string {
if v.v == nil {
return ""
}
text, _ := v.v.MarshalText()
return string(text)
}
func (v textMarshalerVal) Set(s string) error {
return v.v.UnmarshalText([]byte(s))
}
var (
_ cli.Flag = (*TextMarshalerFlag)(nil)
_ cli.RequiredFlag = (*TextMarshalerFlag)(nil)
_ cli.VisibleFlag = (*TextMarshalerFlag)(nil)
_ cli.DocGenerationFlag = (*TextMarshalerFlag)(nil)
_ cli.CategorizableFlag = (*TextMarshalerFlag)(nil)
)
// TextMarshalerFlag wraps a TextMarshaler value.
type TextMarshalerFlag struct {
Name string
Category string
DefaultText string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value TextMarshaler
Aliases []string
EnvVars []string
}
// For cli.Flag:
func (f *TextMarshalerFlag) Names() []string { return append([]string{f.Name}, f.Aliases...) }
func (f *TextMarshalerFlag) IsSet() bool { return f.HasBeenSet }
func (f *TextMarshalerFlag) String() string { return cli.FlagStringer(f) }
func (f *TextMarshalerFlag) Apply(set *flag.FlagSet) error {
for _, envVar := range f.EnvVars {
envVar = strings.TrimSpace(envVar)
if value, found := syscall.Getenv(envVar); found {
if err := f.Value.UnmarshalText([]byte(value)); err != nil {
return fmt.Errorf("could not parse %q from environment variable %q for flag %s: %s", value, envVar, f.Name, err)
}
f.HasBeenSet = true
break
}
}
eachName(f, func(name string) {
set.Var(textMarshalerVal{f.Value}, f.Name, f.Usage)
})
return nil
}
// For cli.RequiredFlag:
func (f *TextMarshalerFlag) IsRequired() bool { return f.Required }
// For cli.VisibleFlag:
func (f *TextMarshalerFlag) IsVisible() bool { return !f.Hidden }
// For cli.CategorizableFlag:
func (f *TextMarshalerFlag) GetCategory() string { return f.Category }
// For cli.DocGenerationFlag:
func (f *TextMarshalerFlag) TakesValue() bool { return true }
func (f *TextMarshalerFlag) GetUsage() string { return f.Usage }
func (f *TextMarshalerFlag) GetEnvVars() []string { return f.EnvVars }
func (f *TextMarshalerFlag) GetValue() string {
t, err := f.Value.MarshalText()
if err != nil {
return "(ERR: " + err.Error() + ")"
}
return string(t)
}
func (f *TextMarshalerFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GlobalTextMarshaler returns the value of a TextMarshalerFlag from the global flag set.
func GlobalTextMarshaler(ctx *cli.Context, name string) TextMarshaler {
val := ctx.Generic(name)
if val == nil {
return nil
}
return val.(textMarshalerVal).v
}
var ( var (
_ cli.Flag = (*BigFlag)(nil) _ cli.Flag = (*BigFlag)(nil)
_ cli.RequiredFlag = (*BigFlag)(nil) _ cli.RequiredFlag = (*BigFlag)(nil)

View file

@ -48,15 +48,6 @@ func NewApp(usage string) *cli.App {
return app return app
} }
// Merge merges the given flag slices.
func Merge(groups ...[]cli.Flag) []cli.Flag {
var ret []cli.Flag
for _, group := range groups {
ret = append(ret, group...)
}
return ret
}
var migrationApplied = map[*cli.Command]struct{}{} var migrationApplied = map[*cli.Command]struct{}{}
// MigrateGlobalFlags makes all global flag values available in the // MigrateGlobalFlags makes all global flag values available in the
@ -265,9 +256,6 @@ func AutoEnvVars(flags []cli.Flag, prefix string) {
case *BigFlag: case *BigFlag:
flag.EnvVars = append(flag.EnvVars, envvar) flag.EnvVars = append(flag.EnvVars, envvar)
case *TextMarshalerFlag:
flag.EnvVars = append(flag.EnvVars, envvar)
case *DirectoryFlag: case *DirectoryFlag:
flag.EnvVars = append(flag.EnvVars, envvar) flag.EnvVars = append(flag.EnvVars, envvar)
} }

View file

@ -18,16 +18,15 @@
package web3ext package web3ext
var Modules = map[string]string{ var Modules = map[string]string{
"admin": AdminJs, "admin": AdminJs,
"clique": CliqueJs, "clique": CliqueJs,
"debug": DebugJs, "debug": DebugJs,
"eth": EthJs, "eth": EthJs,
"miner": MinerJs, "miner": MinerJs,
"net": NetJs, "net": NetJs,
"personal": PersonalJs, "rpc": RpcJs,
"rpc": RpcJs, "txpool": TxpoolJs,
"txpool": TxpoolJs, "dev": DevJs,
"dev": DevJs,
} }
const CliqueJs = ` const CliqueJs = `
@ -658,62 +657,6 @@ web3._extend({
}); });
` `
const PersonalJs = `
web3._extend({
property: 'personal',
methods: [
new web3._extend.Method({
name: 'importRawKey',
call: 'personal_importRawKey',
params: 2
}),
new web3._extend.Method({
name: 'sign',
call: 'personal_sign',
params: 3,
inputFormatter: [null, web3._extend.formatters.inputAddressFormatter, null]
}),
new web3._extend.Method({
name: 'ecRecover',
call: 'personal_ecRecover',
params: 2
}),
new web3._extend.Method({
name: 'openWallet',
call: 'personal_openWallet',
params: 2
}),
new web3._extend.Method({
name: 'deriveAccount',
call: 'personal_deriveAccount',
params: 3
}),
new web3._extend.Method({
name: 'signTransaction',
call: 'personal_signTransaction',
params: 2,
inputFormatter: [web3._extend.formatters.inputTransactionFormatter, null]
}),
new web3._extend.Method({
name: 'unpair',
call: 'personal_unpair',
params: 2
}),
new web3._extend.Method({
name: 'initializeWallet',
call: 'personal_initializeWallet',
params: 1
})
],
properties: [
new web3._extend.Property({
name: 'listWallets',
getter: 'personal_listWallets'
}),
]
})
`
const RpcJs = ` const RpcJs = `
web3._extend({ web3._extend({
property: 'rpc', property: 'rpc',

View file

@ -375,25 +375,13 @@ func (n *Node) obtainJWTSecret(cliParam string) ([]byte, error) {
// startup. It's not meant to be called at any time afterwards as it makes certain // startup. It's not meant to be called at any time afterwards as it makes certain
// assumptions about the state of the node. // assumptions about the state of the node.
func (n *Node) startRPC() error { func (n *Node) startRPC() error {
// Filter out personal api if err := n.startInProc(n.rpcAPIs); err != nil {
var apis []rpc.API
for _, api := range n.rpcAPIs {
if api.Namespace == "personal" {
if n.config.EnablePersonal {
log.Warn("Deprecated personal namespace activated")
} else {
continue
}
}
apis = append(apis, api)
}
if err := n.startInProc(apis); err != nil {
return err return err
} }
// Configure IPC. // Configure IPC.
if n.ipc.endpoint != "" { if n.ipc.endpoint != "" {
if err := n.ipc.start(apis); err != nil { if err := n.ipc.start(n.rpcAPIs); err != nil {
return err return err
} }
} }

View file

@ -294,7 +294,7 @@ func typedDataRequest(data any) (*SignDataRequest, error) {
func (api *SignerAPI) EcRecover(ctx context.Context, data hexutil.Bytes, sig hexutil.Bytes) (common.Address, error) { func (api *SignerAPI) EcRecover(ctx context.Context, data hexutil.Bytes, sig hexutil.Bytes) (common.Address, error) {
// Returns the address for the Account that was used to create the signature. // Returns the address for the Account that was used to create the signature.
// //
// Note, this function is compatible with eth_sign and personal_sign. As such it recovers // Note, this function is compatible with eth_sign. As such it recovers
// the address of: // the address of:
// hash = keccak256("\x19Ethereum Signed Message:\n${message length}${message}") // hash = keccak256("\x19Ethereum Signed Message:\n${message length}${message}")
// addr = ecrecover(hash, signature) // addr = ecrecover(hash, signature)

View file

@ -257,8 +257,12 @@ func fuzzCrossG1MultiExp(data []byte) int {
cp.MultiExp(gnarkPoints, gnarkScalars, ecc.MultiExpConfig{}) cp.MultiExp(gnarkPoints, gnarkScalars, ecc.MultiExpConfig{})
// compare result // compare result
if !(bytes.Equal(cp.Marshal(), g1.ToBytes(&kp))) { gnarkRes := cp.Marshal()
panic("G1 multi exponentiation mismatch gnark / geth ") gethRes := g1.ToBytes(&kp)
if !bytes.Equal(gnarkRes, gethRes) {
msg := fmt.Sprintf("G1 multi exponentiation mismatch gnark/geth.\ngnark: %x\ngeth: %x\ninput: %x\n ",
gnarkRes, gethRes, data)
panic(msg)
} }
return 1 return 1
@ -283,15 +287,18 @@ func getG1Points(input io.Reader) (*bls12381.PointG1, *gnark.G1Affine, *blst.P1A
if err != nil { if err != nil {
panic(fmt.Sprintf("Could not marshal gnark.G1 -> geth.G1: %v", err)) panic(fmt.Sprintf("Could not marshal gnark.G1 -> geth.G1: %v", err))
} }
if !bytes.Equal(g1.ToBytes(kp), cpBytes) {
panic("bytes(gnark.G1) != bytes(geth.G1)") gnarkRes := g1.ToBytes(kp)
if !bytes.Equal(gnarkRes, cpBytes) {
panic(fmt.Sprintf("bytes(gnark.G1) != bytes(geth.G1)\ngnark.G1: %x\ngeth.G1: %x\n", gnarkRes, cpBytes))
} }
// marshal gnark point -> blst point // marshal gnark point -> blst point
scalar := new(blst.Scalar).FromBEndian(common.LeftPadBytes(s.Bytes(), 32)) scalar := new(blst.Scalar).FromBEndian(common.LeftPadBytes(s.Bytes(), 32))
p1 := new(blst.P1Affine).From(scalar) p1 := new(blst.P1Affine).From(scalar)
if !bytes.Equal(p1.Serialize(), cpBytes) { blstRes := p1.Serialize()
panic("bytes(blst.G1) != bytes(geth.G1)") if !bytes.Equal(blstRes, cpBytes) {
panic(fmt.Sprintf("bytes(blst.G1) != bytes(geth.G1)\nblst.G1: %x\ngeth.G1: %x\n", blstRes, cpBytes))
} }
return kp, cp, p1, nil return kp, cp, p1, nil
@ -316,8 +323,10 @@ func getG2Points(input io.Reader) (*bls12381.PointG2, *gnark.G2Affine, *blst.P2A
if err != nil { if err != nil {
panic(fmt.Sprintf("Could not marshal gnark.G2 -> geth.G2: %v", err)) panic(fmt.Sprintf("Could not marshal gnark.G2 -> geth.G2: %v", err))
} }
if !bytes.Equal(g2.ToBytes(kp), cpBytes) {
panic("bytes(gnark.G2) != bytes(geth.G2)") gnarkRes := g2.ToBytes(kp)
if !bytes.Equal(gnarkRes, cpBytes) {
panic(fmt.Sprintf("bytes(gnark.G2) != bytes(geth.G2)\ngnark.G2: %x\ngeth.G2: %x\n", gnarkRes, cpBytes))
} }
// marshal gnark point -> blst point // marshal gnark point -> blst point