diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go
index cb4eea3a0..e410522ac 100644
--- a/accounts/abi/bind/backends/simulated.go
+++ b/accounts/abi/bind/backends/simulated.go
@@ -795,7 +795,7 @@ type callMsg struct {
func (m callMsg) From() common.Address { return m.CallMsg.From }
func (m callMsg) Nonce() uint64 { return 0 }
-func (m callMsg) CheckNonce() bool { return false }
+func (m callMsg) IsFake() bool { return true }
func (m callMsg) To() *common.Address { return m.CallMsg.To }
func (m callMsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
func (m callMsg) GasFeeCap() *big.Int { return m.CallMsg.GasFeeCap }
diff --git a/accounts/external/backend.go b/accounts/external/backend.go
index b2de9e932..e3f754eaf 100644
--- a/accounts/external/backend.go
+++ b/accounts/external/backend.go
@@ -196,6 +196,10 @@ type signTransactionResult struct {
Tx *types.Transaction `json:"tx"`
}
+// SignTx sends the transaction to the external signer.
+// If chainID is nil, or tx.ChainID is zero, the chain ID will be assigned
+// by the external signer. For non-legacy transactions, the chain ID of the
+// transaction overrides the chainID parameter.
func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
data := hexutil.Bytes(tx.Data())
var to *common.MixedcaseAddress
@@ -218,17 +222,17 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio
args.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap())
args.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap())
default:
- return nil, fmt.Errorf("Unsupported tx type %d", tx.Type())
+ return nil, fmt.Errorf("unsupported tx type %d", tx.Type())
}
// We should request the default chain id that we're operating with
// (the chain we're executing on)
- if chainID != nil {
+ if chainID != nil && chainID.Sign() != 0 {
args.ChainID = (*hexutil.Big)(chainID)
}
if tx.Type() != types.LegacyTxType {
// However, if the user asked for a particular chain id, then we should
// use that instead.
- if tx.ChainId() != nil {
+ if tx.ChainId().Sign() != 0 {
args.ChainID = (*hexutil.Big)(tx.ChainId())
}
accessList := tx.AccessList()
diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go
index 9c5d4f9b2..436e558b5 100644
--- a/cmd/geth/chaincmd.go
+++ b/cmd/geth/chaincmd.go
@@ -68,7 +68,6 @@ It expects the genesis file as argument.`,
utils.RopstenFlag,
utils.RinkebyFlag,
utils.GoerliFlag,
- utils.CalaverasFlag,
},
Category: "BLOCKCHAIN COMMANDS",
Description: `
@@ -92,11 +91,15 @@ The dumpgenesis command dumps the genesis block configuration in JSON format to
utils.MetricsHTTPFlag,
utils.MetricsPortFlag,
utils.MetricsEnableInfluxDBFlag,
+ utils.MetricsEnableInfluxDBV2Flag,
utils.MetricsInfluxDBEndpointFlag,
utils.MetricsInfluxDBDatabaseFlag,
utils.MetricsInfluxDBUsernameFlag,
utils.MetricsInfluxDBPasswordFlag,
utils.MetricsInfluxDBTagsFlag,
+ utils.MetricsInfluxDBTokenFlag,
+ utils.MetricsInfluxDBBucketFlag,
+ utils.MetricsInfluxDBOrganizationFlag,
utils.TxLookupLimitFlag,
},
Category: "BLOCKCHAIN COMMANDS",
diff --git a/cmd/geth/config.go b/cmd/geth/config.go
index 117be96ae..604f907b7 100644
--- a/cmd/geth/config.go
+++ b/cmd/geth/config.go
@@ -233,6 +233,18 @@ func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) {
if ctx.GlobalIsSet(utils.MetricsInfluxDBTagsFlag.Name) {
cfg.Metrics.InfluxDBTags = ctx.GlobalString(utils.MetricsInfluxDBTagsFlag.Name)
}
+ if ctx.GlobalIsSet(utils.MetricsEnableInfluxDBV2Flag.Name) {
+ cfg.Metrics.EnableInfluxDBV2 = ctx.GlobalBool(utils.MetricsEnableInfluxDBV2Flag.Name)
+ }
+ if ctx.GlobalIsSet(utils.MetricsInfluxDBTokenFlag.Name) {
+ cfg.Metrics.InfluxDBToken = ctx.GlobalString(utils.MetricsInfluxDBTokenFlag.Name)
+ }
+ if ctx.GlobalIsSet(utils.MetricsInfluxDBBucketFlag.Name) {
+ cfg.Metrics.InfluxDBBucket = ctx.GlobalString(utils.MetricsInfluxDBBucketFlag.Name)
+ }
+ if ctx.GlobalIsSet(utils.MetricsInfluxDBOrganizationFlag.Name) {
+ cfg.Metrics.InfluxDBOrganization = ctx.GlobalString(utils.MetricsInfluxDBOrganizationFlag.Name)
+ }
}
func deprecated(field string) bool {
diff --git a/cmd/geth/consolecmd.go b/cmd/geth/consolecmd.go
index 776412df6..0e156fde9 100644
--- a/cmd/geth/consolecmd.go
+++ b/cmd/geth/consolecmd.go
@@ -134,8 +134,6 @@ func remoteConsole(ctx *cli.Context) error {
path = filepath.Join(path, "rinkeby")
} else if ctx.GlobalBool(utils.GoerliFlag.Name) {
path = filepath.Join(path, "goerli")
- } else if ctx.GlobalBool(utils.CalaverasFlag.Name) {
- path = filepath.Join(path, "calaveras")
}
}
endpoint = fmt.Sprintf("%s/geth.ipc", path)
diff --git a/cmd/geth/dbcmd.go b/cmd/geth/dbcmd.go
index bb3cf0390..54ada4089 100644
--- a/cmd/geth/dbcmd.go
+++ b/cmd/geth/dbcmd.go
@@ -75,7 +75,6 @@ Remove blockchain and state databases`,
utils.RopstenFlag,
utils.RinkebyFlag,
utils.GoerliFlag,
- utils.CalaverasFlag,
},
Usage: "Inspect the storage size for each type of data in the database",
Description: `This commands iterates the entire database. If the optional 'prefix' and 'start' arguments are provided, then the iteration is limited to the given subset of data.`,
@@ -91,7 +90,6 @@ Remove blockchain and state databases`,
utils.RopstenFlag,
utils.RinkebyFlag,
utils.GoerliFlag,
- utils.CalaverasFlag,
},
}
dbCompactCmd = cli.Command{
@@ -105,7 +103,6 @@ Remove blockchain and state databases`,
utils.RopstenFlag,
utils.RinkebyFlag,
utils.GoerliFlag,
- utils.CalaverasFlag,
utils.CacheFlag,
utils.CacheDatabaseFlag,
},
@@ -125,7 +122,6 @@ corruption if it is aborted during execution'!`,
utils.RopstenFlag,
utils.RinkebyFlag,
utils.GoerliFlag,
- utils.CalaverasFlag,
},
Description: "This command looks up the specified database key from the database.",
}
@@ -141,7 +137,6 @@ corruption if it is aborted during execution'!`,
utils.RopstenFlag,
utils.RinkebyFlag,
utils.GoerliFlag,
- utils.CalaverasFlag,
},
Description: `This command deletes the specified database key from the database.
WARNING: This is a low-level operation which may cause database corruption!`,
@@ -158,7 +153,6 @@ WARNING: This is a low-level operation which may cause database corruption!`,
utils.RopstenFlag,
utils.RinkebyFlag,
utils.GoerliFlag,
- utils.CalaverasFlag,
},
Description: `This command sets a given database key to the given value.
WARNING: This is a low-level operation which may cause database corruption!`,
@@ -175,7 +169,6 @@ WARNING: This is a low-level operation which may cause database corruption!`,
utils.RopstenFlag,
utils.RinkebyFlag,
utils.GoerliFlag,
- utils.CalaverasFlag,
},
Description: "This command looks up the specified database key from the database.",
}
@@ -191,7 +184,6 @@ WARNING: This is a low-level operation which may cause database corruption!`,
utils.RopstenFlag,
utils.RinkebyFlag,
utils.GoerliFlag,
- utils.CalaverasFlag,
},
Description: "This command displays information about the freezer index.",
}
diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index 12d2465c6..d75e98425 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -141,7 +141,6 @@ var (
utils.RopstenFlag,
utils.RinkebyFlag,
utils.GoerliFlag,
- utils.CalaverasFlag,
utils.VMEnableDebugFlag,
utils.NetworkIdFlag,
utils.EthStatsURLFlag,
@@ -198,6 +197,10 @@ var (
utils.MetricsInfluxDBUsernameFlag,
utils.MetricsInfluxDBPasswordFlag,
utils.MetricsInfluxDBTagsFlag,
+ utils.MetricsEnableInfluxDBV2Flag,
+ utils.MetricsInfluxDBTokenFlag,
+ utils.MetricsInfluxDBBucketFlag,
+ utils.MetricsInfluxDBOrganizationFlag,
}
)
@@ -277,9 +280,6 @@ func prepare(ctx *cli.Context) {
case ctx.GlobalIsSet(utils.GoerliFlag.Name):
log.Info("Starting Geth on Görli testnet...")
- case ctx.GlobalIsSet(utils.CalaverasFlag.Name):
- log.Info("Starting Geth on Calaveras testnet...")
-
case ctx.GlobalIsSet(utils.DeveloperFlag.Name):
log.Info("Starting Geth in ephemeral dev mode...")
diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go
index 3c401eae8..708edcc79 100644
--- a/cmd/geth/usage.go
+++ b/cmd/geth/usage.go
@@ -44,7 +44,6 @@ var AppHelpFlagGroups = []flags.FlagGroup{
utils.MainnetFlag,
utils.GoerliFlag,
utils.RinkebyFlag,
- utils.CalaverasFlag,
utils.RopstenFlag,
utils.SyncModeFlag,
utils.ExitWhenSyncedFlag,
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 7fa3d8b86..8a53f525f 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -125,10 +125,6 @@ var (
Name: "keystore",
Usage: "Directory for the keystore (default = inside the datadir)",
}
- NoUSBFlag = cli.BoolFlag{
- Name: "nousb",
- Usage: "Disables monitoring for and managing USB hardware wallets (deprecated)",
- }
USBFlag = cli.BoolFlag{
Name: "usb",
Usage: "Enable monitoring and management of USB hardware wallets",
@@ -151,10 +147,6 @@ var (
Name: "goerli",
Usage: "Görli network: pre-configured proof-of-authority test network",
}
- CalaverasFlag = cli.BoolFlag{
- Name: "calaveras",
- Usage: "Calaveras network: pre-configured proof-of-authority shortlived test network.",
- }
RinkebyFlag = cli.BoolFlag{
Name: "rinkeby",
Usage: "Rinkeby network: pre-configured proof-of-authority test network",
@@ -756,6 +748,29 @@ var (
Value: metrics.DefaultConfig.InfluxDBTags,
}
+ MetricsEnableInfluxDBV2Flag = cli.BoolFlag{
+ Name: "metrics.influxdbv2",
+ Usage: "Enable metrics export/push to an external InfluxDB v2 database",
+ }
+
+ MetricsInfluxDBTokenFlag = cli.StringFlag{
+ Name: "metrics.influxdb.token",
+ Usage: "Token to authorize access to the database (v2 only)",
+ Value: metrics.DefaultConfig.InfluxDBToken,
+ }
+
+ MetricsInfluxDBBucketFlag = cli.StringFlag{
+ Name: "metrics.influxdb.bucket",
+ Usage: "InfluxDB bucket name to push reported metrics to (v2 only)",
+ Value: metrics.DefaultConfig.InfluxDBBucket,
+ }
+
+ MetricsInfluxDBOrganizationFlag = cli.StringFlag{
+ Name: "metrics.influxdb.organization",
+ Usage: "InfluxDB organization name (v2 only)",
+ Value: metrics.DefaultConfig.InfluxDBOrganization,
+ }
+
CatalystFlag = cli.BoolFlag{
Name: "catalyst",
Usage: "Catalyst mode (eth2 integration testing)",
@@ -778,9 +793,6 @@ func MakeDataDir(ctx *cli.Context) string {
if ctx.GlobalBool(GoerliFlag.Name) {
return filepath.Join(path, "goerli")
}
- if ctx.GlobalBool(CalaverasFlag.Name) {
- return filepath.Join(path, "calaveras")
- }
return path
}
Fatalf("Cannot determine default data directory, please set manually (--datadir)")
@@ -833,8 +845,6 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
urls = params.RinkebyBootnodes
case ctx.GlobalBool(GoerliFlag.Name):
urls = params.GoerliBootnodes
- case ctx.GlobalBool(CalaverasFlag.Name):
- urls = params.CalaverasBootnodes
case cfg.BootstrapNodes != nil:
return // already set, don't apply defaults.
}
@@ -1278,8 +1288,6 @@ func setDataDir(ctx *cli.Context, cfg *node.Config) {
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "rinkeby")
case ctx.GlobalBool(GoerliFlag.Name) && cfg.DataDir == node.DefaultDataDir():
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "goerli")
- case ctx.GlobalBool(CalaverasFlag.Name) && cfg.DataDir == node.DefaultDataDir():
- cfg.DataDir = filepath.Join(node.DefaultDataDir(), "calaveras")
}
}
@@ -1465,7 +1473,7 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) {
// SetEthConfig applies eth-related command line flags to the config.
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
// Avoid conflicting network flags
- CheckExclusive(ctx, MainnetFlag, DeveloperFlag, RopstenFlag, RinkebyFlag, GoerliFlag, CalaverasFlag)
+ CheckExclusive(ctx, MainnetFlag, DeveloperFlag, RopstenFlag, RinkebyFlag, GoerliFlag)
CheckExclusive(ctx, LightServeFlag, SyncModeFlag, "light")
CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
if ctx.GlobalString(GCModeFlag.Name) == "archive" && ctx.GlobalUint64(TxLookupLimitFlag.Name) != 0 {
@@ -1618,11 +1626,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
}
cfg.Genesis = core.DefaultGoerliGenesisBlock()
SetDNSDiscoveryDefaults(cfg, params.GoerliGenesisHash)
- case ctx.GlobalBool(CalaverasFlag.Name):
- if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
- cfg.NetworkId = 123 // https://gist.github.com/holiman/c5697b041b3dc18c50a5cdd382cbdd16
- }
- cfg.Genesis = core.DefaultCalaverasGenesisBlock()
case ctx.GlobalBool(DeveloperFlag.Name):
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 1337
@@ -1739,11 +1742,36 @@ func SetupMetrics(ctx *cli.Context) {
log.Info("Enabling metrics collection")
var (
- enableExport = ctx.GlobalBool(MetricsEnableInfluxDBFlag.Name)
- endpoint = ctx.GlobalString(MetricsInfluxDBEndpointFlag.Name)
- database = ctx.GlobalString(MetricsInfluxDBDatabaseFlag.Name)
- username = ctx.GlobalString(MetricsInfluxDBUsernameFlag.Name)
- password = ctx.GlobalString(MetricsInfluxDBPasswordFlag.Name)
+ enableExport = ctx.GlobalBool(MetricsEnableInfluxDBFlag.Name)
+ enableExportV2 = ctx.GlobalBool(MetricsEnableInfluxDBV2Flag.Name)
+ )
+
+ if enableExport || enableExportV2 {
+ CheckExclusive(ctx, MetricsEnableInfluxDBFlag, MetricsEnableInfluxDBV2Flag)
+
+ v1FlagIsSet := ctx.GlobalIsSet(MetricsInfluxDBUsernameFlag.Name) ||
+ ctx.GlobalIsSet(MetricsInfluxDBPasswordFlag.Name)
+
+ v2FlagIsSet := ctx.GlobalIsSet(MetricsInfluxDBTokenFlag.Name) ||
+ ctx.GlobalIsSet(MetricsInfluxDBOrganizationFlag.Name) ||
+ ctx.GlobalIsSet(MetricsInfluxDBBucketFlag.Name)
+
+ if enableExport && v2FlagIsSet {
+ Fatalf("Flags --influxdb.metrics.organization, --influxdb.metrics.token, --influxdb.metrics.bucket are only available for influxdb-v2")
+ } else if enableExportV2 && v1FlagIsSet {
+ Fatalf("Flags --influxdb.metrics.username, --influxdb.metrics.password are only available for influxdb-v1")
+ }
+ }
+
+ var (
+ endpoint = ctx.GlobalString(MetricsInfluxDBEndpointFlag.Name)
+ database = ctx.GlobalString(MetricsInfluxDBDatabaseFlag.Name)
+ username = ctx.GlobalString(MetricsInfluxDBUsernameFlag.Name)
+ password = ctx.GlobalString(MetricsInfluxDBPasswordFlag.Name)
+
+ token = ctx.GlobalString(MetricsInfluxDBTokenFlag.Name)
+ bucket = ctx.GlobalString(MetricsInfluxDBBucketFlag.Name)
+ organization = ctx.GlobalString(MetricsInfluxDBOrganizationFlag.Name)
)
if enableExport {
@@ -1752,6 +1780,12 @@ func SetupMetrics(ctx *cli.Context) {
log.Info("Enabling metrics export to InfluxDB")
go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", tagsMap)
+ } else if enableExportV2 {
+ tagsMap := SplitTagsFlag(ctx.GlobalString(MetricsInfluxDBTagsFlag.Name))
+
+ log.Info("Enabling metrics export to InfluxDB (v2)")
+
+ go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, token, bucket, organization, "geth.", tagsMap)
}
if ctx.GlobalIsSet(MetricsHTTPFlag.Name) {
@@ -1812,8 +1846,6 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis {
genesis = core.DefaultRinkebyGenesisBlock()
case ctx.GlobalBool(GoerliFlag.Name):
genesis = core.DefaultGoerliGenesisBlock()
- case ctx.GlobalBool(CalaverasFlag.Name):
- genesis = core.DefaultCalaverasGenesisBlock()
case ctx.GlobalBool(DeveloperFlag.Name):
Fatalf("Developer chains are ephemeral")
}
diff --git a/cmd/utils/flags_legacy.go b/cmd/utils/flags_legacy.go
index df597e365..627f77475 100644
--- a/cmd/utils/flags_legacy.go
+++ b/cmd/utils/flags_legacy.go
@@ -36,10 +36,15 @@ var ShowDeprecated = cli.Command{
var DeprecatedFlags = []cli.Flag{
LegacyMinerGasTargetFlag,
+ NoUSBFlag,
}
var (
// (Deprecated May 2020, shown in aliased flags section)
+ NoUSBFlag = cli.BoolFlag{
+ Name: "nousb",
+ Usage: "Disables monitoring for and managing USB hardware wallets (deprecated)",
+ }
LegacyRPCEnabledFlag = cli.BoolFlag{
Name: "rpc",
Usage: "Enable the HTTP-RPC server (deprecated and will be removed June 2021, use --http)",
diff --git a/core/genesis.go b/core/genesis.go
index dc50ff475..c1f226c34 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -248,8 +248,6 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
return params.RinkebyChainConfig
case ghash == params.GoerliGenesisHash:
return params.GoerliChainConfig
- case ghash == params.CalaverasGenesisHash:
- return params.CalaverasChainConfig
default:
return params.AllEthashProtocolChanges
}
@@ -399,18 +397,6 @@ func DefaultGoerliGenesisBlock() *Genesis {
}
}
-func DefaultCalaverasGenesisBlock() *Genesis {
- // Full genesis: https://gist.github.com/holiman/c6ed9269dce28304ad176314caa75e97
- return &Genesis{
- Config: params.CalaverasChainConfig,
- Timestamp: 0x60b3877f,
- ExtraData: hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000000000005211cea3870c7ba7c6c44b185e62eecdb864cd8c560228ce57d31efbf64c200b2c200aacec78cf17a7148e784fe95a7a750335f8b9572ee28d72e7650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
- GasLimit: 0x47b760,
- Difficulty: big.NewInt(1),
- Alloc: decodePrealloc(calaverasAllocData),
- }
-}
-
// DeveloperGenesisBlock returns the 'geth --dev' genesis block.
func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
// Override the default period to the user requested one
diff --git a/core/genesis_test.go b/core/genesis_test.go
index 487c30ed6..52c4384ab 100644
--- a/core/genesis_test.go
+++ b/core/genesis_test.go
@@ -185,10 +185,6 @@ func TestGenesisHashes(t *testing.T) {
genesis: DefaultRinkebyGenesisBlock(),
hash: params.RinkebyGenesisHash,
},
- {
- genesis: DefaultCalaverasGenesisBlock(),
- hash: params.CalaverasGenesisHash,
- },
}
for i, c := range cases {
b := c.genesis.MustCommit(rawdb.NewMemoryDatabase())
diff --git a/core/rawdb/database.go b/core/rawdb/database.go
index c8bfdbace..90619169a 100644
--- a/core/rawdb/database.go
+++ b/core/rawdb/database.go
@@ -89,6 +89,11 @@ func (db *nofreezedb) Ancient(kind string, number uint64) ([]byte, error) {
return nil, errNotSupported
}
+// ReadAncients returns an error as we don't have a backing chain freezer.
+func (db *nofreezedb) ReadAncients(kind string, start, max, maxByteSize uint64) ([][]byte, error) {
+ return nil, errNotSupported
+}
+
// Ancients returns an error as we don't have a backing chain freezer.
func (db *nofreezedb) Ancients() (uint64, error) {
return 0, errNotSupported
diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go
index b1fc64b21..12130cf33 100644
--- a/core/rawdb/freezer.go
+++ b/core/rawdb/freezer.go
@@ -180,6 +180,18 @@ func (f *freezer) Ancient(kind string, number uint64) ([]byte, error) {
return nil, errUnknownTable
}
+// ReadAncients retrieves multiple items in sequence, starting from the index 'start'.
+// It will return
+// - at most 'max' items,
+// - at least 1 item (even if exceeding the maxByteSize), but will otherwise
+// return as many items as fit into maxByteSize.
+func (f *freezer) ReadAncients(kind string, start, count, maxBytes uint64) ([][]byte, error) {
+ if table := f.tables[kind]; table != nil {
+ return table.RetrieveItems(start, count, maxBytes)
+ }
+ return nil, errUnknownTable
+}
+
// Ancients returns the length of the frozen items.
func (f *freezer) Ancients() (uint64, error) {
return atomic.LoadUint64(&f.frozen), nil
@@ -403,7 +415,7 @@ func (f *freezer) freeze(db ethdb.KeyValueStore) {
}
batch.Reset()
- // Wipe out side chains also and track dangling side chians
+ // Wipe out side chains also and track dangling side chains
var dangling []common.Hash
for number := first; number < f.frozen; number++ {
// Always keep the genesis block in active database
diff --git a/core/rawdb/freezer_table.go b/core/rawdb/freezer_table.go
index d7bfe18e0..9d052f7cd 100644
--- a/core/rawdb/freezer_table.go
+++ b/core/rawdb/freezer_table.go
@@ -70,6 +70,19 @@ func (i *indexEntry) marshallBinary() []byte {
return b
}
+// bounds returns the start- and end- offsets, and the file number of where to
+// read there data item marked by the two index entries. The two entries are
+// assumed to be sequential.
+func (start *indexEntry) bounds(end *indexEntry) (startOffset, endOffset, fileId uint32) {
+ if start.filenum != end.filenum {
+ // If a piece of data 'crosses' a data-file,
+ // it's actually in one piece on the second data-file.
+ // We return a zero-indexEntry for the second file as start
+ return 0, end.offset, end.filenum
+ }
+ return start.offset, end.offset, end.filenum
+}
+
// freezerTable represents a single chained data table within the freezer (e.g. blocks).
// It consists of a data file (snappy encoded arbitrary data blobs) and an indexEntry
// file (uncompressed 64 bit indices into the data file).
@@ -546,84 +559,183 @@ func (t *freezerTable) append(item uint64, encodedBlob []byte, wlock bool) (bool
return false, nil
}
-// getBounds returns the indexes for the item
-// returns start, end, filenumber and error
-func (t *freezerTable) getBounds(item uint64) (uint32, uint32, uint32, error) {
- buffer := make([]byte, indexEntrySize)
- var startIdx, endIdx indexEntry
- // Read second index
- if _, err := t.index.ReadAt(buffer, int64((item+1)*indexEntrySize)); err != nil {
- return 0, 0, 0, err
+// getIndices returns the index entries for the given from-item, covering 'count' items.
+// N.B: The actual number of returned indices for N items will always be N+1 (unless an
+// error is returned).
+// OBS: This method assumes that the caller has already verified (and/or trimmed) the range
+// so that the items are within bounds. If this method is used to read out of bounds,
+// it will return error.
+func (t *freezerTable) getIndices(from, count uint64) ([]*indexEntry, error) {
+ // Apply the table-offset
+ from = from - uint64(t.itemOffset)
+ // For reading N items, we need N+1 indices.
+ buffer := make([]byte, (count+1)*indexEntrySize)
+ if _, err := t.index.ReadAt(buffer, int64(from*indexEntrySize)); err != nil {
+ return nil, err
}
- endIdx.unmarshalBinary(buffer)
- // Read first index (unless it's the very first item)
- if item != 0 {
- if _, err := t.index.ReadAt(buffer, int64(item*indexEntrySize)); err != nil {
- return 0, 0, 0, err
- }
- startIdx.unmarshalBinary(buffer)
- } else {
+ var (
+ indices []*indexEntry
+ offset int
+ )
+ for i := from; i <= from+count; i++ {
+ index := new(indexEntry)
+ index.unmarshalBinary(buffer[offset:])
+ offset += indexEntrySize
+ indices = append(indices, index)
+ }
+ if from == 0 {
// Special case if we're reading the first item in the freezer. We assume that
// the first item always start from zero(regarding the deletion, we
// only support deletion by files, so that the assumption is held).
// This means we can use the first item metadata to carry information about
// the 'global' offset, for the deletion-case
- return 0, endIdx.offset, endIdx.filenum, nil
+ indices[0].offset = 0
+ indices[0].filenum = indices[1].filenum
}
- if startIdx.filenum != endIdx.filenum {
- // If a piece of data 'crosses' a data-file,
- // it's actually in one piece on the second data-file.
- // We return a zero-indexEntry for the second file as start
- return 0, endIdx.offset, endIdx.filenum, nil
- }
- return startIdx.offset, endIdx.offset, endIdx.filenum, nil
+ return indices, nil
}
// Retrieve looks up the data offset of an item with the given number and retrieves
// the raw binary blob from the data file.
func (t *freezerTable) Retrieve(item uint64) ([]byte, error) {
- blob, err := t.retrieve(item)
+ items, err := t.RetrieveItems(item, 1, 0)
if err != nil {
return nil, err
}
- if t.noCompression {
- return blob, nil
- }
- return snappy.Decode(nil, blob)
+ return items[0], nil
}
-// retrieve looks up the data offset of an item with the given number and retrieves
-// the raw binary blob from the data file. OBS! This method does not decode
-// compressed data.
-func (t *freezerTable) retrieve(item uint64) ([]byte, error) {
+// RetrieveItems returns multiple items in sequence, starting from the index 'start'.
+// It will return at most 'max' items, but will abort earlier to respect the
+// 'maxBytes' argument. However, if the 'maxBytes' is smaller than the size of one
+// item, it _will_ return one element and possibly overflow the maxBytes.
+func (t *freezerTable) RetrieveItems(start, count, maxBytes uint64) ([][]byte, error) {
+ // First we read the 'raw' data, which might be compressed.
+ diskData, sizes, err := t.retrieveItems(start, count, maxBytes)
+ if err != nil {
+ return nil, err
+ }
+ var (
+ output = make([][]byte, 0, count)
+ offset int // offset for reading
+ outputSize int // size of uncompressed data
+ )
+ // Now slice up the data and decompress.
+ for i, diskSize := range sizes {
+ item := diskData[offset : offset+diskSize]
+ offset += diskSize
+ decompressedSize := diskSize
+ if !t.noCompression {
+ decompressedSize, _ = snappy.DecodedLen(item)
+ }
+ if i > 0 && uint64(outputSize+decompressedSize) > maxBytes {
+ break
+ }
+ if !t.noCompression {
+ data, err := snappy.Decode(nil, item)
+ if err != nil {
+ return nil, err
+ }
+ output = append(output, data)
+ } else {
+ output = append(output, item)
+ }
+ outputSize += decompressedSize
+ }
+ return output, nil
+}
+
+// retrieveItems reads up to 'count' items from the table. It reads at least
+// one item, but otherwise avoids reading more than maxBytes bytes.
+// It returns the (potentially compressed) data, and the sizes.
+func (t *freezerTable) retrieveItems(start, count, maxBytes uint64) ([]byte, []int, error) {
t.lock.RLock()
defer t.lock.RUnlock()
// Ensure the table and the item is accessible
if t.index == nil || t.head == nil {
- return nil, errClosed
+ return nil, nil, errClosed
}
- if atomic.LoadUint64(&t.items) <= item {
- return nil, errOutOfBounds
+ itemCount := atomic.LoadUint64(&t.items) // max number
+ // Ensure the start is written, not deleted from the tail, and that the
+ // caller actually wants something
+ if itemCount <= start || uint64(t.itemOffset) > start || count == 0 {
+ return nil, nil, errOutOfBounds
}
- // Ensure the item was not deleted from the tail either
- if uint64(t.itemOffset) > item {
- return nil, errOutOfBounds
+ if start+count > itemCount {
+ count = itemCount - start
}
- startOffset, endOffset, filenum, err := t.getBounds(item - uint64(t.itemOffset))
+ var (
+ output = make([]byte, maxBytes) // Buffer to read data into
+ outputSize int // Used size of that buffer
+ )
+ // readData is a helper method to read a single data item from disk.
+ readData := func(fileId, start uint32, length int) error {
+ // In case a small limit is used, and the elements are large, may need to
+ // realloc the read-buffer when reading the first (and only) item.
+ if len(output) < length {
+ output = make([]byte, length)
+ }
+ dataFile, exist := t.files[fileId]
+ if !exist {
+ return fmt.Errorf("missing data file %d", fileId)
+ }
+ if _, err := dataFile.ReadAt(output[outputSize:outputSize+length], int64(start)); err != nil {
+ return err
+ }
+ outputSize += length
+ return nil
+ }
+ // Read all the indexes in one go
+ indices, err := t.getIndices(start, count)
if err != nil {
- return nil, err
+ return nil, nil, err
}
- dataFile, exist := t.files[filenum]
- if !exist {
- return nil, fmt.Errorf("missing data file %d", filenum)
+ var (
+ sizes []int // The sizes for each element
+ totalSize = 0 // The total size of all data read so far
+ readStart = indices[0].offset // Where, in the file, to start reading
+ unreadSize = 0 // The size of the as-yet-unread data
+ )
+
+ for i, firstIndex := range indices[:len(indices)-1] {
+ secondIndex := indices[i+1]
+ // Determine the size of the item.
+ offset1, offset2, _ := firstIndex.bounds(secondIndex)
+ size := int(offset2 - offset1)
+ // Crossing a file boundary?
+ if secondIndex.filenum != firstIndex.filenum {
+ // If we have unread data in the first file, we need to do that read now.
+ if unreadSize > 0 {
+ if err := readData(firstIndex.filenum, readStart, unreadSize); err != nil {
+ return nil, nil, err
+ }
+ unreadSize = 0
+ }
+ readStart = 0
+ }
+ if i > 0 && uint64(totalSize+size) > maxBytes {
+ // About to break out due to byte limit being exceeded. We don't
+ // read this last item, but we need to do the deferred reads now.
+ if unreadSize > 0 {
+ if err := readData(secondIndex.filenum, readStart, unreadSize); err != nil {
+ return nil, nil, err
+ }
+ }
+ break
+ }
+ // Defer the read for later
+ unreadSize += size
+ totalSize += size
+ sizes = append(sizes, size)
+ if i == len(indices)-2 || uint64(totalSize) > maxBytes {
+ // Last item, need to do the read now
+ if err := readData(secondIndex.filenum, readStart, unreadSize); err != nil {
+ return nil, nil, err
+ }
+ break
+ }
}
- // Retrieve the data itself, decompress and return
- blob := make([]byte, endOffset-startOffset)
- if _, err := dataFile.ReadAt(blob, int64(startOffset)); err != nil {
- return nil, err
- }
- t.readMeter.Mark(int64(len(blob) + 2*indexEntrySize))
- return blob, nil
+ return output[:outputSize], sizes, nil
}
// has returns an indicator whether the specified number data
diff --git a/core/rawdb/freezer_table_test.go b/core/rawdb/freezer_table_test.go
index 0df28f236..e8a8b5c46 100644
--- a/core/rawdb/freezer_table_test.go
+++ b/core/rawdb/freezer_table_test.go
@@ -74,7 +74,7 @@ func TestFreezerBasics(t *testing.T) {
exp := getChunk(15, y)
got, err := f.Retrieve(uint64(y))
if err != nil {
- t.Fatal(err)
+ t.Fatalf("reading item %d: %v", y, err)
}
if !bytes.Equal(got, exp) {
t.Fatalf("test %d, got \n%x != \n%x", y, got, exp)
@@ -692,3 +692,118 @@ func TestAppendTruncateParallel(t *testing.T) {
}
}
}
+
+// TestSequentialRead does some basic tests on the RetrieveItems.
+func TestSequentialRead(t *testing.T) {
+ rm, wm, sg := metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge()
+ fname := fmt.Sprintf("batchread-%d", rand.Uint64())
+ { // Fill table
+ f, err := newCustomTable(os.TempDir(), fname, rm, wm, sg, 50, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+ // Write 15 bytes 30 times
+ for x := 0; x < 30; x++ {
+ data := getChunk(15, x)
+ f.Append(uint64(x), data)
+ }
+ f.DumpIndex(0, 30)
+ f.Close()
+ }
+ { // Open it, iterate, verify iteration
+ f, err := newCustomTable(os.TempDir(), fname, rm, wm, sg, 50, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+ items, err := f.RetrieveItems(0, 10000, 100000)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if have, want := len(items), 30; have != want {
+ t.Fatalf("want %d items, have %d ", want, have)
+ }
+ for i, have := range items {
+ want := getChunk(15, i)
+ if !bytes.Equal(want, have) {
+ t.Fatalf("data corruption: have\n%x\n, want \n%x\n", have, want)
+ }
+ }
+ f.Close()
+ }
+ { // Open it, iterate, verify byte limit. The byte limit is less than item
+ // size, so each lookup should only return one item
+ f, err := newCustomTable(os.TempDir(), fname, rm, wm, sg, 40, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+ items, err := f.RetrieveItems(0, 10000, 10)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if have, want := len(items), 1; have != want {
+ t.Fatalf("want %d items, have %d ", want, have)
+ }
+ for i, have := range items {
+ want := getChunk(15, i)
+ if !bytes.Equal(want, have) {
+ t.Fatalf("data corruption: have\n%x\n, want \n%x\n", have, want)
+ }
+ }
+ f.Close()
+ }
+}
+
+// TestSequentialReadByteLimit does some more advanced tests on batch reads.
+// These tests check that when the byte limit hits, we correctly abort in time,
+// but also properly do all the deferred reads for the previous data, regardless
+// of whether the data crosses a file boundary or not.
+func TestSequentialReadByteLimit(t *testing.T) {
+ rm, wm, sg := metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge()
+ fname := fmt.Sprintf("batchread-2-%d", rand.Uint64())
+ { // Fill table
+ f, err := newCustomTable(os.TempDir(), fname, rm, wm, sg, 100, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+ // Write 10 bytes 30 times,
+ // Splitting it at every 100 bytes (10 items)
+ for x := 0; x < 30; x++ {
+ data := getChunk(10, x)
+ f.Append(uint64(x), data)
+ }
+ f.Close()
+ }
+ for i, tc := range []struct {
+ items uint64
+ limit uint64
+ want int
+ }{
+ {9, 89, 8},
+ {10, 99, 9},
+ {11, 109, 10},
+ {100, 89, 8},
+ {100, 99, 9},
+ {100, 109, 10},
+ } {
+ {
+ f, err := newCustomTable(os.TempDir(), fname, rm, wm, sg, 100, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+ items, err := f.RetrieveItems(0, tc.items, tc.limit)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if have, want := len(items), tc.want; have != want {
+ t.Fatalf("test %d: want %d items, have %d ", i, want, have)
+ }
+ for ii, have := range items {
+ want := getChunk(10, ii)
+ if !bytes.Equal(want, have) {
+ t.Fatalf("test %d: data corruption item %d: have\n%x\n, want \n%x\n", i, ii, have, want)
+ }
+ }
+ f.Close()
+ }
+ }
+}
diff --git a/core/rawdb/table.go b/core/rawdb/table.go
index d5ef60ae5..586451c06 100644
--- a/core/rawdb/table.go
+++ b/core/rawdb/table.go
@@ -62,6 +62,12 @@ func (t *table) Ancient(kind string, number uint64) ([]byte, error) {
return t.db.Ancient(kind, number)
}
+// ReadAncients is a noop passthrough that just forwards the request to the underlying
+// database.
+func (t *table) ReadAncients(kind string, start, count, maxBytes uint64) ([][]byte, error) {
+ return t.db.ReadAncients(kind, start, count, maxBytes)
+}
+
// Ancients is a noop passthrough that just forwards the request to the underlying
// database.
func (t *table) Ancients() (uint64, error) {
diff --git a/core/state_transition.go b/core/state_transition.go
index 4c4187df1..6a09f6adc 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -74,7 +74,7 @@ type Message interface {
Value() *big.Int
Nonce() uint64
- CheckNonce() bool
+ IsFake() bool
Data() []byte
AccessList() types.AccessList
}
@@ -212,8 +212,9 @@ func (st *StateTransition) buyGas() error {
}
func (st *StateTransition) preCheck() error {
- // Make sure this transaction's nonce is correct.
- if st.msg.CheckNonce() {
+ // Only check transactions that are not fake
+ if !st.msg.IsFake() {
+ // Make sure this transaction's nonce is correct.
stNonce := st.state.GetNonce(st.msg.From())
if msgNonce := st.msg.Nonce(); stNonce < msgNonce {
return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooHigh,
@@ -222,11 +223,11 @@ func (st *StateTransition) preCheck() error {
return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooLow,
st.msg.From().Hex(), msgNonce, stNonce)
}
- }
- // Make sure the sender is an EOA
- if codeHash := st.state.GetCodeHash(st.msg.From()); codeHash != emptyCodeHash && codeHash != (common.Hash{}) {
- return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA,
- st.msg.From().Hex(), codeHash)
+ // Make sure the sender is an EOA
+ if codeHash := st.state.GetCodeHash(st.msg.From()); codeHash != emptyCodeHash && codeHash != (common.Hash{}) {
+ return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA,
+ st.msg.From().Hex(), codeHash)
+ }
}
// Make sure that transaction gasFeeCap is greater than the baseFee (post london)
if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
diff --git a/core/types/transaction.go b/core/types/transaction.go
index a556f4b57..e21cf2bda 100644
--- a/core/types/transaction.go
+++ b/core/types/transaction.go
@@ -579,10 +579,10 @@ type Message struct {
gasTipCap *big.Int
data []byte
accessList AccessList
- checkNonce bool
+ isFake bool
}
-func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, data []byte, accessList AccessList, checkNonce bool) Message {
+func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, data []byte, accessList AccessList, isFake bool) Message {
return Message{
from: from,
to: to,
@@ -594,7 +594,7 @@ func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *b
gasTipCap: gasTipCap,
data: data,
accessList: accessList,
- checkNonce: checkNonce,
+ isFake: isFake,
}
}
@@ -610,7 +610,7 @@ func (tx *Transaction) AsMessage(s Signer, baseFee *big.Int) (Message, error) {
amount: tx.Value(),
data: tx.Data(),
accessList: tx.AccessList(),
- checkNonce: true,
+ isFake: false,
}
// If baseFee provided, set gasPrice to effectiveGasPrice.
if baseFee != nil {
@@ -631,4 +631,4 @@ func (m Message) Gas() uint64 { return m.gasLimit }
func (m Message) Nonce() uint64 { return m.nonce }
func (m Message) Data() []byte { return m.data }
func (m Message) AccessList() AccessList { return m.accessList }
-func (m Message) CheckNonce() bool { return m.checkNonce }
+func (m Message) IsFake() bool { return m.isFake }
diff --git a/core/vm/analysis.go b/core/vm/analysis.go
index 0ccf47b97..449cded2a 100644
--- a/core/vm/analysis.go
+++ b/core/vm/analysis.go
@@ -16,17 +16,49 @@
package vm
+const (
+ set2BitsMask = uint16(0b1100_0000_0000_0000)
+ set3BitsMask = uint16(0b1110_0000_0000_0000)
+ set4BitsMask = uint16(0b1111_0000_0000_0000)
+ set5BitsMask = uint16(0b1111_1000_0000_0000)
+ set6BitsMask = uint16(0b1111_1100_0000_0000)
+ set7BitsMask = uint16(0b1111_1110_0000_0000)
+)
+
// bitvec is a bit vector which maps bytes in a program.
// An unset bit means the byte is an opcode, a set bit means
// it's data (i.e. argument of PUSHxx).
type bitvec []byte
-func (bits *bitvec) set(pos uint64) {
- (*bits)[pos/8] |= 0x80 >> (pos % 8)
+var lookup = [8]byte{
+ 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1,
}
-func (bits *bitvec) set8(pos uint64) {
- (*bits)[pos/8] |= 0xFF >> (pos % 8)
- (*bits)[pos/8+1] |= ^(0xFF >> (pos % 8))
+
+func (bits bitvec) set1(pos uint64) {
+ bits[pos/8] |= lookup[pos%8]
+}
+
+func (bits bitvec) setN(flag uint16, pos uint64) {
+ a := flag >> (pos % 8)
+ bits[pos/8] |= byte(a >> 8)
+ if b := byte(a); b != 0 {
+ // If the bit-setting affects the neighbouring byte, we can assign - no need to OR it,
+ // since it's the first write to that byte
+ bits[pos/8+1] = b
+ }
+}
+
+func (bits bitvec) set8(pos uint64) {
+ a := byte(0xFF >> (pos % 8))
+ bits[pos/8] |= a
+ bits[pos/8+1] = ^a
+}
+
+func (bits bitvec) set16(pos uint64) {
+ a := byte(0xFF >> (pos % 8))
+ bits[pos/8] |= a
+ bits[pos/8+1] = 0xFF
+ bits[pos/8+2] = ^a
}
// codeSegment checks if the position is in a code segment.
@@ -40,22 +72,52 @@ func codeBitmap(code []byte) bitvec {
// ends with a PUSH32, the algorithm will push zeroes onto the
// bitvector outside the bounds of the actual code.
bits := make(bitvec, len(code)/8+1+4)
+ return codeBitmapInternal(code, bits)
+}
+
+// codeBitmapInternal is the internal implementation of codeBitmap.
+// It exists for the purpose of being able to run benchmark tests
+// without dynamic allocations affecting the results.
+func codeBitmapInternal(code, bits bitvec) bitvec {
for pc := uint64(0); pc < uint64(len(code)); {
op := OpCode(code[pc])
-
- if op >= PUSH1 && op <= PUSH32 {
- numbits := op - PUSH1 + 1
- pc++
+ pc++
+ if op < PUSH1 || op > PUSH32 {
+ continue
+ }
+ numbits := op - PUSH1 + 1
+ if numbits >= 8 {
+ for ; numbits >= 16; numbits -= 16 {
+ bits.set16(pc)
+ pc += 16
+ }
for ; numbits >= 8; numbits -= 8 {
- bits.set8(pc) // 8
+ bits.set8(pc)
pc += 8
}
- for ; numbits > 0; numbits-- {
- bits.set(pc)
- pc++
- }
- } else {
- pc++
+ }
+ switch numbits {
+ case 1:
+ bits.set1(pc)
+ pc += 1
+ case 2:
+ bits.setN(set2BitsMask, pc)
+ pc += 2
+ case 3:
+ bits.setN(set3BitsMask, pc)
+ pc += 3
+ case 4:
+ bits.setN(set4BitsMask, pc)
+ pc += 4
+ case 5:
+ bits.setN(set5BitsMask, pc)
+ pc += 5
+ case 6:
+ bits.setN(set6BitsMask, pc)
+ pc += 6
+ case 7:
+ bits.setN(set7BitsMask, pc)
+ pc += 7
}
}
return bits
diff --git a/core/vm/analysis_test.go b/core/vm/analysis_test.go
index fd2d744d8..585bb3097 100644
--- a/core/vm/analysis_test.go
+++ b/core/vm/analysis_test.go
@@ -47,10 +47,10 @@ func TestJumpDestAnalysis(t *testing.T) {
{[]byte{byte(PUSH32)}, 0xFF, 1},
{[]byte{byte(PUSH32)}, 0xFF, 2},
}
- for _, test := range tests {
+ for i, test := range tests {
ret := codeBitmap(test.code)
if ret[test.which] != test.exp {
- t.Fatalf("expected %x, got %02x", test.exp, ret[test.which])
+ t.Fatalf("test %d: expected %x, got %02x", i, test.exp, ret[test.which])
}
}
}
@@ -73,3 +73,23 @@ func BenchmarkJumpdestHashing_1200k(bench *testing.B) {
}
bench.StopTimer()
}
+
+func BenchmarkJumpdestOpAnalysis(bench *testing.B) {
+ var op OpCode
+ bencher := func(b *testing.B) {
+ code := make([]byte, 32*b.N)
+ for i := range code {
+ code[i] = byte(op)
+ }
+ bits := make(bitvec, len(code)/8+1+4)
+ b.ResetTimer()
+ codeBitmapInternal(code, bits)
+ }
+ for op = PUSH1; op <= PUSH32; op++ {
+ bench.Run(op.String(), bencher)
+ }
+ op = JUMPDEST
+ bench.Run(op.String(), bencher)
+ op = STOP
+ bench.Run(op.String(), bencher)
+}
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index f7ef2f900..6c8c6e6e6 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -669,6 +669,7 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt
}
stack.push(&temp)
if err == nil || err == ErrExecutionReverted {
+ ret = common.CopyBytes(ret)
scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
}
scope.Contract.Gas += returnGas
@@ -703,6 +704,7 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
}
stack.push(&temp)
if err == nil || err == ErrExecutionReverted {
+ ret = common.CopyBytes(ret)
scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
}
scope.Contract.Gas += returnGas
@@ -730,6 +732,7 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext
}
stack.push(&temp)
if err == nil || err == ErrExecutionReverted {
+ ret = common.CopyBytes(ret)
scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
}
scope.Contract.Gas += returnGas
@@ -757,6 +760,7 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
}
stack.push(&temp)
if err == nil || err == ErrExecutionReverted {
+ ret = common.CopyBytes(ret)
scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
}
scope.Contract.Gas += returnGas
diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go
index 9cf0c4e2c..9fb83799c 100644
--- a/core/vm/interpreter.go
+++ b/core/vm/interpreter.go
@@ -262,7 +262,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
// if the operation clears the return data (e.g. it has returning data)
// set the last return to the result of the operation.
if operation.returns {
- in.returnData = common.CopyBytes(res)
+ in.returnData = res
}
switch {
diff --git a/eth/api.go b/eth/api.go
index 8b96d1f31..0f57128d7 100644
--- a/eth/api.go
+++ b/eth/api.go
@@ -342,7 +342,7 @@ func (api *PrivateDebugAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs,
} else {
blockRlp = fmt.Sprintf("0x%x", rlpBytes)
}
- if blockJSON, err = ethapi.RPCMarshalBlock(block, true, true); err != nil {
+ if blockJSON, err = ethapi.RPCMarshalBlock(block, true, true, api.eth.engine); err != nil {
blockJSON = map[string]interface{}{"error": err.Error()}
}
results = append(results, &BadBlockArgs{
diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go
index e8a4a76ca..1767506a3 100644
--- a/eth/downloader/downloader.go
+++ b/eth/downloader/downloader.go
@@ -465,7 +465,7 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.I
}
if mode == FastSync && pivot == nil {
// If no pivot block was returned, the head is below the min full block
- // threshold (i.e. new chian). In that case we won't really fast sync
+ // threshold (i.e. new chain). In that case we won't really fast sync
// anyway, but still need a valid pivot block to avoid some code hitting
// nil panics on an access.
pivot = d.blockchain.CurrentBlock().Header()
@@ -681,7 +681,7 @@ func (d *Downloader) fetchHead(p *peerConnection) (head *types.Header, pivot *ty
return head, nil, nil
}
// At this point we have 2 headers in total and the first is the
- // validated head of the chian. Check the pivot number and return,
+ // validated head of the chain. Check the pivot number and return,
pivot := headers[1]
if pivot.Number.Uint64() != head.Number.Uint64()-uint64(fsMinFullBlocks) {
return nil, nil, fmt.Errorf("%w: remote pivot %d != requested %d", errInvalidChain, pivot.Number, head.Number.Uint64()-uint64(fsMinFullBlocks))
diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go
index 23ccf2484..89cdb7559 100644
--- a/eth/ethconfig/config.go
+++ b/eth/ethconfig/config.go
@@ -43,8 +43,8 @@ import (
var FullNodeGPO = gasprice.Config{
Blocks: 20,
Percentile: 60,
- MaxHeaderHistory: 0,
- MaxBlockHistory: 0,
+ MaxHeaderHistory: 1024,
+ MaxBlockHistory: 1024,
MaxPrice: gasprice.DefaultMaxPrice,
IgnorePrice: gasprice.DefaultIgnorePrice,
}
diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go
index 2c4486c6f..970dfd446 100644
--- a/eth/gasprice/feehistory.go
+++ b/eth/gasprice/feehistory.go
@@ -18,8 +18,10 @@ package gasprice
import (
"context"
+ "encoding/binary"
"errors"
"fmt"
+ "math"
"math/big"
"sort"
"sync/atomic"
@@ -37,10 +39,6 @@ var (
)
const (
- // maxFeeHistory is the maximum number of blocks that can be retrieved for a
- // fee history request.
- maxFeeHistory = 1024
-
// maxBlockFetchers is the max number of goroutines to spin up to pull blocks
// for the fee history calculation (mostly relevant for LES).
maxBlockFetchers = 4
@@ -54,10 +52,15 @@ type blockFees struct {
block *types.Block // only set if reward percentiles are requested
receipts types.Receipts
// filled by processBlock
+ results processedFees
+ err error
+}
+
+// processedFees contains the results of a processed block and is also used for caching
+type processedFees struct {
reward []*big.Int
baseFee, nextBaseFee *big.Int
gasUsedRatio float64
- err error
}
// txGasAndReward is sorted in ascending order based on reward
@@ -82,15 +85,15 @@ func (s sortGasAndReward) Less(i, j int) bool {
// fills in the rest of the fields.
func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
chainconfig := oracle.backend.ChainConfig()
- if bf.baseFee = bf.header.BaseFee; bf.baseFee == nil {
- bf.baseFee = new(big.Int)
+ if bf.results.baseFee = bf.header.BaseFee; bf.results.baseFee == nil {
+ bf.results.baseFee = new(big.Int)
}
if chainconfig.IsLondon(big.NewInt(int64(bf.blockNumber + 1))) {
- bf.nextBaseFee = misc.CalcBaseFee(chainconfig, bf.header)
+ bf.results.nextBaseFee = misc.CalcBaseFee(chainconfig, bf.header)
} else {
- bf.nextBaseFee = new(big.Int)
+ bf.results.nextBaseFee = new(big.Int)
}
- bf.gasUsedRatio = float64(bf.header.GasUsed) / float64(bf.header.GasLimit)
+ bf.results.gasUsedRatio = float64(bf.header.GasUsed) / float64(bf.header.GasLimit)
if len(percentiles) == 0 {
// rewards were not requested, return null
return
@@ -100,11 +103,11 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
return
}
- bf.reward = make([]*big.Int, len(percentiles))
+ bf.results.reward = make([]*big.Int, len(percentiles))
if len(bf.block.Transactions()) == 0 {
// return an all zero row if there are no transactions to gather data from
- for i := range bf.reward {
- bf.reward[i] = new(big.Int)
+ for i := range bf.results.reward {
+ bf.results.reward[i] = new(big.Int)
}
return
}
@@ -125,7 +128,7 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
txIndex++
sumGasUsed += sorter[txIndex].gasUsed
}
- bf.reward[i] = sorter[txIndex].reward
+ bf.results.reward[i] = sorter[txIndex].reward
}
}
@@ -134,7 +137,7 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
// also returned if requested and available.
// Note: an error is only returned if retrieving the head header has failed. If there are no
// retrievable blocks in the specified range then zero block count is returned with no error.
-func (oracle *Oracle) resolveBlockRange(ctx context.Context, lastBlock rpc.BlockNumber, blocks, maxHistory int) (*types.Block, []*types.Receipt, uint64, int, error) {
+func (oracle *Oracle) resolveBlockRange(ctx context.Context, lastBlock rpc.BlockNumber, blocks int) (*types.Block, []*types.Receipt, uint64, int, error) {
var (
headBlock rpc.BlockNumber
pendingBlock *types.Block
@@ -167,17 +170,6 @@ func (oracle *Oracle) resolveBlockRange(ctx context.Context, lastBlock rpc.Block
} else if pendingBlock == nil && lastBlock > headBlock {
return nil, nil, 0, 0, fmt.Errorf("%w: requested %d, head %d", errRequestBeyondHead, lastBlock, headBlock)
}
- if maxHistory != 0 {
- // limit retrieval to the given number of latest blocks
- if tooOldCount := int64(headBlock) - int64(maxHistory) - int64(lastBlock) + int64(blocks); tooOldCount > 0 {
- // tooOldCount is the number of requested blocks that are too old to be served
- if int64(blocks) > tooOldCount {
- blocks -= int(tooOldCount)
- } else {
- return nil, nil, 0, 0, nil
- }
- }
- }
// ensure not trying to retrieve before genesis
if rpc.BlockNumber(blocks) > lastBlock+1 {
blocks = int(lastBlock + 1)
@@ -202,6 +194,10 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks int, unresolvedLast
if blocks < 1 {
return common.Big0, nil, nil, nil, nil // returning with no data and no error means there are no retrievable blocks
}
+ maxFeeHistory := oracle.maxHeaderHistory
+ if len(rewardPercentiles) != 0 {
+ maxFeeHistory = oracle.maxBlockHistory
+ }
if blocks > maxFeeHistory {
log.Warn("Sanitizing fee history length", "requested", blocks, "truncated", maxFeeHistory)
blocks = maxFeeHistory
@@ -214,17 +210,12 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks int, unresolvedLast
return common.Big0, nil, nil, nil, fmt.Errorf("%w: #%d:%f > #%d:%f", errInvalidPercentile, i-1, rewardPercentiles[i-1], i, p)
}
}
- // Only process blocks if reward percentiles were requested
- maxHistory := oracle.maxHeaderHistory
- if len(rewardPercentiles) != 0 {
- maxHistory = oracle.maxBlockHistory
- }
var (
pendingBlock *types.Block
pendingReceipts []*types.Receipt
err error
)
- pendingBlock, pendingReceipts, lastBlock, blocks, err := oracle.resolveBlockRange(ctx, unresolvedLastBlock, blocks, maxHistory)
+ pendingBlock, pendingReceipts, lastBlock, blocks, err := oracle.resolveBlockRange(ctx, unresolvedLastBlock, blocks)
if err != nil || blocks == 0 {
return common.Big0, nil, nil, nil, err
}
@@ -234,6 +225,10 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks int, unresolvedLast
next = oldestBlock
results = make(chan *blockFees, blocks)
)
+ percentileKey := make([]byte, 8*len(rewardPercentiles))
+ for i, p := range rewardPercentiles {
+ binary.LittleEndian.PutUint64(percentileKey[i*8:(i+1)*8], math.Float64bits(p))
+ }
for i := 0; i < maxBlockFetchers && i < blocks; i++ {
go func() {
for {
@@ -246,24 +241,38 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks int, unresolvedLast
fees := &blockFees{blockNumber: blockNumber}
if pendingBlock != nil && blockNumber >= pendingBlock.NumberU64() {
fees.block, fees.receipts = pendingBlock, pendingReceipts
+ fees.header = fees.block.Header()
+ oracle.processBlock(fees, rewardPercentiles)
+ results <- fees
} else {
- if len(rewardPercentiles) != 0 {
- fees.block, fees.err = oracle.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNumber))
- if fees.block != nil && fees.err == nil {
- fees.receipts, fees.err = oracle.backend.GetReceipts(ctx, fees.block.Hash())
- }
+ cacheKey := struct {
+ number uint64
+ percentiles string
+ }{blockNumber, string(percentileKey)}
+
+ if p, ok := oracle.historyCache.Get(cacheKey); ok {
+ fees.results = p.(processedFees)
+ results <- fees
} else {
- fees.header, fees.err = oracle.backend.HeaderByNumber(ctx, rpc.BlockNumber(blockNumber))
+ if len(rewardPercentiles) != 0 {
+ fees.block, fees.err = oracle.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNumber))
+ if fees.block != nil && fees.err == nil {
+ fees.receipts, fees.err = oracle.backend.GetReceipts(ctx, fees.block.Hash())
+ fees.header = fees.block.Header()
+ }
+ } else {
+ fees.header, fees.err = oracle.backend.HeaderByNumber(ctx, rpc.BlockNumber(blockNumber))
+ }
+ if fees.header != nil && fees.err == nil {
+ oracle.processBlock(fees, rewardPercentiles)
+ if fees.err == nil {
+ oracle.historyCache.Add(cacheKey, fees.results)
+ }
+ }
+ // send to results even if empty to guarantee that blocks items are sent in total
+ results <- fees
}
}
- if fees.block != nil {
- fees.header = fees.block.Header()
- }
- if fees.header != nil {
- oracle.processBlock(fees, rewardPercentiles)
- }
- // send to results even if empty to guarantee that blocks items are sent in total
- results <- fees
}
}()
}
@@ -279,8 +288,8 @@ func (oracle *Oracle) FeeHistory(ctx context.Context, blocks int, unresolvedLast
return common.Big0, nil, nil, nil, fees.err
}
i := int(fees.blockNumber - oldestBlock)
- if fees.header != nil {
- reward[i], baseFee[i], baseFee[i+1], gasUsedRatio[i] = fees.reward, fees.baseFee, fees.nextBaseFee, fees.gasUsedRatio
+ if fees.results.baseFee != nil {
+ reward[i], baseFee[i], baseFee[i+1], gasUsedRatio[i] = fees.results.reward, fees.results.baseFee, fees.results.nextBaseFee, fees.results.gasUsedRatio
} else {
// getting no block and no error means we are requesting into the future (might happen because of a reorg)
if i < firstMissing {
diff --git a/eth/gasprice/feehistory_test.go b/eth/gasprice/feehistory_test.go
index 16c74b7db..c259eb0ac 100644
--- a/eth/gasprice/feehistory_test.go
+++ b/eth/gasprice/feehistory_test.go
@@ -36,20 +36,20 @@ func TestFeeHistory(t *testing.T) {
expCount int
expErr error
}{
- {false, 0, 0, 10, 30, nil, 21, 10, nil},
- {false, 0, 0, 10, 30, []float64{0, 10}, 21, 10, nil},
- {false, 0, 0, 10, 30, []float64{20, 10}, 0, 0, errInvalidPercentile},
- {false, 0, 0, 1000000000, 30, nil, 0, 31, nil},
- {false, 0, 0, 1000000000, rpc.LatestBlockNumber, nil, 0, 33, nil},
- {false, 0, 0, 10, 40, nil, 0, 0, errRequestBeyondHead},
- {true, 0, 0, 10, 40, nil, 0, 0, errRequestBeyondHead},
+ {false, 1000, 1000, 10, 30, nil, 21, 10, nil},
+ {false, 1000, 1000, 10, 30, []float64{0, 10}, 21, 10, nil},
+ {false, 1000, 1000, 10, 30, []float64{20, 10}, 0, 0, errInvalidPercentile},
+ {false, 1000, 1000, 1000000000, 30, nil, 0, 31, nil},
+ {false, 1000, 1000, 1000000000, rpc.LatestBlockNumber, nil, 0, 33, nil},
+ {false, 1000, 1000, 10, 40, nil, 0, 0, errRequestBeyondHead},
+ {true, 1000, 1000, 10, 40, nil, 0, 0, errRequestBeyondHead},
{false, 20, 2, 100, rpc.LatestBlockNumber, nil, 13, 20, nil},
{false, 20, 2, 100, rpc.LatestBlockNumber, []float64{0, 10}, 31, 2, nil},
{false, 20, 2, 100, 32, []float64{0, 10}, 31, 2, nil},
- {false, 0, 0, 1, rpc.PendingBlockNumber, nil, 0, 0, nil},
- {false, 0, 0, 2, rpc.PendingBlockNumber, nil, 32, 1, nil},
- {true, 0, 0, 2, rpc.PendingBlockNumber, nil, 32, 2, nil},
- {true, 0, 0, 2, rpc.PendingBlockNumber, []float64{0, 10}, 32, 2, nil},
+ {false, 1000, 1000, 1, rpc.PendingBlockNumber, nil, 0, 0, nil},
+ {false, 1000, 1000, 2, rpc.PendingBlockNumber, nil, 32, 1, nil},
+ {true, 1000, 1000, 2, rpc.PendingBlockNumber, nil, 32, 2, nil},
+ {true, 1000, 1000, 2, rpc.PendingBlockNumber, []float64{0, 10}, 32, 2, nil},
}
for i, c := range cases {
config := Config{
diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go
index 407eeaa28..8feb5ef24 100644
--- a/eth/gasprice/gasprice.go
+++ b/eth/gasprice/gasprice.go
@@ -23,10 +23,13 @@ import (
"sync"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
+ lru "github.com/hashicorp/golang-lru"
)
const sampleNumber = 3 // Number of transactions sampled in a block
@@ -53,6 +56,7 @@ type OracleBackend interface {
GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
PendingBlockAndReceipts() (*types.Block, types.Receipts)
ChainConfig() *params.ChainConfig
+ SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
}
// Oracle recommends gas prices based on the content of recent
@@ -68,6 +72,7 @@ type Oracle struct {
checkBlocks, percentile int
maxHeaderHistory, maxBlockHistory int
+ historyCache *lru.Cache
}
// NewOracle returns a new gasprice oracle which can recommend suitable
@@ -99,6 +104,20 @@ func NewOracle(backend OracleBackend, params Config) *Oracle {
} else if ignorePrice.Int64() > 0 {
log.Info("Gasprice oracle is ignoring threshold set", "threshold", ignorePrice)
}
+
+ cache, _ := lru.New(2048)
+ headEvent := make(chan core.ChainHeadEvent, 1)
+ backend.SubscribeChainHeadEvent(headEvent)
+ go func() {
+ var lastHead common.Hash
+ for ev := range headEvent {
+ if ev.Block.ParentHash() != lastHead {
+ cache.Purge()
+ }
+ lastHead = ev.Block.Hash()
+ }
+ }()
+
return &Oracle{
backend: backend,
lastPrice: params.Default,
@@ -108,6 +127,7 @@ func NewOracle(backend OracleBackend, params Config) *Oracle {
percentile: percent,
maxHeaderHistory: params.MaxHeaderHistory,
maxBlockHistory: params.MaxBlockHistory,
+ historyCache: cache,
}
}
diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go
index dea8fea95..feecfddec 100644
--- a/eth/gasprice/gasprice_test.go
+++ b/eth/gasprice/gasprice_test.go
@@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
)
@@ -90,6 +91,10 @@ func (b *testBackend) ChainConfig() *params.ChainConfig {
return b.chain.Config()
}
+func (b *testBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription {
+ return nil
+}
+
func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBackend {
var (
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
diff --git a/ethdb/database.go b/ethdb/database.go
index 0dc14624b..bdc09d5e9 100644
--- a/ethdb/database.go
+++ b/ethdb/database.go
@@ -76,6 +76,13 @@ type AncientReader interface {
// Ancient retrieves an ancient binary blob from the append-only immutable files.
Ancient(kind string, number uint64) ([]byte, error)
+ // ReadAncients retrieves multiple items in sequence, starting from the index 'start'.
+ // It will return
+ // - at most 'count' items,
+ // - at least 1 item (even if exceeding the maxBytes), but will otherwise
+ // return as many items as fit into maxBytes.
+ ReadAncients(kind string, start, count, maxBytes uint64) ([][]byte, error)
+
// Ancients returns the ancient item numbers in the ancient store.
Ancients() (uint64, error)
diff --git a/go.mod b/go.mod
index e59dfd580..bab3b302d 100644
--- a/go.mod
+++ b/go.mod
@@ -8,6 +8,7 @@ require (
github.com/Azure/go-autorest/autorest/adal v0.8.0 // indirect
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
github.com/VictoriaMetrics/fastcache v1.6.0
+ github.com/aws/aws-sdk-go v1.41.4
github.com/aws/aws-sdk-go-v2 v1.2.0
github.com/aws/aws-sdk-go-v2/config v1.1.1
github.com/aws/aws-sdk-go-v2/credentials v1.1.1
@@ -18,6 +19,7 @@ require (
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f
github.com/davecgh/go-spew v1.1.1
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea
+ github.com/deepmap/oapi-codegen v1.8.2 // indirect
github.com/dlclark/regexp2 v1.2.0 // indirect
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf
github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498
@@ -39,13 +41,15 @@ require (
github.com/holiman/uint256 v1.2.0
github.com/huin/goupnp v1.0.2
github.com/influxdata/influxdb v1.8.3
+ github.com/influxdata/influxdb-client-go/v2 v2.4.0
+ github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458
github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e
github.com/julienschmidt/httprouter v1.2.0
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356
github.com/kylelemons/godebug v1.1.0 // indirect
- github.com/mattn/go-colorable v0.1.0
- github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035
+ github.com/mattn/go-colorable v0.1.8
+ github.com/mattn/go-isatty v0.0.12
github.com/naoina/go-stringutil v0.1.0 // indirect
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416
github.com/olekukonko/tablewriter v0.0.5
@@ -53,6 +57,7 @@ require (
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7
github.com/prometheus/tsdb v0.7.1
github.com/rjeczalik/notify v0.9.1
+ github.com/robertkrimen/otto v0.0.0-20211008084715-4eacda02dd21
github.com/rs/cors v1.7.0
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4
@@ -61,13 +66,14 @@ require (
github.com/tklauser/go-sysconf v0.3.5 // indirect
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
- golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect
+ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
- golang.org/x/sys v0.0.0-20210423082822-04245dca01da
+ golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912
golang.org/x/text v0.3.6
- golang.org/x/time v0.0.0-20201208040808-7e3f01d25324
+ golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6
gopkg.in/urfave/cli.v1 v1.20.0
+ gopkg.in/yaml.v2 v2.4.0 // indirect
gotest.tools v2.2.0+incompatible // indirect
)
diff --git a/go.sum b/go.sum
index 33e187e75..825f0c892 100644
--- a/go.sum
+++ b/go.sum
@@ -33,6 +33,7 @@ github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSW
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
@@ -54,6 +55,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0=
+github.com/aws/aws-sdk-go v1.41.4 h1:5xRzZp8LfBFfowMPxmoNsxLBZOY/NTH4EeI7q2F5eWE=
+github.com/aws/aws-sdk-go v1.41.4/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
github.com/aws/aws-sdk-go-v2 v1.2.0 h1:BS+UYpbsElC82gB+2E2jiCBg36i8HlubTB/dO/moQ9c=
github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo=
github.com/aws/aws-sdk-go-v2/config v1.1.1 h1:ZAoq32boMzcaTW9bcUacBswAmHTbvlvDJICgHFZuECo=
@@ -103,6 +106,7 @@ github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f h1:C43yEtQ6NIf4ftFXD/V55gnGFgPbMQobd//YlnLjUJ8=
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -110,6 +114,9 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea h1:j4317fAZh7X6GqbFowYdYdI0L9bwxL07jyPZIdepyZ0=
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
+github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M=
+github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU=
+github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ=
@@ -135,8 +142,12 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
+github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
+github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
+github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
@@ -146,6 +157,8 @@ github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80n
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
+github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-sourcemap/sourcemap v2.1.2+incompatible h1:0b/xya7BKGhXuqFESKM4oIiRo9WOt2ebz7KxfreD6ug=
github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
@@ -178,6 +191,7 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
@@ -200,6 +214,7 @@ github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29 h1:sezaKhEfPFg8W0Enm61B9Gs911H8iesGY5R8NDPtd1M=
@@ -221,8 +236,13 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY=
github.com/influxdata/influxdb v1.8.3 h1:WEypI1BQFTT4teLM+1qkEcvUi0dAvopAI/ir0vAiBg8=
github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI=
+github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k=
+github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8=
github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk=
github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE=
+github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
+github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 h1:vilfsDSy7TDxedi9gyBkMvAirat/oRcL0lFdJBf6tdM=
+github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8=
github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE=
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
@@ -232,7 +252,9 @@ github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH
github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e h1:UvSe12bq+Uj2hWd8aOlwPmoZ+CITRFrdit+sDGfAg8U=
github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@@ -263,18 +285,27 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg=
+github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
-github.com/mattn/go-colorable v0.1.0 h1:v2XXALHHh6zHfYTJ+cSkwtyffnaOyR1MXaA91mTrb8o=
-github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
+github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d h1:oNAwILwmgWKFpuU+dXvI6dl9jG2mAWAZLX3r9s0PPiw=
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035 h1:USWjF42jDCSEeikX/G1g40ZWnsPXN5WkZ4jMHZWyBK4=
-github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
+github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
@@ -337,6 +368,8 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE=
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
+github.com/robertkrimen/otto v0.0.0-20211008084715-4eacda02dd21 h1:uMgr5kPPCGOlEPx6lE8GPYjFkAN4ZDA9FX++QjIZn6Q=
+github.com/robertkrimen/otto v0.0.0-20211008084715-4eacda02dd21/go.mod h1:/mK7FZ3mFYEn9zvNPhpngTyatyehSwte5bJZ4ehL5Xw=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
@@ -362,6 +395,7 @@ github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954 h1:xQdMZ1WLrgkkvOZ/LDQxjVxMLdby7osSh4ZEVa5sIjs=
@@ -374,6 +408,9 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4=
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
+github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -391,6 +428,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -438,11 +477,14 @@ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI=
+golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -464,6 +506,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -471,23 +514,31 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 h1:uCLL3g5wH2xjxVREVuAbP9JM5PPKjRbXKRa6IBjkzmU=
+golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -495,12 +546,14 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
+golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -587,6 +640,9 @@ gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 h1:a6cXbcDDUkSBlpnkWV1bJ+vv3mOgQEltEJ2rPxroVu0=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
+gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375/go.mod h1:lNEQeAhU009zbRxng+XOj5ITVgY24WcbNnQopyfKoYQ=
+gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
+gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=
@@ -596,8 +652,9 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go
index 9a82824ad..1af98e107 100644
--- a/internal/ethapi/api.go
+++ b/internal/ethapi/api.go
@@ -32,6 +32,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
+ "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/clique"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/consensus/misc"
@@ -1175,7 +1176,8 @@ func FormatLogs(logs []vm.StructLog) []StructLogRes {
}
// RPCMarshalHeader converts the given header to the RPC output .
-func RPCMarshalHeader(head *types.Header) map[string]interface{} {
+func RPCMarshalHeader(head *types.Header, engine consensus.Engine) map[string]interface{} {
+ miner, _ := engine.Author(head)
result := map[string]interface{}{
"number": (*hexutil.Big)(head.Number),
"hash": head.Hash(),
@@ -1185,7 +1187,7 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} {
"sha3Uncles": head.UncleHash,
"logsBloom": head.Bloom,
"stateRoot": head.Root,
- "miner": head.Coinbase,
+ "miner": miner,
"difficulty": (*hexutil.Big)(head.Difficulty),
"extraData": hexutil.Bytes(head.Extra),
"size": hexutil.Uint64(head.Size()),
@@ -1206,8 +1208,8 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} {
// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
// transaction hashes.
-func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
- fields := RPCMarshalHeader(block.Header())
+func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, engine consensus.Engine) (map[string]interface{}, error) {
+ fields := RPCMarshalHeader(block.Header(), engine)
fields["size"] = hexutil.Uint64(block.Size())
if inclTx {
@@ -1242,7 +1244,7 @@ func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]i
// rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires
// a `PublicBlockchainAPI`.
func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *types.Header) map[string]interface{} {
- fields := RPCMarshalHeader(header)
+ fields := RPCMarshalHeader(header, s.b.Engine())
fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, header.Hash()))
return fields
}
@@ -1250,7 +1252,7 @@ func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *type
// rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires
// a `PublicBlockchainAPI`.
func (s *PublicBlockChainAPI) rpcMarshalBlock(ctx context.Context, b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
- fields, err := RPCMarshalBlock(b, inclTx, fullTx)
+ fields, err := RPCMarshalBlock(b, inclTx, fullTx, s.b.Engine())
if err != nil {
return nil, err
}
diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go
index 8c12743dc..52811b2a9 100644
--- a/internal/ethapi/transaction_args.go
+++ b/internal/ethapi/transaction_args.go
@@ -171,7 +171,7 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend) error {
return nil
}
-// ToMessage converts th transaction arguments to the Message type used by the
+// ToMessage converts the transaction arguments to the Message type used by the
// core evm. This method is used in calls and traces that do not require a real
// live transaction.
func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (types.Message, error) {
@@ -238,7 +238,7 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (t
if args.AccessList != nil {
accessList = *args.AccessList
}
- msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, false)
+ msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, true)
return msg, nil
}
diff --git a/les/odr_test.go b/les/odr_test.go
index 91419ec80..ea88495d1 100644
--- a/les/odr_test.go
+++ b/les/odr_test.go
@@ -135,7 +135,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
from := statedb.GetOrNewStateObject(bankAddr)
from.SetBalance(math.MaxBig256)
- msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, false)}
+ msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true)}
context := core.NewEVMBlockContext(header, bc, nil)
txContext := core.NewEVMTxContext(msg)
@@ -150,7 +150,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
header := lc.GetHeaderByHash(bhash)
state := light.NewState(ctx, header, lc.Odr())
state.SetBalance(bankAddr, math.MaxBig256)
- msg := callmsg{types.NewMessage(bankAddr, &testContractAddr, 0, new(big.Int), 100000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, false)}
+ msg := callmsg{types.NewMessage(bankAddr, &testContractAddr, 0, new(big.Int), 100000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true)}
context := core.NewEVMBlockContext(header, lc, nil)
txContext := core.NewEVMTxContext(msg)
vmenv := vm.NewEVM(context, txContext, state, config, vm.Config{NoBaseFee: true})
diff --git a/light/odr_test.go b/light/odr_test.go
index b31e54d28..fdf657a82 100644
--- a/light/odr_test.go
+++ b/light/odr_test.go
@@ -194,7 +194,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
// Perform read-only call.
st.SetBalance(testBankAddress, math.MaxBig256)
- msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, false)}
+ msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true)}
txContext := core.NewEVMTxContext(msg)
context := core.NewEVMBlockContext(header, chain, nil)
vmenv := vm.NewEVM(context, txContext, st, config, vm.Config{NoBaseFee: true})
diff --git a/metrics/config.go b/metrics/config.go
index d05d66426..2eb09fb48 100644
--- a/metrics/config.go
+++ b/metrics/config.go
@@ -28,6 +28,11 @@ type Config struct {
InfluxDBUsername string `toml:",omitempty"`
InfluxDBPassword string `toml:",omitempty"`
InfluxDBTags string `toml:",omitempty"`
+
+ EnableInfluxDBV2 bool `toml:",omitempty"`
+ InfluxDBToken string `toml:",omitempty"`
+ InfluxDBBucket string `toml:",omitempty"`
+ InfluxDBOrganization string `toml:",omitempty"`
}
// DefaultConfig is the default config for metrics used in go-ethereum.
@@ -42,4 +47,10 @@ var DefaultConfig = Config{
InfluxDBUsername: "test",
InfluxDBPassword: "test",
InfluxDBTags: "host=localhost",
+
+ // influxdbv2-specific flags
+ EnableInfluxDBV2: false,
+ InfluxDBToken: "test",
+ InfluxDBBucket: "geth",
+ InfluxDBOrganization: "geth",
}
diff --git a/metrics/influxdb/influxdbv2.go b/metrics/influxdb/influxdbv2.go
new file mode 100644
index 000000000..00901f52c
--- /dev/null
+++ b/metrics/influxdb/influxdbv2.go
@@ -0,0 +1,223 @@
+//
+// 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 .
+package influxdb
+
+import (
+ "context"
+ "fmt"
+ "time"
+
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/metrics"
+ influxdb2 "github.com/influxdata/influxdb-client-go/v2"
+ "github.com/influxdata/influxdb-client-go/v2/api"
+)
+
+type v2Reporter struct {
+ reg metrics.Registry
+ interval time.Duration
+
+ endpoint string
+ token string
+ bucket string
+ organization string
+ namespace string
+ tags map[string]string
+
+ client influxdb2.Client
+ write api.WriteAPI
+
+ cache map[string]int64
+}
+
+// InfluxDBWithTags starts a InfluxDB reporter which will post the from the given metrics.Registry at each d interval with the specified tags
+func InfluxDBV2WithTags(r metrics.Registry, d time.Duration, endpoint string, token string, bucket string, organization string, namespace string, tags map[string]string) {
+ rep := &v2Reporter{
+ reg: r,
+ interval: d,
+ endpoint: endpoint,
+ token: token,
+ bucket: bucket,
+ organization: organization,
+ namespace: namespace,
+ tags: tags,
+ cache: make(map[string]int64),
+ }
+
+ rep.client = influxdb2.NewClient(rep.endpoint, rep.token)
+ defer rep.client.Close()
+
+ // async write client
+ rep.write = rep.client.WriteAPI(rep.organization, rep.bucket)
+ errorsCh := rep.write.Errors()
+
+ // have to handle write errors in a separate goroutine like this b/c the channel is unbuffered and will block writes if not read
+ go func() {
+ for err := range errorsCh {
+ log.Warn("write error", "err", err.Error())
+ }
+ }()
+ rep.run()
+}
+
+func (r *v2Reporter) run() {
+ intervalTicker := time.Tick(r.interval)
+ pingTicker := time.Tick(time.Second * 5)
+
+ for {
+ select {
+ case <-intervalTicker:
+ r.send()
+ case <-pingTicker:
+ _, err := r.client.Health(context.Background())
+ if err != nil {
+ log.Warn("Got error from influxdb client health check", "err", err.Error())
+ }
+ }
+ }
+
+}
+
+func (r *v2Reporter) send() {
+ r.reg.Each(func(name string, i interface{}) {
+ now := time.Now()
+ namespace := r.namespace
+
+ switch metric := i.(type) {
+
+ case metrics.Counter:
+ v := metric.Count()
+ l := r.cache[name]
+
+ measurement := fmt.Sprintf("%s%s.count", namespace, name)
+ fields := map[string]interface{}{
+ "value": v - l,
+ }
+
+ pt := influxdb2.NewPoint(measurement, r.tags, fields, now)
+ r.write.WritePoint(pt)
+
+ r.cache[name] = v
+
+ case metrics.Gauge:
+ ms := metric.Snapshot()
+
+ measurement := fmt.Sprintf("%s%s.gauge", namespace, name)
+ fields := map[string]interface{}{
+ "value": ms.Value(),
+ }
+
+ pt := influxdb2.NewPoint(measurement, r.tags, fields, now)
+ r.write.WritePoint(pt)
+
+ case metrics.GaugeFloat64:
+ ms := metric.Snapshot()
+
+ measurement := fmt.Sprintf("%s%s.gauge", namespace, name)
+ fields := map[string]interface{}{
+ "value": ms.Value(),
+ }
+
+ pt := influxdb2.NewPoint(measurement, r.tags, fields, now)
+ r.write.WritePoint(pt)
+
+ case metrics.Histogram:
+ ms := metric.Snapshot()
+
+ if ms.Count() > 0 {
+ ps := ms.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999})
+ measurement := fmt.Sprintf("%s%s.histogram", namespace, name)
+ fields := map[string]interface{}{
+ "count": ms.Count(),
+ "max": ms.Max(),
+ "mean": ms.Mean(),
+ "min": ms.Min(),
+ "stddev": ms.StdDev(),
+ "variance": ms.Variance(),
+ "p50": ps[0],
+ "p75": ps[1],
+ "p95": ps[2],
+ "p99": ps[3],
+ "p999": ps[4],
+ "p9999": ps[5],
+ }
+
+ pt := influxdb2.NewPoint(measurement, r.tags, fields, now)
+ r.write.WritePoint(pt)
+ }
+
+ case metrics.Meter:
+ ms := metric.Snapshot()
+
+ measurement := fmt.Sprintf("%s%s.meter", namespace, name)
+ fields := map[string]interface{}{
+ "count": ms.Count(),
+ "m1": ms.Rate1(),
+ "m5": ms.Rate5(),
+ "m15": ms.Rate15(),
+ "mean": ms.RateMean(),
+ }
+
+ pt := influxdb2.NewPoint(measurement, r.tags, fields, now)
+ r.write.WritePoint(pt)
+
+ case metrics.Timer:
+ ms := metric.Snapshot()
+ ps := ms.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999})
+
+ measurement := fmt.Sprintf("%s%s.timer", namespace, name)
+ fields := map[string]interface{}{
+ "count": ms.Count(),
+ "max": ms.Max(),
+ "mean": ms.Mean(),
+ "min": ms.Min(),
+ "stddev": ms.StdDev(),
+ "variance": ms.Variance(),
+ "p50": ps[0],
+ "p75": ps[1],
+ "p95": ps[2],
+ "p99": ps[3],
+ "p999": ps[4],
+ "p9999": ps[5],
+ "m1": ms.Rate1(),
+ "m5": ms.Rate5(),
+ "m15": ms.Rate15(),
+ "meanrate": ms.RateMean(),
+ }
+
+ pt := influxdb2.NewPoint(measurement, r.tags, fields, now)
+ r.write.WritePoint(pt)
+
+ case metrics.ResettingTimer:
+ t := metric.Snapshot()
+
+ if len(t.Values()) > 0 {
+ ps := t.Percentiles([]float64{50, 95, 99})
+ val := t.Values()
+
+ measurement := fmt.Sprintf("%s%s.span", namespace, name)
+ fields := map[string]interface{}{
+ "count": len(val),
+ "max": val[len(val)-1],
+ "mean": t.Mean(),
+ "min": val[0],
+ "p50": ps[0],
+ "p95": ps[1],
+ "p99": ps[2],
+ }
+
+ pt := influxdb2.NewPoint(measurement, r.tags, fields, now)
+ r.write.WritePoint(pt)
+ }
+ }
+ })
+
+ // Force all unwritten data to be sent
+ r.write.Flush()
+}
diff --git a/params/bootnodes.go b/params/bootnodes.go
index 1610ea819..bc291449e 100644
--- a/params/bootnodes.go
+++ b/params/bootnodes.go
@@ -67,12 +67,6 @@ var GoerliBootnodes = []string{
"enode://a59e33ccd2b3e52d578f1fbd70c6f9babda2650f0760d6ff3b37742fdcdfdb3defba5d56d315b40c46b70198c7621e63ffa3f987389c7118634b0fefbbdfa7fd@51.15.119.157:40303",
}
-// CalaverasBootnodes are the enode URLs of the P2P bootstrap nodes running on the
-// Calaveras ephemeral test network.
-var CalaverasBootnodes = []string{
- "enode://9e1096aa59862a6f164994cb5cb16f5124d6c992cdbf4535ff7dea43ea1512afe5448dca9df1b7ab0726129603f1a3336b631e4d7a1a44c94daddd03241587f9@3.9.20.133:30303",
-}
-
var V5Bootnodes = []string{
// Teku team's bootnode
"enr:-KG4QOtcP9X1FbIMOe17QNMKqDxCpm14jcX5tiOE4_TyMrFqbmhPZHK_ZPG2Gxb1GE2xdtodOfx9-cgvNtxnRyHEmC0ghGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQDE8KdiXNlY3AyNTZrMaEDhpehBDbZjM_L9ek699Y7vhUJ-eAdMyQW_Fil522Y0fODdGNwgiMog3VkcIIjKA",
diff --git a/params/config.go b/params/config.go
index 591c36de2..16c801825 100644
--- a/params/config.go
+++ b/params/config.go
@@ -27,11 +27,10 @@ import (
// Genesis hashes to enforce below configs on.
var (
- MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
- RopstenGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d")
- RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177")
- GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a")
- CalaverasGenesisHash = common.HexToHash("0xeb9233d066c275efcdfed8037f4fc082770176aefdbcb7691c71da412a5670f2")
+ MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
+ RopstenGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d")
+ RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177")
+ GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a")
)
// TrustedCheckpoints associates each known checkpoint with the genesis hash of
@@ -221,27 +220,6 @@ var (
Threshold: 2,
}
- CalaverasChainConfig = &ChainConfig{
- ChainID: big.NewInt(123),
- HomesteadBlock: big.NewInt(0),
- DAOForkBlock: nil,
- DAOForkSupport: true,
- EIP150Block: big.NewInt(0),
- EIP155Block: big.NewInt(0),
- EIP158Block: big.NewInt(0),
- ByzantiumBlock: big.NewInt(0),
- ConstantinopleBlock: big.NewInt(0),
- PetersburgBlock: big.NewInt(0),
- IstanbulBlock: big.NewInt(0),
- MuirGlacierBlock: nil,
- BerlinBlock: big.NewInt(0),
- LondonBlock: big.NewInt(500),
- Clique: &CliqueConfig{
- Period: 30,
- Epoch: 30000,
- },
- }
-
// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ethereum core developers into the Ethash consensus.
//
diff --git a/params/version.go b/params/version.go
index 2d3155d35..8d222ac04 100644
--- a/params/version.go
+++ b/params/version.go
@@ -23,7 +23,7 @@ import (
const (
VersionMajor = 1 // Major version component of the current release
VersionMinor = 10 // Minor version component of the current release
- VersionPatch = 7 // Patch version component of the current release
+ VersionPatch = 8 // Patch version component of the current release
VersionMeta = "stable" // Version metadata to append to the version string
)
diff --git a/signer/core/apitypes/types.go b/signer/core/apitypes/types.go
index 591d253ab..625959219 100644
--- a/signer/core/apitypes/types.go
+++ b/signer/core/apitypes/types.go
@@ -19,12 +19,12 @@ package apitypes
import (
"encoding/json"
"fmt"
+ "math/big"
"strings"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/internal/ethapi"
)
type ValidationInfo struct {
@@ -97,23 +97,60 @@ func (args SendTxArgs) String() string {
return err.Error()
}
+// ToTransaction converts the arguments to a transaction.
func (args *SendTxArgs) ToTransaction() *types.Transaction {
- txArgs := ethapi.TransactionArgs{
- Gas: &args.Gas,
- GasPrice: args.GasPrice,
- MaxFeePerGas: args.MaxFeePerGas,
- MaxPriorityFeePerGas: args.MaxPriorityFeePerGas,
- Value: &args.Value,
- Nonce: &args.Nonce,
- Data: args.Data,
- Input: args.Input,
- AccessList: args.AccessList,
- ChainID: args.ChainID,
- }
// Add the To-field, if specified
+ var to *common.Address
if args.To != nil {
- to := args.To.Address()
- txArgs.To = &to
+ dstAddr := args.To.Address()
+ to = &dstAddr
}
- return txArgs.ToTransaction()
+
+ var input []byte
+ if args.Input != nil {
+ input = *args.Input
+ } else if args.Data != nil {
+ input = *args.Data
+ }
+
+ var data types.TxData
+ switch {
+ case args.MaxFeePerGas != nil:
+ al := types.AccessList{}
+ if args.AccessList != nil {
+ al = *args.AccessList
+ }
+ data = &types.DynamicFeeTx{
+ To: to,
+ ChainID: (*big.Int)(args.ChainID),
+ Nonce: uint64(args.Nonce),
+ Gas: uint64(args.Gas),
+ GasFeeCap: (*big.Int)(args.MaxFeePerGas),
+ GasTipCap: (*big.Int)(args.MaxPriorityFeePerGas),
+ Value: (*big.Int)(&args.Value),
+ Data: input,
+ AccessList: al,
+ }
+ case args.AccessList != nil:
+ data = &types.AccessListTx{
+ To: to,
+ ChainID: (*big.Int)(args.ChainID),
+ Nonce: uint64(args.Nonce),
+ Gas: uint64(args.Gas),
+ GasPrice: (*big.Int)(args.GasPrice),
+ Value: (*big.Int)(&args.Value),
+ Data: input,
+ AccessList: *args.AccessList,
+ }
+ default:
+ data = &types.LegacyTx{
+ To: to,
+ Nonce: uint64(args.Nonce),
+ Gas: uint64(args.Gas),
+ GasPrice: (*big.Int)(args.GasPrice),
+ Value: (*big.Int)(&args.Value),
+ Data: input,
+ }
+ }
+ return types.NewTx(data)
}
diff --git a/tests/gen_vmexec.go b/tests/gen_vmexec.go
deleted file mode 100644
index 2fe155152..000000000
--- a/tests/gen_vmexec.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package tests
-
-import (
- "encoding/json"
- "errors"
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
-)
-
-var _ = (*vmExecMarshaling)(nil)
-
-// MarshalJSON marshals as JSON.
-func (v vmExec) MarshalJSON() ([]byte, error) {
- type vmExec struct {
- Address common.UnprefixedAddress `json:"address" gencodec:"required"`
- Caller common.UnprefixedAddress `json:"caller" gencodec:"required"`
- Origin common.UnprefixedAddress `json:"origin" gencodec:"required"`
- Code hexutil.Bytes `json:"code" gencodec:"required"`
- Data hexutil.Bytes `json:"data" gencodec:"required"`
- Value *math.HexOrDecimal256 `json:"value" gencodec:"required"`
- GasLimit math.HexOrDecimal64 `json:"gas" gencodec:"required"`
- GasPrice *math.HexOrDecimal256 `json:"gasPrice" gencodec:"required"`
- }
- var enc vmExec
- enc.Address = common.UnprefixedAddress(v.Address)
- enc.Caller = common.UnprefixedAddress(v.Caller)
- enc.Origin = common.UnprefixedAddress(v.Origin)
- enc.Code = v.Code
- enc.Data = v.Data
- enc.Value = (*math.HexOrDecimal256)(v.Value)
- enc.GasLimit = math.HexOrDecimal64(v.GasLimit)
- enc.GasPrice = (*math.HexOrDecimal256)(v.GasPrice)
- return json.Marshal(&enc)
-}
-
-// UnmarshalJSON unmarshals from JSON.
-func (v *vmExec) UnmarshalJSON(input []byte) error {
- type vmExec struct {
- Address *common.UnprefixedAddress `json:"address" gencodec:"required"`
- Caller *common.UnprefixedAddress `json:"caller" gencodec:"required"`
- Origin *common.UnprefixedAddress `json:"origin" gencodec:"required"`
- Code *hexutil.Bytes `json:"code" gencodec:"required"`
- Data *hexutil.Bytes `json:"data" gencodec:"required"`
- Value *math.HexOrDecimal256 `json:"value" gencodec:"required"`
- GasLimit *math.HexOrDecimal64 `json:"gas" gencodec:"required"`
- GasPrice *math.HexOrDecimal256 `json:"gasPrice" gencodec:"required"`
- }
- var dec vmExec
- if err := json.Unmarshal(input, &dec); err != nil {
- return err
- }
- if dec.Address == nil {
- return errors.New("missing required field 'address' for vmExec")
- }
- v.Address = common.Address(*dec.Address)
- if dec.Caller == nil {
- return errors.New("missing required field 'caller' for vmExec")
- }
- v.Caller = common.Address(*dec.Caller)
- if dec.Origin == nil {
- return errors.New("missing required field 'origin' for vmExec")
- }
- v.Origin = common.Address(*dec.Origin)
- if dec.Code == nil {
- return errors.New("missing required field 'code' for vmExec")
- }
- v.Code = *dec.Code
- if dec.Data == nil {
- return errors.New("missing required field 'data' for vmExec")
- }
- v.Data = *dec.Data
- if dec.Value == nil {
- return errors.New("missing required field 'value' for vmExec")
- }
- v.Value = (*big.Int)(dec.Value)
- if dec.GasLimit == nil {
- return errors.New("missing required field 'gas' for vmExec")
- }
- v.GasLimit = uint64(*dec.GasLimit)
- if dec.GasPrice == nil {
- return errors.New("missing required field 'gasPrice' for vmExec")
- }
- v.GasPrice = (*big.Int)(dec.GasPrice)
- return nil
-}
diff --git a/tests/init_test.go b/tests/init_test.go
index 969cf7139..312ad8869 100644
--- a/tests/init_test.go
+++ b/tests/init_test.go
@@ -34,12 +34,11 @@ import (
)
var (
- baseDir = filepath.Join(".", "testdata")
- blockTestDir = filepath.Join(baseDir, "BlockchainTests")
- stateTestDir = filepath.Join(baseDir, "GeneralStateTests")
- //legacyStateTestDir = filepath.Join(baseDir, "LegacyTests", "Constantinople", "GeneralStateTests")
+ baseDir = filepath.Join(".", "testdata")
+ blockTestDir = filepath.Join(baseDir, "BlockchainTests")
+ stateTestDir = filepath.Join(baseDir, "GeneralStateTests")
+ legacyStateTestDir = filepath.Join(baseDir, "LegacyTests", "Constantinople", "GeneralStateTests")
transactionTestDir = filepath.Join(baseDir, "TransactionTests")
- vmTestDir = filepath.Join(baseDir, "VMTests")
rlpTestDir = filepath.Join(baseDir, "RLPTests")
difficultyTestDir = filepath.Join(baseDir, "BasicTests")
)
diff --git a/tests/state_test.go b/tests/state_test.go
index 242e9712a..c2ca0e8d6 100644
--- a/tests/state_test.go
+++ b/tests/state_test.go
@@ -45,8 +45,7 @@ func TestState(t *testing.T) {
// Uses 1GB RAM per tested fork
st.skipLoad(`^stStaticCall/static_Call1MB`)
- // Un-skip this when https://github.com/ethereum/tests/issues/908 is closed
- st.skipLoad(`^stQuadraticComplexityTest/QuadraticComplexitySolidity_CallDataCopy`)
+
// Broken tests:
// Expected failures:
//st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/Byzantium/0`, "bug in test")
@@ -59,9 +58,7 @@ func TestState(t *testing.T) {
// For Istanbul, older tests were moved into LegacyTests
for _, dir := range []string{
stateTestDir,
- // legacy state tests are disabled, due to them not being
- // regenerated for the no-sender-eoa change.
- //legacyStateTestDir,
+ legacyStateTestDir,
} {
st.walk(t, dir, func(t *testing.T, name string, test *StateTest) {
for _, subtest := range test.Subtests() {
diff --git a/tests/state_test_util.go b/tests/state_test_util.go
index 4f57fee89..f7fb08bfb 100644
--- a/tests/state_test_util.go
+++ b/tests/state_test_util.go
@@ -348,7 +348,7 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (core.Messa
}
msg := types.NewMessage(from, to, tx.Nonce, value, gasLimit, gasPrice,
- tx.MaxFeePerGas, tx.MaxPriorityFeePerGas, data, accessList, true)
+ tx.MaxFeePerGas, tx.MaxPriorityFeePerGas, data, accessList, false)
return msg, nil
}
@@ -358,3 +358,7 @@ func rlpHash(x interface{}) (h common.Hash) {
hw.Sum(h[:0])
return h
}
+
+func vmTestBlockHash(n uint64) common.Hash {
+ return common.BytesToHash(crypto.Keccak256([]byte(big.NewInt(int64(n)).String())))
+}
diff --git a/tests/testdata b/tests/testdata
index 5d534e37b..6b85703b5 160000
--- a/tests/testdata
+++ b/tests/testdata
@@ -1 +1 @@
-Subproject commit 5d534e37b80e9310e8c7751f805ca481a451123e
+Subproject commit 6b85703b568f4456582a00665d8a3e5c3b20b484
diff --git a/tests/vm_test.go b/tests/vm_test.go
deleted file mode 100644
index 2150df9e2..000000000
--- a/tests/vm_test.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2014 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 .
-
-package tests
-
-import (
- "testing"
-
- "github.com/ethereum/go-ethereum/core/vm"
-)
-
-func TestVM(t *testing.T) {
- t.Parallel()
- vmt := new(testMatcher)
- vmt.slow("^vmPerformance")
- vmt.fails("^vmSystemOperationsTest.json/createNameRegistrator$", "fails without parallel execution")
-
- vmt.walk(t, vmTestDir, func(t *testing.T, name string, test *VMTest) {
- withTrace(t, test.json.Exec.GasLimit, func(vmconfig vm.Config) error {
- return vmt.checkFailure(t, test.Run(vmconfig, false))
- })
- withTrace(t, test.json.Exec.GasLimit, func(vmconfig vm.Config) error {
- return vmt.checkFailure(t, test.Run(vmconfig, true))
- })
- })
-}
diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go
deleted file mode 100644
index 418cc6716..000000000
--- a/tests/vm_test_util.go
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2015 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 .
-
-package tests
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/params"
-)
-
-// VMTest checks EVM execution without block or transaction context.
-// See https://github.com/ethereum/tests/wiki/VM-Tests for the test format specification.
-type VMTest struct {
- json vmJSON
-}
-
-func (t *VMTest) UnmarshalJSON(data []byte) error {
- return json.Unmarshal(data, &t.json)
-}
-
-type vmJSON struct {
- Env stEnv `json:"env"`
- Exec vmExec `json:"exec"`
- Logs common.UnprefixedHash `json:"logs"`
- GasRemaining *math.HexOrDecimal64 `json:"gas"`
- Out hexutil.Bytes `json:"out"`
- Pre core.GenesisAlloc `json:"pre"`
- Post core.GenesisAlloc `json:"post"`
- PostStateRoot common.Hash `json:"postStateRoot"`
-}
-
-//go:generate gencodec -type vmExec -field-override vmExecMarshaling -out gen_vmexec.go
-
-type vmExec struct {
- Address common.Address `json:"address" gencodec:"required"`
- Caller common.Address `json:"caller" gencodec:"required"`
- Origin common.Address `json:"origin" gencodec:"required"`
- Code []byte `json:"code" gencodec:"required"`
- Data []byte `json:"data" gencodec:"required"`
- Value *big.Int `json:"value" gencodec:"required"`
- GasLimit uint64 `json:"gas" gencodec:"required"`
- GasPrice *big.Int `json:"gasPrice" gencodec:"required"`
-}
-
-type vmExecMarshaling struct {
- Address common.UnprefixedAddress
- Caller common.UnprefixedAddress
- Origin common.UnprefixedAddress
- Code hexutil.Bytes
- Data hexutil.Bytes
- Value *math.HexOrDecimal256
- GasLimit math.HexOrDecimal64
- GasPrice *math.HexOrDecimal256
-}
-
-func (t *VMTest) Run(vmconfig vm.Config, snapshotter bool) error {
- snaps, statedb := MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, snapshotter)
- if snapshotter {
- preRoot := statedb.IntermediateRoot(false)
- defer func() {
- if _, err := snaps.Journal(preRoot); err != nil {
- panic(err)
- }
- }()
- }
- ret, gasRemaining, err := t.exec(statedb, vmconfig)
-
- if t.json.GasRemaining == nil {
- if err == nil {
- return fmt.Errorf("gas unspecified (indicating an error), but VM returned no error")
- }
- if gasRemaining > 0 {
- return fmt.Errorf("gas unspecified (indicating an error), but VM returned gas remaining > 0")
- }
- return nil
- }
- // Test declares gas, expecting outputs to match.
- if !bytes.Equal(ret, t.json.Out) {
- return fmt.Errorf("return data mismatch: got %x, want %x", ret, t.json.Out)
- }
- if gasRemaining != uint64(*t.json.GasRemaining) {
- return fmt.Errorf("remaining gas %v, want %v", gasRemaining, *t.json.GasRemaining)
- }
- for addr, account := range t.json.Post {
- for k, wantV := range account.Storage {
- if haveV := statedb.GetState(addr, k); haveV != wantV {
- return fmt.Errorf("wrong storage value at %x:\n got %x\n want %x", k, haveV, wantV)
- }
- }
- }
- // if root := statedb.IntermediateRoot(false); root != t.json.PostStateRoot {
- // return fmt.Errorf("post state root mismatch, got %x, want %x", root, t.json.PostStateRoot)
- // }
- if logs := rlpHash(statedb.Logs()); logs != common.Hash(t.json.Logs) {
- return fmt.Errorf("post state logs hash mismatch: got %x, want %x", logs, t.json.Logs)
- }
- return nil
-}
-
-func (t *VMTest) exec(statedb *state.StateDB, vmconfig vm.Config) ([]byte, uint64, error) {
- evm := t.newEVM(statedb, vmconfig)
- e := t.json.Exec
- return evm.Call(vm.AccountRef(e.Caller), e.Address, e.Data, e.GasLimit, e.Value)
-}
-
-func (t *VMTest) newEVM(statedb *state.StateDB, vmconfig vm.Config) *vm.EVM {
- initialCall := true
- canTransfer := func(db vm.StateDB, address common.Address, amount *big.Int) bool {
- if initialCall {
- initialCall = false
- return true
- }
- return core.CanTransfer(db, address, amount)
- }
- transfer := func(db vm.StateDB, sender, recipient common.Address, amount *big.Int) {}
- txContext := vm.TxContext{
- Origin: t.json.Exec.Origin,
- GasPrice: t.json.Exec.GasPrice,
- }
- context := vm.BlockContext{
- CanTransfer: canTransfer,
- Transfer: transfer,
- GetHash: vmTestBlockHash,
- Coinbase: t.json.Env.Coinbase,
- BlockNumber: new(big.Int).SetUint64(t.json.Env.Number),
- Time: new(big.Int).SetUint64(t.json.Env.Timestamp),
- GasLimit: t.json.Env.GasLimit,
- Difficulty: t.json.Env.Difficulty,
- }
- vmconfig.NoRecursion = true
- return vm.NewEVM(context, txContext, statedb, params.MainnetChainConfig, vmconfig)
-}
-
-func vmTestBlockHash(n uint64) common.Hash {
- return common.BytesToHash(crypto.Keccak256([]byte(big.NewInt(int64(n)).String())))
-}