Merge branch 'master' into slog

This commit is contained in:
Martin Holst Swende 2023-11-22 13:55:52 +01:00 committed by GitHub
commit 77b6db7b45
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
96 changed files with 585 additions and 174 deletions

View file

@ -4,7 +4,7 @@ ARG VERSION=""
ARG BUILDNUM="" ARG BUILDNUM=""
# Build Geth in a stock Go builder container # Build Geth in a stock Go builder container
FROM golang:1.20-alpine as builder FROM golang:1.21-alpine as builder
RUN apk add --no-cache gcc musl-dev linux-headers git RUN apk add --no-cache gcc musl-dev linux-headers git

View file

@ -80,7 +80,7 @@ func (arguments Arguments) isTuple() bool {
func (arguments Arguments) Unpack(data []byte) ([]interface{}, error) { func (arguments Arguments) Unpack(data []byte) ([]interface{}, error) {
if len(data) == 0 { if len(data) == 0 {
if len(arguments.NonIndexed()) != 0 { if len(arguments.NonIndexed()) != 0 {
return nil, errors.New("abi: attempting to unmarshall an empty string while arguments are expected") return nil, errors.New("abi: attempting to unmarshal an empty string while arguments are expected")
} }
return make([]interface{}, 0), nil return make([]interface{}, 0), nil
} }
@ -95,7 +95,7 @@ func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte)
} }
if len(data) == 0 { if len(data) == 0 {
if len(arguments.NonIndexed()) != 0 { if len(arguments.NonIndexed()) != 0 {
return errors.New("abi: attempting to unmarshall an empty string while arguments are expected") return errors.New("abi: attempting to unmarshal an empty string while arguments are expected")
} }
return nil // Nothing to unmarshal, return return nil // Nothing to unmarshal, return
} }

View file

@ -846,7 +846,7 @@ func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error {
defer b.mu.Unlock() defer b.mu.Unlock()
if len(b.pendingBlock.Transactions()) != 0 { if len(b.pendingBlock.Transactions()) != 0 {
return errors.New("Could not adjust time on non-empty block") return errors.New("could not adjust time on non-empty block")
} }
// Get the last block // Get the last block
block := b.blockchain.GetBlockByHash(b.pendingBlock.ParentHash()) block := b.blockchain.GetBlockByHash(b.pendingBlock.ParentHash())

View file

@ -121,7 +121,7 @@ func TestWaitDeployedCornerCases(t *testing.T) {
backend.Commit() backend.Commit()
notContentCreation := errors.New("tx is not contract creation") notContentCreation := errors.New("tx is not contract creation")
if _, err := bind.WaitDeployed(ctx, backend, tx); err.Error() != notContentCreation.Error() { if _, err := bind.WaitDeployed(ctx, backend, tx); err.Error() != notContentCreation.Error() {
t.Errorf("error missmatch: want %q, got %q, ", notContentCreation, err) t.Errorf("error mismatch: want %q, got %q, ", notContentCreation, err)
} }
// Create a transaction that is not mined. // Create a transaction that is not mined.
@ -131,7 +131,7 @@ func TestWaitDeployedCornerCases(t *testing.T) {
go func() { go func() {
contextCanceled := errors.New("context canceled") contextCanceled := errors.New("context canceled")
if _, err := bind.WaitDeployed(ctx, backend, tx); err.Error() != contextCanceled.Error() { if _, err := bind.WaitDeployed(ctx, backend, tx); err.Error() != contextCanceled.Error() {
t.Errorf("error missmatch: want %q, got %q, ", contextCanceled, err) t.Errorf("error mismatch: want %q, got %q, ", contextCanceled, err)
} }
}() }()

View file

@ -18,7 +18,6 @@ package abi
import ( import (
"bytes" "bytes"
"errors"
"fmt" "fmt"
"strings" "strings"
@ -84,10 +83,10 @@ func (e Error) String() string {
func (e *Error) Unpack(data []byte) (interface{}, error) { func (e *Error) Unpack(data []byte) (interface{}, error) {
if len(data) < 4 { if len(data) < 4 {
return "", errors.New("invalid data for unpacking") return "", fmt.Errorf("insufficient data for unpacking: have %d, want at least 4", len(data))
} }
if !bytes.Equal(data[:4], e.ID[:4]) { if !bytes.Equal(data[:4], e.ID[:4]) {
return "", errors.New("invalid data for unpacking") return "", fmt.Errorf("invalid identifier, have %#x want %#x", data[:4], e.ID[:4])
} }
return e.Inputs.Unpack(data[4:]) return e.Inputs.Unpack(data[4:])
} }

View file

@ -117,15 +117,6 @@ func NewMethod(name string, rawName string, funType FunctionType, mutability str
sig = fmt.Sprintf("%v(%v)", rawName, strings.Join(types, ",")) sig = fmt.Sprintf("%v(%v)", rawName, strings.Join(types, ","))
id = crypto.Keccak256([]byte(sig))[:4] id = crypto.Keccak256([]byte(sig))[:4]
} }
// Extract meaningful state mutability of solidity method.
// If it's default value, never print it.
state := mutability
if state == "nonpayable" {
state = ""
}
if state != "" {
state = state + " "
}
identity := fmt.Sprintf("function %v", rawName) identity := fmt.Sprintf("function %v", rawName)
switch funType { switch funType {
case Fallback: case Fallback:
@ -135,7 +126,14 @@ func NewMethod(name string, rawName string, funType FunctionType, mutability str
case Constructor: case Constructor:
identity = "constructor" identity = "constructor"
} }
str := fmt.Sprintf("%v(%v) %sreturns(%v)", identity, strings.Join(inputNames, ", "), state, strings.Join(outputNames, ", ")) var str string
// Extract meaningful state mutability of solidity method.
// If it's empty string or default value "nonpayable", never print it.
if mutability == "" || mutability == "nonpayable" {
str = fmt.Sprintf("%v(%v) returns(%v)", identity, strings.Join(inputNames, ", "), strings.Join(outputNames, ", "))
} else {
str = fmt.Sprintf("%v(%v) %s returns(%v)", identity, strings.Join(inputNames, ", "), mutability, strings.Join(outputNames, ", "))
}
return Method{ return Method{
Name: name, Name: name,

View file

@ -57,7 +57,7 @@ func packElement(t Type, reflectValue reflect.Value) ([]byte, error) {
reflectValue = mustArrayToByteSlice(reflectValue) reflectValue = mustArrayToByteSlice(reflectValue)
} }
if reflectValue.Type() != reflect.TypeOf([]byte{}) { if reflectValue.Type() != reflect.TypeOf([]byte{}) {
return []byte{}, errors.New("Bytes type is neither slice nor array") return []byte{}, errors.New("bytes type is neither slice nor array")
} }
return packBytesSlice(reflectValue.Bytes(), reflectValue.Len()), nil return packBytesSlice(reflectValue.Bytes(), reflectValue.Len()), nil
case FixedBytesTy, FunctionTy: case FixedBytesTy, FunctionTy:
@ -66,7 +66,7 @@ func packElement(t Type, reflectValue reflect.Value) ([]byte, error) {
} }
return common.RightPadBytes(reflectValue.Bytes(), 32), nil return common.RightPadBytes(reflectValue.Bytes(), 32), nil
default: default:
return []byte{}, fmt.Errorf("Could not pack element, unknown type: %v", t.T) return []byte{}, fmt.Errorf("could not pack element, unknown type: %v", t.T)
} }
} }

View file

@ -134,7 +134,7 @@ func setSlice(dst, src reflect.Value) error {
dst.Set(slice) dst.Set(slice)
return nil return nil
} }
return errors.New("Cannot set slice, destination not settable") return errors.New("cannot set slice, destination not settable")
} }
func setArray(dst, src reflect.Value) error { func setArray(dst, src reflect.Value) error {
@ -155,7 +155,7 @@ func setArray(dst, src reflect.Value) error {
dst.Set(array) dst.Set(array)
return nil return nil
} }
return errors.New("Cannot set array, destination not settable") return errors.New("cannot set array, destination not settable")
} }
func setStruct(dst, src reflect.Value) error { func setStruct(dst, src reflect.Value) error {
@ -163,7 +163,7 @@ func setStruct(dst, src reflect.Value) error {
srcField := src.Field(i) srcField := src.Field(i)
dstField := dst.Field(i) dstField := dst.Field(i)
if !dstField.IsValid() || !srcField.IsValid() { if !dstField.IsValid() || !srcField.IsValid() {
return fmt.Errorf("Could not find src field: %v value: %v in destination", srcField.Type().Name(), srcField) return fmt.Errorf("could not find src field: %v value: %v in destination", srcField.Type().Name(), srcField)
} }
if err := set(dstField, srcField); err != nil { if err := set(dstField, srcField); err != nil {
return err return err

View file

@ -206,13 +206,13 @@ var unpackTests = []unpackTest{
def: `[{"type":"bool"}]`, def: `[{"type":"bool"}]`,
enc: "", enc: "",
want: false, want: false,
err: "abi: attempting to unmarshall an empty string while arguments are expected", err: "abi: attempting to unmarshal an empty string while arguments are expected",
}, },
{ {
def: `[{"type":"bytes32","indexed":true},{"type":"uint256","indexed":false}]`, def: `[{"type":"bytes32","indexed":true},{"type":"uint256","indexed":false}]`,
enc: "", enc: "",
want: false, want: false,
err: "abi: attempting to unmarshall an empty string while arguments are expected", err: "abi: attempting to unmarshal an empty string while arguments are expected",
}, },
{ {
def: `[{"type":"bool","indexed":true},{"type":"uint64","indexed":true}]`, def: `[{"type":"bool","indexed":true},{"type":"uint64","indexed":true}]`,

View file

@ -68,7 +68,7 @@ func waitWatcherStart(ks *KeyStore) bool {
func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error { func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error {
var list []accounts.Account var list []accounts.Account
for t0 := time.Now(); time.Since(t0) < 5*time.Second; time.Sleep(200 * time.Millisecond) { for t0 := time.Now(); time.Since(t0) < 5*time.Second; time.Sleep(100 * time.Millisecond) {
list = ks.Accounts() list = ks.Accounts()
if reflect.DeepEqual(list, wantAccounts) { if reflect.DeepEqual(list, wantAccounts) {
// ks should have also received change notifications // ks should have also received change notifications
@ -350,7 +350,7 @@ func TestUpdatedKeyfileContents(t *testing.T) {
return return
} }
// needed so that modTime of `file` is different to its current value after forceCopyFile // needed so that modTime of `file` is different to its current value after forceCopyFile
time.Sleep(time.Second) os.Chtimes(file, time.Now().Add(-time.Second), time.Now().Add(-time.Second))
// Now replace file contents // Now replace file contents
if err := forceCopyFile(file, cachetestAccounts[1].URL.Path); err != nil { if err := forceCopyFile(file, cachetestAccounts[1].URL.Path); err != nil {
@ -366,7 +366,7 @@ func TestUpdatedKeyfileContents(t *testing.T) {
} }
// needed so that modTime of `file` is different to its current value after forceCopyFile // needed so that modTime of `file` is different to its current value after forceCopyFile
time.Sleep(time.Second) os.Chtimes(file, time.Now().Add(-time.Second), time.Now().Add(-time.Second))
// Now replace file contents again // Now replace file contents again
if err := forceCopyFile(file, cachetestAccounts[2].URL.Path); err != nil { if err := forceCopyFile(file, cachetestAccounts[2].URL.Path); err != nil {
@ -382,7 +382,7 @@ func TestUpdatedKeyfileContents(t *testing.T) {
} }
// needed so that modTime of `file` is different to its current value after os.WriteFile // needed so that modTime of `file` is different to its current value after os.WriteFile
time.Sleep(time.Second) os.Chtimes(file, time.Now().Add(-time.Second), time.Now().Add(-time.Second))
// Now replace file contents with crap // Now replace file contents with crap
if err := os.WriteFile(file, []byte("foo"), 0600); err != nil { if err := os.WriteFile(file, []byte("foo"), 0600); err != nil {

View file

@ -54,7 +54,7 @@ func TestKeyEncryptDecrypt(t *testing.T) {
// Recrypt with a new password and start over // Recrypt with a new password and start over
password += "new data appended" // nolint: gosec password += "new data appended" // nolint: gosec
if keyjson, err = EncryptKey(key, password, veryLightScryptN, veryLightScryptP); err != nil { if keyjson, err = EncryptKey(key, password, veryLightScryptN, veryLightScryptP); err != nil {
t.Errorf("test %d: failed to recrypt key %v", i, err) t.Errorf("test %d: failed to re-encrypt key %v", i, err)
} }
} }
} }

View file

@ -125,7 +125,7 @@ func (w *watcher) loop() {
if !ok { if !ok {
return return
} }
log.Info("Filsystem watcher error", "err", err) log.Info("Filesystem watcher error", "err", err)
case <-debounce.C: case <-debounce.C:
w.ac.scanAccounts() w.ac.scanAccounts()
rescanTriggered = false rescanTriggered = false

View file

@ -776,16 +776,16 @@ func (w *Wallet) findAccountPath(account accounts.Account) (accounts.DerivationP
return nil, fmt.Errorf("scheme %s does not match wallet scheme %s", account.URL.Scheme, w.Hub.scheme) return nil, fmt.Errorf("scheme %s does not match wallet scheme %s", account.URL.Scheme, w.Hub.scheme)
} }
parts := strings.SplitN(account.URL.Path, "/", 2) url, path, found := strings.Cut(account.URL.Path, "/")
if len(parts) != 2 { if !found {
return nil, fmt.Errorf("invalid URL format: %s", account.URL) return nil, fmt.Errorf("invalid URL format: %s", account.URL)
} }
if parts[0] != fmt.Sprintf("%x", w.PublicKey[1:3]) { if url != fmt.Sprintf("%x", w.PublicKey[1:3]) {
return nil, fmt.Errorf("URL %s is not for this wallet", account.URL) return nil, fmt.Errorf("URL %s is not for this wallet", account.URL)
} }
return accounts.ParseDerivationPath(parts[1]) return accounts.ParseDerivationPath(path)
} }
// Session represents a secured communication session with the wallet. // Session represents a secured communication session with the wallet.

View file

@ -55,7 +55,7 @@ func TestURLMarshalJSON(t *testing.T) {
url := URL{Scheme: "https", Path: "ethereum.org"} url := URL{Scheme: "https", Path: "ethereum.org"}
json, err := url.MarshalJSON() json, err := url.MarshalJSON()
if err != nil { if err != nil {
t.Errorf("unexpcted error: %v", err) t.Errorf("unexpected error: %v", err)
} }
if string(json) != "\"https://ethereum.org\"" { if string(json) != "\"https://ethereum.org\"" {
t.Errorf("expected: %v, got: %v", "\"https://ethereum.org\"", string(json)) t.Errorf("expected: %v, got: %v", "\"https://ethereum.org\"", string(json))
@ -66,7 +66,7 @@ func TestURLUnmarshalJSON(t *testing.T) {
url := &URL{} url := &URL{}
err := url.UnmarshalJSON([]byte("\"https://ethereum.org\"")) err := url.UnmarshalJSON([]byte("\"https://ethereum.org\""))
if err != nil { if err != nil {
t.Errorf("unexpcted error: %v", err) t.Errorf("unexpected error: %v", err)
} }
if url.Scheme != "https" { if url.Scheme != "https" {
t.Errorf("expected: %v, got: %v", "https", url.Scheme) t.Errorf("expected: %v, got: %v", "https", url.Scheme)

View file

@ -8,6 +8,7 @@ import (
) )
func TestNameFilter(t *testing.T) { func TestNameFilter(t *testing.T) {
t.Parallel()
_, err := newNameFilter("Foo") _, err := newNameFilter("Foo")
require.Error(t, err) require.Error(t, err)
_, err = newNameFilter("too/many:colons:Foo") _, err = newNameFilter("too/many:colons:Foo")

View file

@ -26,12 +26,13 @@ import (
// TestImportRaw tests clef --importraw // TestImportRaw tests clef --importraw
func TestImportRaw(t *testing.T) { func TestImportRaw(t *testing.T) {
t.Parallel()
keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name())) keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name()))
os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777) os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777)
t.Cleanup(func() { os.Remove(keyPath) }) t.Cleanup(func() { os.Remove(keyPath) })
t.Parallel()
t.Run("happy-path", func(t *testing.T) { t.Run("happy-path", func(t *testing.T) {
t.Parallel()
// Run clef importraw // Run clef importraw
clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath) clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath)
clef.input("myverylongpassword").input("myverylongpassword") clef.input("myverylongpassword").input("myverylongpassword")
@ -43,6 +44,7 @@ func TestImportRaw(t *testing.T) {
}) })
// tests clef --importraw with mismatched passwords. // tests clef --importraw with mismatched passwords.
t.Run("pw-mismatch", func(t *testing.T) { t.Run("pw-mismatch", func(t *testing.T) {
t.Parallel()
// Run clef importraw // Run clef importraw
clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath) clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath)
clef.input("myverylongpassword1").input("myverylongpassword2").WaitExit() clef.input("myverylongpassword1").input("myverylongpassword2").WaitExit()
@ -52,6 +54,7 @@ func TestImportRaw(t *testing.T) {
}) })
// tests clef --importraw with a too short password. // tests clef --importraw with a too short password.
t.Run("short-pw", func(t *testing.T) { t.Run("short-pw", func(t *testing.T) {
t.Parallel()
// Run clef importraw // Run clef importraw
clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath) clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath)
clef.input("shorty").input("shorty").WaitExit() clef.input("shorty").input("shorty").WaitExit()
@ -64,12 +67,13 @@ func TestImportRaw(t *testing.T) {
// TestListAccounts tests clef --list-accounts // TestListAccounts tests clef --list-accounts
func TestListAccounts(t *testing.T) { func TestListAccounts(t *testing.T) {
t.Parallel()
keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name())) keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name()))
os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777) os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777)
t.Cleanup(func() { os.Remove(keyPath) }) t.Cleanup(func() { os.Remove(keyPath) })
t.Parallel()
t.Run("no-accounts", func(t *testing.T) { t.Run("no-accounts", func(t *testing.T) {
t.Parallel()
clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "list-accounts") clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "list-accounts")
if out := string(clef.Output()); !strings.Contains(out, "The keystore is empty.") { if out := string(clef.Output()); !strings.Contains(out, "The keystore is empty.") {
t.Logf("Output\n%v", out) t.Logf("Output\n%v", out)
@ -77,6 +81,7 @@ func TestListAccounts(t *testing.T) {
} }
}) })
t.Run("one-account", func(t *testing.T) { t.Run("one-account", func(t *testing.T) {
t.Parallel()
// First, we need to import // First, we need to import
clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath) clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath)
clef.input("myverylongpassword").input("myverylongpassword").WaitExit() clef.input("myverylongpassword").input("myverylongpassword").WaitExit()
@ -91,12 +96,13 @@ func TestListAccounts(t *testing.T) {
// TestListWallets tests clef --list-wallets // TestListWallets tests clef --list-wallets
func TestListWallets(t *testing.T) { func TestListWallets(t *testing.T) {
t.Parallel()
keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name())) keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name()))
os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777) os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777)
t.Cleanup(func() { os.Remove(keyPath) }) t.Cleanup(func() { os.Remove(keyPath) })
t.Parallel()
t.Run("no-accounts", func(t *testing.T) { t.Run("no-accounts", func(t *testing.T) {
t.Parallel()
clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "list-wallets") clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "list-wallets")
if out := string(clef.Output()); !strings.Contains(out, "There are no wallets.") { if out := string(clef.Output()); !strings.Contains(out, "There are no wallets.") {
t.Logf("Output\n%v", out) t.Logf("Output\n%v", out)
@ -104,6 +110,7 @@ func TestListWallets(t *testing.T) {
} }
}) })
t.Run("one-account", func(t *testing.T) { t.Run("one-account", func(t *testing.T) {
t.Parallel()
// First, we need to import // First, we need to import
clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath) clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath)
clef.input("myverylongpassword").input("myverylongpassword").WaitExit() clef.input("myverylongpassword").input("myverylongpassword").WaitExit()

View file

@ -582,6 +582,7 @@ func accountImport(c *cli.Context) error {
return err return err
} }
if first != second { if first != second {
//lint:ignore ST1005 This is a message for the user
return errors.New("Passwords do not match") return errors.New("Passwords do not match")
} }
acc, err := internalApi.ImportRawKey(hex.EncodeToString(crypto.FromECDSA(pKey)), first) acc, err := internalApi.ImportRawKey(hex.EncodeToString(crypto.FromECDSA(pKey)), first)

View file

@ -236,7 +236,7 @@ func discv4Crawl(ctx *cli.Context) error {
func discv4Test(ctx *cli.Context) error { func discv4Test(ctx *cli.Context) error {
// Configure test package globals. // Configure test package globals.
if !ctx.IsSet(remoteEnodeFlag.Name) { if !ctx.IsSet(remoteEnodeFlag.Name) {
return fmt.Errorf("Missing -%v", remoteEnodeFlag.Name) return fmt.Errorf("missing -%v", remoteEnodeFlag.Name)
} }
v4test.Remote = ctx.String(remoteEnodeFlag.Name) v4test.Remote = ctx.String(remoteEnodeFlag.Name)
v4test.Listen1 = ctx.String(testListen1Flag.Name) v4test.Listen1 = ctx.String(testListen1Flag.Name)

View file

@ -26,6 +26,7 @@ import (
// This test checks that computeChanges/splitChanges create DNS changes in // This test checks that computeChanges/splitChanges create DNS changes in
// leaf-added -> root-changed -> leaf-deleted order. // leaf-added -> root-changed -> leaf-deleted order.
func TestRoute53ChangeSort(t *testing.T) { func TestRoute53ChangeSort(t *testing.T) {
t.Parallel()
testTree0 := map[string]recordSet{ testTree0 := map[string]recordSet{
"2kfjogvxdqtxxugbh7gs7naaai.n": {ttl: 3333, values: []string{ "2kfjogvxdqtxxugbh7gs7naaai.n": {ttl: 3333, values: []string{
`"enr:-HW4QO1ml1DdXLeZLsUxewnthhUy8eROqkDyoMTyavfks9JlYQIlMFEUoM78PovJDPQrAkrb3LRJ-""vtrymDguKCOIAWAgmlkgnY0iXNlY3AyNTZrMaEDffaGfJzgGhUif1JqFruZlYmA31HzathLSWxfbq_QoQ4"`, `"enr:-HW4QO1ml1DdXLeZLsUxewnthhUy8eROqkDyoMTyavfks9JlYQIlMFEUoM78PovJDPQrAkrb3LRJ-""vtrymDguKCOIAWAgmlkgnY0iXNlY3AyNTZrMaEDffaGfJzgGhUif1JqFruZlYmA31HzathLSWxfbq_QoQ4"`,
@ -164,6 +165,7 @@ func TestRoute53ChangeSort(t *testing.T) {
// This test checks that computeChanges compares the quoted value of the records correctly. // This test checks that computeChanges compares the quoted value of the records correctly.
func TestRoute53NoChange(t *testing.T) { func TestRoute53NoChange(t *testing.T) {
t.Parallel()
// Existing record set. // Existing record set.
testTree0 := map[string]recordSet{ testTree0 := map[string]recordSet{
"n": {ttl: rootTTL, values: []string{ "n": {ttl: rootTTL, values: []string{

View file

@ -30,6 +30,7 @@ import (
// TestEthProtocolNegotiation tests whether the test suite // TestEthProtocolNegotiation tests whether the test suite
// can negotiate the highest eth protocol in a status message exchange // can negotiate the highest eth protocol in a status message exchange
func TestEthProtocolNegotiation(t *testing.T) { func TestEthProtocolNegotiation(t *testing.T) {
t.Parallel()
var tests = []struct { var tests = []struct {
conn *Conn conn *Conn
caps []p2p.Cap caps []p2p.Cap
@ -125,6 +126,7 @@ func TestEthProtocolNegotiation(t *testing.T) {
// TestChain_GetHeaders tests whether the test suite can correctly // TestChain_GetHeaders tests whether the test suite can correctly
// respond to a GetBlockHeaders request from a node. // respond to a GetBlockHeaders request from a node.
func TestChain_GetHeaders(t *testing.T) { func TestChain_GetHeaders(t *testing.T) {
t.Parallel()
chainFile, err := filepath.Abs("./testdata/chain.rlp") chainFile, err := filepath.Abs("./testdata/chain.rlp")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View file

@ -683,7 +683,7 @@ func (s *Suite) snapGetTrieNodes(t *utesting.T, tc *trieNodesTest) error {
hash := make([]byte, 32) hash := make([]byte, 32)
trienodes := res.Nodes trienodes := res.Nodes
if got, want := len(trienodes), len(tc.expHashes); got != want { if got, want := len(trienodes), len(tc.expHashes); got != want {
return fmt.Errorf("wrong trienode count, got %d, want %d\n", got, want) return fmt.Errorf("wrong trienode count, got %d, want %d", got, want)
} }
for i, trienode := range trienodes { for i, trienode := range trienodes {
hasher.Reset() hasher.Reset()

View file

@ -35,6 +35,7 @@ var (
) )
func TestEthSuite(t *testing.T) { func TestEthSuite(t *testing.T) {
t.Parallel()
geth, err := runGeth() geth, err := runGeth()
if err != nil { if err != nil {
t.Fatalf("could not run geth: %v", err) t.Fatalf("could not run geth: %v", err)
@ -56,6 +57,7 @@ func TestEthSuite(t *testing.T) {
} }
func TestSnapSuite(t *testing.T) { func TestSnapSuite(t *testing.T) {
t.Parallel()
geth, err := runGeth() geth, err := runGeth()
if err != nil { if err != nil {
t.Fatalf("could not run geth: %v", err) t.Fatalf("could not run geth: %v", err)

View file

@ -22,6 +22,7 @@ import (
) )
func TestMessageSignVerify(t *testing.T) { func TestMessageSignVerify(t *testing.T) {
t.Parallel()
tmpdir := t.TempDir() tmpdir := t.TempDir()
keyfile := filepath.Join(tmpdir, "the-keyfile") keyfile := filepath.Join(tmpdir, "the-keyfile")

View file

@ -40,7 +40,7 @@ var RunFlag = &cli.StringFlag{
var blockTestCommand = &cli.Command{ var blockTestCommand = &cli.Command{
Action: blockTestCmd, Action: blockTestCmd,
Name: "blocktest", Name: "blocktest",
Usage: "executes the given blockchain tests", Usage: "Executes the given blockchain tests",
ArgsUsage: "<file>", ArgsUsage: "<file>",
Flags: []cli.Flag{RunFlag}, Flags: []cli.Flag{RunFlag},
} }

View file

@ -29,7 +29,7 @@ import (
var compileCommand = &cli.Command{ var compileCommand = &cli.Command{
Action: compileCmd, Action: compileCmd,
Name: "compile", Name: "compile",
Usage: "compiles easm source to evm binary", Usage: "Compiles easm source to evm binary",
ArgsUsage: "<file>", ArgsUsage: "<file>",
} }

View file

@ -29,7 +29,7 @@ import (
var disasmCommand = &cli.Command{ var disasmCommand = &cli.Command{
Action: disasmCmd, Action: disasmCmd,
Name: "disasm", Name: "disasm",
Usage: "disassembles evm binary", Usage: "Disassembles evm binary",
ArgsUsage: "<file>", ArgsUsage: "<file>",
} }

View file

@ -139,7 +139,7 @@ var (
var stateTransitionCommand = &cli.Command{ var stateTransitionCommand = &cli.Command{
Name: "transition", Name: "transition",
Aliases: []string{"t8n"}, Aliases: []string{"t8n"},
Usage: "executes a full state transition", Usage: "Executes a full state transition",
Action: t8ntool.Transition, Action: t8ntool.Transition,
Flags: []cli.Flag{ Flags: []cli.Flag{
t8ntool.TraceFlag, t8ntool.TraceFlag,
@ -165,7 +165,7 @@ var stateTransitionCommand = &cli.Command{
var transactionCommand = &cli.Command{ var transactionCommand = &cli.Command{
Name: "transaction", Name: "transaction",
Aliases: []string{"t9n"}, Aliases: []string{"t9n"},
Usage: "performs transaction validation", Usage: "Performs transaction validation",
Action: t8ntool.Transaction, Action: t8ntool.Transaction,
Flags: []cli.Flag{ Flags: []cli.Flag{
t8ntool.InputTxsFlag, t8ntool.InputTxsFlag,
@ -178,7 +178,7 @@ var transactionCommand = &cli.Command{
var blockBuilderCommand = &cli.Command{ var blockBuilderCommand = &cli.Command{
Name: "block-builder", Name: "block-builder",
Aliases: []string{"b11r"}, Aliases: []string{"b11r"},
Usage: "builds a block", Usage: "Builds a block",
Action: t8ntool.BuildBlock, Action: t8ntool.BuildBlock,
Flags: []cli.Flag{ Flags: []cli.Flag{
t8ntool.OutputBasedir, t8ntool.OutputBasedir,

View file

@ -46,7 +46,7 @@ import (
var runCommand = &cli.Command{ var runCommand = &cli.Command{
Action: runCmd, Action: runCmd,
Name: "run", Name: "run",
Usage: "run arbitrary evm binary", Usage: "Run arbitrary evm binary",
ArgsUsage: "<code>", ArgsUsage: "<code>",
Description: `The run command runs arbitrary EVM code.`, Description: `The run command runs arbitrary EVM code.`,
Flags: flags.Merge(vmFlags, traceFlags), Flags: flags.Merge(vmFlags, traceFlags),

View file

@ -106,6 +106,7 @@ func (args *t8nOutput) get() (out []string) {
} }
func TestT8n(t *testing.T) { func TestT8n(t *testing.T) {
t.Parallel()
tt := new(testT8n) tt := new(testT8n)
tt.TestCmd = cmdtest.NewTestCmd(t, tt) tt.TestCmd = cmdtest.NewTestCmd(t, tt)
for i, tc := range []struct { for i, tc := range []struct {
@ -338,6 +339,7 @@ func (args *t9nInput) get(base string) []string {
} }
func TestT9n(t *testing.T) { func TestT9n(t *testing.T) {
t.Parallel()
tt := new(testT8n) tt := new(testT8n)
tt.TestCmd = cmdtest.NewTestCmd(t, tt) tt.TestCmd = cmdtest.NewTestCmd(t, tt)
for i, tc := range []struct { for i, tc := range []struct {
@ -473,6 +475,7 @@ func (args *b11rInput) get(base string) []string {
} }
func TestB11r(t *testing.T) { func TestB11r(t *testing.T) {
t.Parallel()
tt := new(testT8n) tt := new(testT8n)
tt.TestCmd = cmdtest.NewTestCmd(t, tt) tt.TestCmd = cmdtest.NewTestCmd(t, tt)
for i, tc := range []struct { for i, tc := range []struct {

View file

@ -249,7 +249,7 @@ func newFaucet(genesis *core.Genesis, port int, enodes []*enode.Node, network ui
lesBackend, err := les.New(stack, &cfg) lesBackend, err := les.New(stack, &cfg)
if err != nil { if err != nil {
return nil, fmt.Errorf("Failed to register the Ethereum service: %w", err) return nil, fmt.Errorf("failed to register the Ethereum service: %w", err)
} }
// Assemble the ethstats monitoring and reporting service' // Assemble the ethstats monitoring and reporting service'

View file

@ -23,6 +23,7 @@ import (
) )
func TestFacebook(t *testing.T) { func TestFacebook(t *testing.T) {
t.Parallel()
// TODO: Remove facebook auth or implement facebook api, which seems to require an API key // TODO: Remove facebook auth or implement facebook api, which seems to require an API key
t.Skipf("The facebook access is flaky, needs to be reimplemented or removed") t.Skipf("The facebook access is flaky, needs to be reimplemented or removed")
for _, tt := range []struct { for _, tt := range []struct {

View file

@ -43,11 +43,13 @@ func tmpDatadirWithKeystore(t *testing.T) string {
} }
func TestAccountListEmpty(t *testing.T) { func TestAccountListEmpty(t *testing.T) {
t.Parallel()
geth := runGeth(t, "account", "list") geth := runGeth(t, "account", "list")
geth.ExpectExit() geth.ExpectExit()
} }
func TestAccountList(t *testing.T) { func TestAccountList(t *testing.T) {
t.Parallel()
datadir := tmpDatadirWithKeystore(t) datadir := tmpDatadirWithKeystore(t)
var want = ` var want = `
Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8
@ -74,6 +76,7 @@ Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}\k
} }
func TestAccountNew(t *testing.T) { func TestAccountNew(t *testing.T) {
t.Parallel()
geth := runGeth(t, "account", "new", "--lightkdf") geth := runGeth(t, "account", "new", "--lightkdf")
defer geth.ExpectExit() defer geth.ExpectExit()
geth.Expect(` geth.Expect(`
@ -96,6 +99,7 @@ Path of the secret key file: .*UTC--.+--[0-9a-f]{40}
} }
func TestAccountImport(t *testing.T) { func TestAccountImport(t *testing.T) {
t.Parallel()
tests := []struct{ name, key, output string }{ tests := []struct{ name, key, output string }{
{ {
name: "correct account", name: "correct account",
@ -118,6 +122,7 @@ func TestAccountImport(t *testing.T) {
} }
func TestAccountHelp(t *testing.T) { func TestAccountHelp(t *testing.T) {
t.Parallel()
geth := runGeth(t, "account", "-h") geth := runGeth(t, "account", "-h")
geth.WaitExit() geth.WaitExit()
if have, want := geth.ExitStatus(), 0; have != want { if have, want := geth.ExitStatus(), 0; have != want {
@ -147,6 +152,7 @@ func importAccountWithExpect(t *testing.T, key string, expected string) {
} }
func TestAccountNewBadRepeat(t *testing.T) { func TestAccountNewBadRepeat(t *testing.T) {
t.Parallel()
geth := runGeth(t, "account", "new", "--lightkdf") geth := runGeth(t, "account", "new", "--lightkdf")
defer geth.ExpectExit() defer geth.ExpectExit()
geth.Expect(` geth.Expect(`
@ -159,6 +165,7 @@ Fatal: Passwords do not match
} }
func TestAccountUpdate(t *testing.T) { func TestAccountUpdate(t *testing.T) {
t.Parallel()
datadir := tmpDatadirWithKeystore(t) datadir := tmpDatadirWithKeystore(t)
geth := runGeth(t, "account", "update", geth := runGeth(t, "account", "update",
"--datadir", datadir, "--lightkdf", "--datadir", datadir, "--lightkdf",
@ -175,6 +182,7 @@ Repeat password: {{.InputLine "foobar2"}}
} }
func TestWalletImport(t *testing.T) { func TestWalletImport(t *testing.T) {
t.Parallel()
geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json") geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
defer geth.ExpectExit() defer geth.ExpectExit()
geth.Expect(` geth.Expect(`
@ -190,6 +198,7 @@ Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f}
} }
func TestWalletImportBadPassword(t *testing.T) { func TestWalletImportBadPassword(t *testing.T) {
t.Parallel()
geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json") geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
defer geth.ExpectExit() defer geth.ExpectExit()
geth.Expect(` geth.Expect(`
@ -200,6 +209,7 @@ Fatal: could not decrypt key with given password
} }
func TestUnlockFlag(t *testing.T) { func TestUnlockFlag(t *testing.T) {
t.Parallel()
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "console", "--exec", "loadScript('testdata/empty.js')") "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "console", "--exec", "loadScript('testdata/empty.js')")
geth.Expect(` geth.Expect(`
@ -222,6 +232,7 @@ undefined
} }
func TestUnlockFlagWrongPassword(t *testing.T) { func TestUnlockFlagWrongPassword(t *testing.T) {
t.Parallel()
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "console", "--exec", "loadScript('testdata/empty.js')") "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "console", "--exec", "loadScript('testdata/empty.js')")
@ -240,6 +251,7 @@ Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could
// https://github.com/ethereum/go-ethereum/issues/1785 // https://github.com/ethereum/go-ethereum/issues/1785
func TestUnlockFlagMultiIndex(t *testing.T) { func TestUnlockFlagMultiIndex(t *testing.T) {
t.Parallel()
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--unlock", "0,2", "console", "--exec", "loadScript('testdata/empty.js')") "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--unlock", "0,2", "console", "--exec", "loadScript('testdata/empty.js')")
@ -266,6 +278,7 @@ undefined
} }
func TestUnlockFlagPasswordFile(t *testing.T) { func TestUnlockFlagPasswordFile(t *testing.T) {
t.Parallel()
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--password", "testdata/passwords.txt", "--unlock", "0,2", "console", "--exec", "loadScript('testdata/empty.js')") "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--password", "testdata/passwords.txt", "--unlock", "0,2", "console", "--exec", "loadScript('testdata/empty.js')")
@ -287,6 +300,7 @@ undefined
} }
func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) { func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) {
t.Parallel()
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--password", "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--password",
"testdata/wrong-passwords.txt", "--unlock", "0,2") "testdata/wrong-passwords.txt", "--unlock", "0,2")
@ -297,6 +311,7 @@ Fatal: Failed to unlock account 0 (could not decrypt key with given password)
} }
func TestUnlockFlagAmbiguous(t *testing.T) { func TestUnlockFlagAmbiguous(t *testing.T) {
t.Parallel()
store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes") store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--keystore", "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--keystore",
@ -336,6 +351,7 @@ undefined
} }
func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) { func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) {
t.Parallel()
store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes") store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--keystore", "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--keystore",

View file

@ -224,14 +224,21 @@ func initGenesis(ctx *cli.Context) error {
} }
func dumpGenesis(ctx *cli.Context) error { func dumpGenesis(ctx *cli.Context) error {
// if there is a testnet preset enabled, dump that // check if there is a testnet preset enabled
var genesis *core.Genesis
if utils.IsNetworkPreset(ctx) { if utils.IsNetworkPreset(ctx) {
genesis := utils.MakeGenesis(ctx) genesis = utils.MakeGenesis(ctx)
} else if ctx.IsSet(utils.DeveloperFlag.Name) && !ctx.IsSet(utils.DataDirFlag.Name) {
genesis = core.DeveloperGenesisBlock(11_500_000, nil)
}
if genesis != nil {
if err := json.NewEncoder(os.Stdout).Encode(genesis); err != nil { if err := json.NewEncoder(os.Stdout).Encode(genesis); err != nil {
utils.Fatalf("could not encode genesis: %s", err) utils.Fatalf("could not encode genesis: %s", err)
} }
return nil return nil
} }
// dump whatever already exists in the datadir // dump whatever already exists in the datadir
stack, _ := makeConfigNode(ctx) stack, _ := makeConfigNode(ctx)
for _, name := range []string{"chaindata", "lightchaindata"} { for _, name := range []string{"chaindata", "lightchaindata"} {
@ -256,7 +263,7 @@ func dumpGenesis(ctx *cli.Context) error {
if ctx.IsSet(utils.DataDirFlag.Name) { if ctx.IsSet(utils.DataDirFlag.Name) {
utils.Fatalf("no existing datadir at %s", stack.Config().DataDir) utils.Fatalf("no existing datadir at %s", stack.Config().DataDir)
} }
utils.Fatalf("no network preset provided, no existing genesis in the default datadir") utils.Fatalf("no network preset provided, and no genesis exists in the default datadir")
return nil return nil
} }

View file

@ -50,6 +50,7 @@ func runMinimalGeth(t *testing.T, args ...string) *testgeth {
// Tests that a node embedded within a console can be started up properly and // Tests that a node embedded within a console can be started up properly and
// then terminated by closing the input stream. // then terminated by closing the input stream.
func TestConsoleWelcome(t *testing.T) { func TestConsoleWelcome(t *testing.T) {
t.Parallel()
coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182"
// Start a geth console, make sure it's cleaned up and terminate the console // Start a geth console, make sure it's cleaned up and terminate the console

View file

@ -27,6 +27,7 @@ import (
// TestExport does a basic test of "geth export", exporting the test-genesis. // TestExport does a basic test of "geth export", exporting the test-genesis.
func TestExport(t *testing.T) { func TestExport(t *testing.T) {
t.Parallel()
outfile := fmt.Sprintf("%v/testExport.out", os.TempDir()) outfile := fmt.Sprintf("%v/testExport.out", os.TempDir())
defer os.Remove(outfile) defer os.Remove(outfile)
geth := runGeth(t, "--datadir", initGeth(t), "export", outfile) geth := runGeth(t, "--datadir", initGeth(t), "export", outfile)

View file

@ -156,6 +156,7 @@ func startClient(t *testing.T, name string) *gethrpc {
} }
func TestPriorityClient(t *testing.T) { func TestPriorityClient(t *testing.T) {
t.Parallel()
lightServer := startLightServer(t) lightServer := startLightServer(t)
defer lightServer.killAndWait() defer lightServer.killAndWait()

View file

@ -58,6 +58,7 @@ func censor(input string, start, end int) string {
} }
func TestLogging(t *testing.T) { func TestLogging(t *testing.T) {
t.Parallel()
testConsoleLogging(t, "terminal", 6, 24) testConsoleLogging(t, "terminal", 6, 24)
testConsoleLogging(t, "logfmt", 2, 26) testConsoleLogging(t, "logfmt", 2, 26)
} }
@ -98,6 +99,7 @@ func testConsoleLogging(t *testing.T, format string, tStart, tEnd int) {
} }
func TestVmodule(t *testing.T) { func TestVmodule(t *testing.T) {
t.Parallel()
checkOutput := func(level int, want, wantNot string) { checkOutput := func(level int, want, wantNot string) {
t.Helper() t.Helper()
output, err := runSelf("--log.format", "terminal", "--verbosity=0", "--log.vmodule", fmt.Sprintf("logtestcmd_active.go=%d", level), "logtest") output, err := runSelf("--log.format", "terminal", "--verbosity=0", "--log.vmodule", fmt.Sprintf("logtestcmd_active.go=%d", level), "logtest")
@ -145,6 +147,7 @@ func nicediff(have, want []byte) string {
} }
func TestFileOut(t *testing.T) { func TestFileOut(t *testing.T) {
t.Parallel()
var ( var (
have, want []byte have, want []byte
err error err error
@ -165,6 +168,7 @@ func TestFileOut(t *testing.T) {
} }
func TestRotatingFileOut(t *testing.T) { func TestRotatingFileOut(t *testing.T) {
t.Parallel()
var ( var (
have, want []byte have, want []byte
err error err error

View file

@ -30,14 +30,17 @@ import (
) )
func TestVerification(t *testing.T) { func TestVerification(t *testing.T) {
t.Parallel()
// Signatures generated with `minisign`. Legacy format, not pre-hashed file. // Signatures generated with `minisign`. Legacy format, not pre-hashed file.
t.Run("minisig-legacy", func(t *testing.T) { t.Run("minisig-legacy", func(t *testing.T) {
t.Parallel()
// For this test, the pubkey is in testdata/vcheck/minisign.pub // For this test, the pubkey is in testdata/vcheck/minisign.pub
// (the privkey is `minisign.sec`, if we want to expand this test. Password 'test' ) // (the privkey is `minisign.sec`, if we want to expand this test. Password 'test' )
pub := "RWQkliYstQBOKOdtClfgC3IypIPX6TAmoEi7beZ4gyR3wsaezvqOMWsp" pub := "RWQkliYstQBOKOdtClfgC3IypIPX6TAmoEi7beZ4gyR3wsaezvqOMWsp"
testVerification(t, pub, "./testdata/vcheck/minisig-sigs/") testVerification(t, pub, "./testdata/vcheck/minisig-sigs/")
}) })
t.Run("minisig-new", func(t *testing.T) { t.Run("minisig-new", func(t *testing.T) {
t.Parallel()
// For this test, the pubkey is in testdata/vcheck/minisign.pub // For this test, the pubkey is in testdata/vcheck/minisign.pub
// (the privkey is `minisign.sec`, if we want to expand this test. Password 'test' ) // (the privkey is `minisign.sec`, if we want to expand this test. Password 'test' )
// `minisign -S -s ./minisign.sec -m data.json -x ./minisig-sigs-new/data.json.minisig` // `minisign -S -s ./minisign.sec -m data.json -x ./minisig-sigs-new/data.json.minisig`
@ -46,6 +49,7 @@ func TestVerification(t *testing.T) {
}) })
// Signatures generated with `signify-openbsd` // Signatures generated with `signify-openbsd`
t.Run("signify-openbsd", func(t *testing.T) { t.Run("signify-openbsd", func(t *testing.T) {
t.Parallel()
t.Skip("This currently fails, minisign expects 4 lines of data, signify provides only 2") t.Skip("This currently fails, minisign expects 4 lines of data, signify provides only 2")
// For this test, the pubkey is in testdata/vcheck/signifykey.pub // For this test, the pubkey is in testdata/vcheck/signifykey.pub
// (the privkey is `signifykey.sec`, if we want to expand this test. Password 'test' ) // (the privkey is `signifykey.sec`, if we want to expand this test. Password 'test' )
@ -97,6 +101,7 @@ func versionUint(v string) int {
// TestMatching can be used to check that the regexps are correct // TestMatching can be used to check that the regexps are correct
func TestMatching(t *testing.T) { func TestMatching(t *testing.T) {
t.Parallel()
data, _ := os.ReadFile("./testdata/vcheck/vulnerabilities.json") data, _ := os.ReadFile("./testdata/vcheck/vulnerabilities.json")
var vulns []vulnJson var vulns []vulnJson
if err := json.Unmarshal(data, &vulns); err != nil { if err := json.Unmarshal(data, &vulns); err != nil {
@ -141,6 +146,7 @@ func TestMatching(t *testing.T) {
} }
func TestGethPubKeysParseable(t *testing.T) { func TestGethPubKeysParseable(t *testing.T) {
t.Parallel()
for _, pubkey := range gethPubKeys { for _, pubkey := range gethPubKeys {
_, err := minisign.NewPublicKey(pubkey) _, err := minisign.NewPublicKey(pubkey)
if err != nil { if err != nil {
@ -150,6 +156,7 @@ func TestGethPubKeysParseable(t *testing.T) {
} }
func TestKeyID(t *testing.T) { func TestKeyID(t *testing.T) {
t.Parallel()
type args struct { type args struct {
id [8]byte id [8]byte
} }
@ -163,7 +170,9 @@ func TestKeyID(t *testing.T) {
{"third key", args{id: extractKeyId(gethPubKeys[2])}, "FD9813B2D2098484"}, {"third key", args{id: extractKeyId(gethPubKeys[2])}, "FD9813B2D2098484"},
} }
for _, tt := range tests { for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := keyID(tt.args.id); got != tt.want { if got := keyID(tt.args.id); got != tt.want {
t.Errorf("keyID() = %v, want %v", got, tt.want) t.Errorf("keyID() = %v, want %v", got, tt.want)
} }

View file

@ -417,9 +417,7 @@ func rpcNode(ctx *cli.Context) error {
} }
func rpcSubscribe(client *rpc.Client, out io.Writer, method string, args ...string) error { func rpcSubscribe(client *rpc.Client, out io.Writer, method string, args ...string) error {
parts := strings.SplitN(method, "_", 2) namespace, method, _ := strings.Cut(method, "_")
namespace := parts[0]
method = parts[1]
ch := make(chan interface{}) ch := make(chan interface{})
subArgs := make([]interface{}, len(args)+1) subArgs := make([]interface{}, len(args)+1)
subArgs[0] = method subArgs[0] = method

View file

@ -27,6 +27,7 @@ import (
) )
func TestRoundtrip(t *testing.T) { func TestRoundtrip(t *testing.T) {
t.Parallel()
for i, want := range []string{ for i, want := range []string{
"0xf880806482520894d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0a1010000000000000000000000000000000000000000000000000000000000000001801ba0c16787a8e25e941d67691954642876c08f00996163ae7dfadbbfd6cd436f549da06180e5626cae31590f40641fe8f63734316c4bfeb4cdfab6714198c1044d2e28", "0xf880806482520894d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0a1010000000000000000000000000000000000000000000000000000000000000001801ba0c16787a8e25e941d67691954642876c08f00996163ae7dfadbbfd6cd436f549da06180e5626cae31590f40641fe8f63734316c4bfeb4cdfab6714198c1044d2e28",
"0xd5c0d3cb84746573742a2a808213378667617a6f6e6b", "0xd5c0d3cb84746573742a2a808213378667617a6f6e6b",
@ -51,6 +52,7 @@ func TestRoundtrip(t *testing.T) {
} }
func TestTextToRlp(t *testing.T) { func TestTextToRlp(t *testing.T) {
t.Parallel()
type tc struct { type tc struct {
text string text string
want string want string

View file

@ -460,7 +460,7 @@ func ImportLDBData(db ethdb.Database, f string, startIndex int64, interrupt chan
case OpBatchAdd: case OpBatchAdd:
batch.Put(key, val) batch.Put(key, val)
default: default:
return fmt.Errorf("unknown op %d\n", op) return fmt.Errorf("unknown op %d", op)
} }
if batch.ValueSize() > ethdb.IdealBatchSize { if batch.ValueSize() > ethdb.IdealBatchSize {
if err := batch.Write(); err != nil { if err := batch.Write(); err != nil {

View file

@ -170,6 +170,7 @@ func testDeletion(t *testing.T, f string) {
// TestImportFutureFormat tests that we reject unsupported future versions. // TestImportFutureFormat tests that we reject unsupported future versions.
func TestImportFutureFormat(t *testing.T) { func TestImportFutureFormat(t *testing.T) {
t.Parallel()
f := fmt.Sprintf("%v/tempdump-future", os.TempDir()) f := fmt.Sprintf("%v/tempdump-future", os.TempDir())
defer func() { defer func() {
os.Remove(f) os.Remove(f)

View file

@ -1872,11 +1872,26 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
log.Info("Using developer account", "address", developer.Address) log.Info("Using developer account", "address", developer.Address)
// Create a new developer genesis block or reuse existing one // Create a new developer genesis block or reuse existing one
cfg.Genesis = core.DeveloperGenesisBlock(ctx.Uint64(DeveloperGasLimitFlag.Name), developer.Address) cfg.Genesis = core.DeveloperGenesisBlock(ctx.Uint64(DeveloperGasLimitFlag.Name), &developer.Address)
if ctx.IsSet(DataDirFlag.Name) { if ctx.IsSet(DataDirFlag.Name) {
chaindb := tryMakeReadOnlyDatabase(ctx, stack) chaindb := tryMakeReadOnlyDatabase(ctx, stack)
if rawdb.ReadCanonicalHash(chaindb, 0) != (common.Hash{}) { if rawdb.ReadCanonicalHash(chaindb, 0) != (common.Hash{}) {
cfg.Genesis = nil // fallback to db content cfg.Genesis = nil // fallback to db content
//validate genesis has PoS enabled in block 0
genesis, err := core.ReadGenesis(chaindb)
if err != nil {
Fatalf("Could not read genesis from database: %v", err)
}
if !genesis.Config.TerminalTotalDifficultyPassed {
Fatalf("Bad developer-mode genesis configuration: terminalTotalDifficultyPassed must be true in developer mode")
}
if genesis.Config.TerminalTotalDifficulty == nil {
Fatalf("Bad developer-mode genesis configuration: terminalTotalDifficulty must be specified.")
}
if genesis.Difficulty.Cmp(genesis.Config.TerminalTotalDifficulty) != 1 {
Fatalf("Bad developer-mode genesis configuration: genesis block difficulty must be > terminalTotalDifficulty")
}
} }
chaindb.Close() chaindb.Close()
} }

View file

@ -23,6 +23,7 @@ import (
) )
func Test_SplitTagsFlag(t *testing.T) { func Test_SplitTagsFlag(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
name string name string
args string args string
@ -55,7 +56,9 @@ func Test_SplitTagsFlag(t *testing.T) {
}, },
} }
for _, tt := range tests { for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := SplitTagsFlag(tt.args); !reflect.DeepEqual(got, tt.want) { if got := SplitTagsFlag(tt.args); !reflect.DeepEqual(got, tt.want) {
t.Errorf("splitTagsFlag() = %v, want %v", got, tt.want) t.Errorf("splitTagsFlag() = %v, want %v", got, tt.want)
} }

View file

@ -22,6 +22,7 @@ import (
) )
func TestGetPassPhraseWithList(t *testing.T) { func TestGetPassPhraseWithList(t *testing.T) {
t.Parallel()
type args struct { type args struct {
text string text string
confirmation bool confirmation bool
@ -65,7 +66,9 @@ func TestGetPassPhraseWithList(t *testing.T) {
}, },
} }
for _, tt := range tests { for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := GetPassPhraseWithList(tt.args.text, tt.args.confirmation, tt.args.index, tt.args.passwords); got != tt.want { if got := GetPassPhraseWithList(tt.args.text, tt.args.confirmation, tt.args.index, tt.args.passwords); got != tt.want {
t.Errorf("GetPassPhraseWithList() = %v, want %v", got, tt.want) t.Errorf("GetPassPhraseWithList() = %v, want %v", got, tt.want)
} }

View file

@ -78,7 +78,7 @@ func (b *bridge) NewAccount(call jsre.Call) (goja.Value, error) {
return nil, err return nil, err
} }
if password != confirm { if password != confirm {
return nil, errors.New("passwords don't match!") return nil, errors.New("passwords don't match")
} }
// A single string password was specified, use that // A single string password was specified, use that
case len(call.Arguments) == 1 && call.Argument(0).ToString() != nil: case len(call.Arguments) == 1 && call.Argument(0).ToString() != nil:

View file

@ -94,7 +94,7 @@ func newTester(t *testing.T, confOverride func(*ethconfig.Config)) *tester {
t.Fatalf("failed to create node: %v", err) t.Fatalf("failed to create node: %v", err)
} }
ethConf := &ethconfig.Config{ ethConf := &ethconfig.Config{
Genesis: core.DeveloperGenesisBlock(11_500_000, common.Address{}), Genesis: core.DeveloperGenesisBlock(11_500_000, nil),
Miner: miner.Config{ Miner: miner.Config{
Etherbase: common.HexToAddress(testAddress), Etherbase: common.HexToAddress(testAddress),
}, },

View file

@ -366,8 +366,9 @@ func TestValidation(t *testing.T) {
// TODO(karalabe): Enable this when Cancun is specced // TODO(karalabe): Enable this when Cancun is specced
//{params.MainnetChainConfig, 20999999, 1677999999, ID{Hash: checksumToBytes(0x71147644), Next: 1678000000}, ErrLocalIncompatibleOrStale}, //{params.MainnetChainConfig, 20999999, 1677999999, ID{Hash: checksumToBytes(0x71147644), Next: 1678000000}, ErrLocalIncompatibleOrStale},
} }
genesis := core.DefaultGenesisBlock().ToBlock()
for i, tt := range tests { for i, tt := range tests {
filter := newFilter(tt.config, core.DefaultGenesisBlock().ToBlock(), func() (uint64, uint64) { return tt.head, tt.time }) filter := newFilter(tt.config, genesis, func() (uint64, uint64) { return tt.head, tt.time })
if err := filter(tt.id); err != tt.err { if err := filter(tt.id); err != tt.err {
t.Errorf("test %d: validation error mismatch: have %v, want %v", i, err, tt.err) t.Errorf("test %d: validation error mismatch: have %v, want %v", i, err, tt.err)
} }

View file

@ -580,16 +580,16 @@ func DefaultHoleskyGenesisBlock() *Genesis {
} }
// DeveloperGenesisBlock returns the 'geth --dev' genesis block. // DeveloperGenesisBlock returns the 'geth --dev' genesis block.
func DeveloperGenesisBlock(gasLimit uint64, faucet common.Address) *Genesis { func DeveloperGenesisBlock(gasLimit uint64, faucet *common.Address) *Genesis {
// Override the default period to the user requested one // Override the default period to the user requested one
config := *params.AllDevChainProtocolChanges config := *params.AllDevChainProtocolChanges
// Assemble and return the genesis with the precompiles and faucet pre-funded // Assemble and return the genesis with the precompiles and faucet pre-funded
return &Genesis{ genesis := &Genesis{
Config: &config, Config: &config,
GasLimit: gasLimit, GasLimit: gasLimit,
BaseFee: big.NewInt(params.InitialBaseFee), BaseFee: big.NewInt(params.InitialBaseFee),
Difficulty: big.NewInt(0), Difficulty: big.NewInt(1),
Alloc: map[common.Address]GenesisAccount{ Alloc: map[common.Address]GenesisAccount{
common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover
common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256 common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256
@ -600,9 +600,12 @@ func DeveloperGenesisBlock(gasLimit uint64, faucet common.Address) *Genesis {
common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul
common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing
common.BytesToAddress([]byte{9}): {Balance: big.NewInt(1)}, // BLAKE2b common.BytesToAddress([]byte{9}): {Balance: big.NewInt(1)}, // BLAKE2b
faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
}, },
} }
if faucet != nil {
genesis.Alloc[*faucet] = GenesisAccount{Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))}
}
return genesis
} }
func decodePrealloc(data string) GenesisAlloc { func decodePrealloc(data string) GenesisAlloc {

View file

@ -446,7 +446,7 @@ func (dl *diskLayer) generateRange(ctx *generatorContext, trieId *trie.ID, prefi
// Trie errors should never happen. Still, in case of a bug, expose the // Trie errors should never happen. Still, in case of a bug, expose the
// error here, as the outer code will presume errors are interrupts, not // error here, as the outer code will presume errors are interrupts, not
// some deeper issues. // some deeper issues.
log.Error("State snapshotter failed to iterate trie", "err", err) log.Error("State snapshotter failed to iterate trie", "err", iter.Err)
return false, nil, iter.Err return false, nil, iter.Err
} }
// Delete all stale snapshot states remaining // Delete all stale snapshot states remaining

View file

@ -426,10 +426,12 @@ func (test *snapshotTest) run() bool {
state, _ = New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) state, _ = New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
snapshotRevs = make([]int, len(test.snapshots)) snapshotRevs = make([]int, len(test.snapshots))
sindex = 0 sindex = 0
checkstates = make([]*StateDB, len(test.snapshots))
) )
for i, action := range test.actions { for i, action := range test.actions {
if len(test.snapshots) > sindex && i == test.snapshots[sindex] { if len(test.snapshots) > sindex && i == test.snapshots[sindex] {
snapshotRevs[sindex] = state.Snapshot() snapshotRevs[sindex] = state.Snapshot()
checkstates[sindex] = state.Copy()
sindex++ sindex++
} }
action.fn(action, state) action.fn(action, state)
@ -437,12 +439,8 @@ func (test *snapshotTest) run() bool {
// Revert all snapshots in reverse order. Each revert must yield a state // Revert all snapshots in reverse order. Each revert must yield a state
// that is equivalent to fresh state with all actions up the snapshot applied. // that is equivalent to fresh state with all actions up the snapshot applied.
for sindex--; sindex >= 0; sindex-- { for sindex--; sindex >= 0; sindex-- {
checkstate, _ := New(types.EmptyRootHash, state.Database(), nil)
for _, action := range test.actions[:test.snapshots[sindex]] {
action.fn(action, checkstate)
}
state.RevertToSnapshot(snapshotRevs[sindex]) state.RevertToSnapshot(snapshotRevs[sindex])
if err := test.checkEqual(state, checkstate); err != nil { if err := test.checkEqual(state, checkstates[sindex]); err != nil {
test.err = fmt.Errorf("state mismatch after revert to snapshot %d\n%v", sindex, err) test.err = fmt.Errorf("state mismatch after revert to snapshot %d\n%v", sindex, err)
return false return false
} }

View file

@ -959,6 +959,9 @@ func (pool *LegacyPool) addRemoteSync(tx *types.Transaction) error {
// If sync is set, the method will block until all internal maintenance related // If sync is set, the method will block until all internal maintenance related
// to the add is finished. Only use this during tests for determinism! // to the add is finished. Only use this during tests for determinism!
func (pool *LegacyPool) Add(txs []*types.Transaction, local, sync bool) []error { func (pool *LegacyPool) Add(txs []*types.Transaction, local, sync bool) []error {
// Do not treat as local if local transactions have been disabled
local = local && !pool.config.NoLocals
// Filter out known ones without obtaining the pool lock or recovering signatures // Filter out known ones without obtaining the pool lock or recovering signatures
var ( var (
errs = make([]error, len(txs)) errs = make([]error, len(txs))

View file

@ -1492,6 +1492,50 @@ func TestRepricing(t *testing.T) {
} }
} }
func TestMinGasPriceEnforced(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(eip1559Config, 10000000, statedb, new(event.Feed))
txPoolConfig := DefaultConfig
txPoolConfig.NoLocals = true
pool := New(txPoolConfig, blockchain)
pool.Init(new(big.Int).SetUint64(txPoolConfig.PriceLimit), blockchain.CurrentBlock(), makeAddressReserver())
defer pool.Close()
key, _ := crypto.GenerateKey()
testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000))
tx := pricedTransaction(0, 100000, big.NewInt(2), key)
pool.SetGasTip(big.NewInt(tx.GasPrice().Int64() + 1))
if err := pool.addLocal(tx); !errors.Is(err, txpool.ErrUnderpriced) {
t.Fatalf("Min tip not enforced")
}
if err := pool.Add([]*types.Transaction{tx}, true, false)[0]; !errors.Is(err, txpool.ErrUnderpriced) {
t.Fatalf("Min tip not enforced")
}
tx = dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), key)
pool.SetGasTip(big.NewInt(tx.GasTipCap().Int64() + 1))
if err := pool.addLocal(tx); !errors.Is(err, txpool.ErrUnderpriced) {
t.Fatalf("Min tip not enforced")
}
if err := pool.Add([]*types.Transaction{tx}, true, false)[0]; !errors.Is(err, txpool.ErrUnderpriced) {
t.Fatalf("Min tip not enforced")
}
// Make sure the tx is accepted if locals are enabled
pool.config.NoLocals = false
if err := pool.Add([]*types.Transaction{tx}, true, false)[0]; err != nil {
t.Fatalf("Min tip enforced with locals enabled, error: %v", err)
}
}
// Tests that setting the transaction pool gas price to a higher value correctly // Tests that setting the transaction pool gas price to a higher value correctly
// discards everything cheaper (legacy & dynamic fee) than that and moves any // discards everything cheaper (legacy & dynamic fee) than that and moves any
// gapped transactions back from the pending pool to the queue. // gapped transactions back from the pending pool to the queue.

View file

@ -37,6 +37,9 @@ var (
ErrTxTypeNotSupported = errors.New("transaction type not supported") ErrTxTypeNotSupported = errors.New("transaction type not supported")
ErrGasFeeCapTooLow = errors.New("fee cap less than base fee") ErrGasFeeCapTooLow = errors.New("fee cap less than base fee")
errShortTypedTx = errors.New("typed transaction too short") errShortTypedTx = errors.New("typed transaction too short")
errInvalidYParity = errors.New("'yParity' field must be 0 or 1")
errVYParityMismatch = errors.New("'v' and 'yParity' fields do not match")
errVYParityMissing = errors.New("missing 'yParity' or 'v' field in transaction")
) )
// Transaction types. // Transaction types.

View file

@ -57,18 +57,18 @@ func (tx *txJSON) yParityValue() (*big.Int, error) {
if tx.YParity != nil { if tx.YParity != nil {
val := uint64(*tx.YParity) val := uint64(*tx.YParity)
if val != 0 && val != 1 { if val != 0 && val != 1 {
return nil, errors.New("'yParity' field must be 0 or 1") return nil, errInvalidYParity
} }
bigval := new(big.Int).SetUint64(val) bigval := new(big.Int).SetUint64(val)
if tx.V != nil && tx.V.ToInt().Cmp(bigval) != 0 { if tx.V != nil && tx.V.ToInt().Cmp(bigval) != 0 {
return nil, errors.New("'v' and 'yParity' fields do not match") return nil, errVYParityMismatch
} }
return bigval, nil return bigval, nil
} }
if tx.V != nil { if tx.V != nil {
return tx.V.ToInt(), nil return tx.V.ToInt(), nil
} }
return nil, errors.New("missing 'yParity' or 'v' field in transaction") return nil, errVYParityMissing
} }
// MarshalJSON marshals as JSON with a hash. // MarshalJSON marshals as JSON with a hash.
@ -294,9 +294,6 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
return errors.New("missing required field 'input' in transaction") return errors.New("missing required field 'input' in transaction")
} }
itx.Data = *dec.Input itx.Data = *dec.Input
if dec.V == nil {
return errors.New("missing required field 'v' in transaction")
}
if dec.AccessList != nil { if dec.AccessList != nil {
itx.AccessList = *dec.AccessList itx.AccessList = *dec.AccessList
} }
@ -361,9 +358,6 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
return errors.New("missing required field 'input' in transaction") return errors.New("missing required field 'input' in transaction")
} }
itx.Data = *dec.Input itx.Data = *dec.Input
if dec.V == nil {
return errors.New("missing required field 'v' in transaction")
}
if dec.AccessList != nil { if dec.AccessList != nil {
itx.AccessList = *dec.AccessList itx.AccessList = *dec.AccessList
} }

View file

@ -451,3 +451,97 @@ func TestTransactionSizes(t *testing.T) {
} }
} }
} }
func TestYParityJSONUnmarshalling(t *testing.T) {
baseJson := map[string]interface{}{
// type is filled in by the test
"chainId": "0x7",
"nonce": "0x0",
"to": "0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425",
"gas": "0x124f8",
"gasPrice": "0x693d4ca8",
"maxPriorityFeePerGas": "0x3b9aca00",
"maxFeePerGas": "0x6fc23ac00",
"maxFeePerBlobGas": "0x3b9aca00",
"value": "0x0",
"input": "0x",
"accessList": []interface{}{},
"blobVersionedHashes": []string{
"0x010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c444014",
},
// v and yParity are filled in by the test
"r": "0x2a922afc784d07e98012da29f2f37cae1f73eda78aa8805d3df6ee5dbb41ec1",
"s": "0x4f1f75ae6bcdf4970b4f305da1a15d8c5ddb21f555444beab77c9af2baab14",
}
tests := []struct {
name string
v string
yParity string
wantErr error
}{
// Valid v and yParity
{"valid v and yParity, 0x0", "0x0", "0x0", nil},
{"valid v and yParity, 0x1", "0x1", "0x1", nil},
// Valid v, missing yParity
{"valid v, missing yParity, 0x0", "0x0", "", nil},
{"valid v, missing yParity, 0x1", "0x1", "", nil},
// Valid yParity, missing v
{"valid yParity, missing v, 0x0", "", "0x0", nil},
{"valid yParity, missing v, 0x1", "", "0x1", nil},
// Invalid yParity
{"invalid yParity, 0x2", "", "0x2", errInvalidYParity},
// Conflicting v and yParity
{"conflicting v and yParity", "0x1", "0x0", errVYParityMismatch},
// Missing v and yParity
{"missing v and yParity", "", "", errVYParityMissing},
}
// Run for all types that accept yParity
t.Parallel()
for _, txType := range []uint64{
AccessListTxType,
DynamicFeeTxType,
BlobTxType,
} {
txType := txType
for _, test := range tests {
test := test
t.Run(fmt.Sprintf("txType=%d: %s", txType, test.name), func(t *testing.T) {
// Copy the base json
testJson := make(map[string]interface{})
for k, v := range baseJson {
testJson[k] = v
}
// Set v, yParity and type
if test.v != "" {
testJson["v"] = test.v
}
if test.yParity != "" {
testJson["yParity"] = test.yParity
}
testJson["type"] = fmt.Sprintf("0x%x", txType)
// Marshal the JSON
jsonBytes, err := json.Marshal(testJson)
if err != nil {
t.Fatal(err)
}
// Unmarshal the tx
var tx Transaction
err = tx.UnmarshalJSON(jsonBytes)
if err != test.wantErr {
t.Fatalf("wrong error: got %v, want %v", err, test.wantErr)
}
})
}
}
}

View file

@ -82,10 +82,6 @@ type SimulatedBeacon struct {
} }
func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, error) { func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, error) {
chainConfig := eth.APIBackend.ChainConfig()
if !chainConfig.IsDevMode {
return nil, errors.New("incompatible pre-existing chain configuration")
}
block := eth.BlockChain().CurrentBlock() block := eth.BlockChain().CurrentBlock()
current := engine.ForkchoiceStateV1{ current := engine.ForkchoiceStateV1{
HeadBlockHash: block.Hash(), HeadBlockHash: block.Hash(),

View file

@ -85,7 +85,7 @@ func TestSimulatedBeaconSendWithdrawals(t *testing.T) {
// short period (1 second) for testing purposes // short period (1 second) for testing purposes
var gasLimit uint64 = 10_000_000 var gasLimit uint64 = 10_000_000
genesis := core.DeveloperGenesisBlock(gasLimit, testAddr) genesis := core.DeveloperGenesisBlock(gasLimit, &testAddr)
node, ethService, mock := startSimulatedBeaconEthService(t, genesis) node, ethService, mock := startSimulatedBeaconEthService(t, genesis)
_ = mock _ = mock
defer node.Close() defer node.Close()

View file

@ -114,7 +114,7 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) {
// special case for pending logs // special case for pending logs
if beginPending && !endPending { if beginPending && !endPending {
return nil, errors.New("invalid block range") return nil, errInvalidBlockRange
} }
// Short-cut if all we care about is pending logs // Short-cut if all we care about is pending logs

View file

@ -353,7 +353,7 @@ func TestFilters(t *testing.T) {
}, },
{ {
f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
err: "invalid block range", err: errInvalidBlockRange.Error(),
}, },
} { } {
logs, err := tc.f.Logs(context.Background()) logs, err := tc.f.Logs(context.Background())

View file

@ -207,7 +207,7 @@ func (db *Database) Len() int {
// keyvalue is a key-value tuple tagged with a deletion field to allow creating // keyvalue is a key-value tuple tagged with a deletion field to allow creating
// memory-database write batches. // memory-database write batches.
type keyvalue struct { type keyvalue struct {
key []byte key string
value []byte value []byte
delete bool delete bool
} }
@ -222,14 +222,14 @@ type batch struct {
// Put inserts the given value into the batch for later committing. // Put inserts the given value into the batch for later committing.
func (b *batch) Put(key, value []byte) error { func (b *batch) Put(key, value []byte) error {
b.writes = append(b.writes, keyvalue{common.CopyBytes(key), common.CopyBytes(value), false}) b.writes = append(b.writes, keyvalue{string(key), common.CopyBytes(value), false})
b.size += len(key) + len(value) b.size += len(key) + len(value)
return nil return nil
} }
// Delete inserts the a key removal into the batch for later committing. // Delete inserts the a key removal into the batch for later committing.
func (b *batch) Delete(key []byte) error { func (b *batch) Delete(key []byte) error {
b.writes = append(b.writes, keyvalue{common.CopyBytes(key), nil, true}) b.writes = append(b.writes, keyvalue{string(key), nil, true})
b.size += len(key) b.size += len(key)
return nil return nil
} }
@ -249,10 +249,10 @@ func (b *batch) Write() error {
} }
for _, keyvalue := range b.writes { for _, keyvalue := range b.writes {
if keyvalue.delete { if keyvalue.delete {
delete(b.db.db, string(keyvalue.key)) delete(b.db.db, keyvalue.key)
continue continue
} }
b.db.db[string(keyvalue.key)] = keyvalue.value b.db.db[keyvalue.key] = keyvalue.value
} }
return nil return nil
} }
@ -267,12 +267,12 @@ func (b *batch) Reset() {
func (b *batch) Replay(w ethdb.KeyValueWriter) error { func (b *batch) Replay(w ethdb.KeyValueWriter) error {
for _, keyvalue := range b.writes { for _, keyvalue := range b.writes {
if keyvalue.delete { if keyvalue.delete {
if err := w.Delete(keyvalue.key); err != nil { if err := w.Delete([]byte(keyvalue.key)); err != nil {
return err return err
} }
continue continue
} }
if err := w.Put(keyvalue.key, keyvalue.value); err != nil { if err := w.Put([]byte(keyvalue.key), keyvalue.value); err != nil {
return err return err
} }
} }

View file

@ -17,6 +17,7 @@
package memorydb package memorydb
import ( import (
"encoding/binary"
"testing" "testing"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
@ -30,3 +31,20 @@ func TestMemoryDB(t *testing.T) {
}) })
}) })
} }
// BenchmarkBatchAllocs measures the time/allocs for storing 120 kB of data
func BenchmarkBatchAllocs(b *testing.B) {
b.ReportAllocs()
var key = make([]byte, 20)
var val = make([]byte, 100)
// 120 * 1_000 -> 120_000 == 120kB
for i := 0; i < b.N; i++ {
batch := New().NewBatch()
for j := uint64(0); j < 1000; j++ {
binary.BigEndian.PutUint64(key, j)
binary.BigEndian.PutUint64(val, j)
batch.Put(key, val)
}
batch.Write()
}
}

View file

@ -609,9 +609,12 @@ func (b *batch) Replay(w ethdb.KeyValueWriter) error {
// pebbleIterator is a wrapper of underlying iterator in storage engine. // pebbleIterator is a wrapper of underlying iterator in storage engine.
// The purpose of this structure is to implement the missing APIs. // The purpose of this structure is to implement the missing APIs.
//
// The pebble iterator is not thread-safe.
type pebbleIterator struct { type pebbleIterator struct {
iter *pebble.Iterator iter *pebble.Iterator
moved bool moved bool
released bool
} }
// NewIterator creates a binary-alphabetical iterator over a subset // NewIterator creates a binary-alphabetical iterator over a subset
@ -623,7 +626,7 @@ func (d *Database) NewIterator(prefix []byte, start []byte) ethdb.Iterator {
UpperBound: upperBound(prefix), UpperBound: upperBound(prefix),
}) })
iter.First() iter.First()
return &pebbleIterator{iter: iter, moved: true} return &pebbleIterator{iter: iter, moved: true, released: false}
} }
// Next moves the iterator to the next key/value pair. It returns whether the // Next moves the iterator to the next key/value pair. It returns whether the
@ -658,4 +661,9 @@ func (iter *pebbleIterator) Value() []byte {
// Release releases associated resources. Release should always succeed and can // Release releases associated resources. Release should always succeed and can
// be called multiple times without causing error. // be called multiple times without causing error.
func (iter *pebbleIterator) Release() { iter.iter.Close() } func (iter *pebbleIterator) Release() {
if !iter.released {
iter.iter.Close()
iter.released = true
}
}

View file

@ -1033,7 +1033,7 @@ var formatOutputInt = function (param) {
* *
* @method formatOutputUInt * @method formatOutputUInt
* @param {SolidityParam} * @param {SolidityParam}
* @returns {BigNumeber} right-aligned output bytes formatted to uint * @returns {BigNumber} right-aligned output bytes formatted to uint
*/ */
var formatOutputUInt = function (param) { var formatOutputUInt = function (param) {
var value = param.staticPart() || "0"; var value = param.staticPart() || "0";

View file

@ -338,7 +338,7 @@ func (h *serverHandler) measure(setup *benchmarkSetup, count int) error {
case <-h.closeCh: case <-h.closeCh:
clientPipe.Close() clientPipe.Close()
serverPipe.Close() serverPipe.Close()
return errors.New("Benchmark cancelled") return errors.New("benchmark cancelled")
} }
setup.totalTime += time.Duration(mclock.Now() - start) setup.totalTime += time.Duration(mclock.Now() - start)

View file

@ -1000,7 +1000,7 @@ func (p *clientPeer) Handshake(td *big.Int, head common.Hash, headNum uint64, ge
} }
} }
if recentTx != txIndexUnlimited && p.version < lpv4 { if recentTx != txIndexUnlimited && p.version < lpv4 {
return errors.New("Cannot serve old clients without a complete tx index") return errors.New("cannot serve old clients without a complete tx index")
} }
// Note: clientPeer.headInfo should contain the last head announced to the client by us. // Note: clientPeer.headInfo should contain the last head announced to the client by us.
// The values announced in the handshake are dummy values for compatibility reasons and should be ignored. // The values announced in the handshake are dummy values for compatibility reasons and should be ignored.

View file

@ -143,7 +143,7 @@ func TestHandshake(t *testing.T) {
return err return err
} }
if reqType != announceTypeSigned { if reqType != announceTypeSigned {
return errors.New("Expected announceTypeSigned") return errors.New("expected announceTypeSigned")
} }
return nil return nil
}) })

View file

@ -257,7 +257,7 @@ func (vt *ValueTracker) loadFromDb(mapping []string) error {
} }
if version != vtVersion { if version != vtVersion {
log.Error("Unknown ValueTracker version", "stored", version, "current", nvtVersion) log.Error("Unknown ValueTracker version", "stored", version, "current", nvtVersion)
return fmt.Errorf("Unknown ValueTracker version %d (current version is %d)", version, vtVersion) return fmt.Errorf("unknown ValueTracker version %d (current version is %d)", version, vtVersion)
} }
var vte valueTrackerEncV1 var vte valueTrackerEncV1
if err := rlp.Decode(r, &vte); err != nil { if err := rlp.Decode(r, &vte); err != nil {
@ -295,7 +295,7 @@ loop:
} else { } else {
if vte.RefBasketMapping >= uint(len(vt.mappings)) { if vte.RefBasketMapping >= uint(len(vt.mappings)) {
log.Error("Unknown request basket mapping", "stored", vte.RefBasketMapping, "current", vt.currentMapping) log.Error("Unknown request basket mapping", "stored", vte.RefBasketMapping, "current", vt.currentMapping)
return fmt.Errorf("Unknown request basket mapping %d (current version is %d)", vte.RefBasketMapping, vt.currentMapping) return fmt.Errorf("unknown request basket mapping %d (current version is %d)", vte.RefBasketMapping, vt.currentMapping)
} }
vt.refBasket.basket = vte.RefBasket.convertMapping(vt.mappings[vte.RefBasketMapping], mapping, vt.initRefBasket) vt.refBasket.basket = vte.RefBasket.convertMapping(vt.mappings[vte.RefBasketMapping], mapping, vt.initRefBasket)
} }

View file

@ -23,5 +23,5 @@ import "errors"
// ReadDiskStats retrieves the disk IO stats belonging to the current process. // ReadDiskStats retrieves the disk IO stats belonging to the current process.
func ReadDiskStats(stats *DiskStats) error { func ReadDiskStats(stats *DiskStats) error {
return errors.New("Not implemented") return errors.New("not implemented")
} }

View file

@ -36,7 +36,7 @@ func TestGaugeFloat64Snapshot(t *testing.T) {
g.Update(47.0) g.Update(47.0)
snapshot := g.Snapshot() snapshot := g.Snapshot()
g.Update(float64(0)) g.Update(float64(0))
if v := snapshot.Value(); 47.0 != v { if v := snapshot.Value(); v != 47.0 {
t.Errorf("g.Value(): 47.0 != %v\n", v) t.Errorf("g.Value(): 47.0 != %v\n", v)
} }
} }
@ -45,7 +45,7 @@ func TestGetOrRegisterGaugeFloat64(t *testing.T) {
r := NewRegistry() r := NewRegistry()
NewRegisteredGaugeFloat64("foo", r).Update(47.0) NewRegisteredGaugeFloat64("foo", r).Update(47.0)
t.Logf("registry: %v", r) t.Logf("registry: %v", r)
if g := GetOrRegisterGaugeFloat64("foo", r).Snapshot(); 47.0 != g.Value() { if g := GetOrRegisterGaugeFloat64("foo", r).Snapshot(); g.Value() != 47.0 {
t.Fatal(g) t.Fatal(g)
} }
} }

View file

@ -99,6 +99,7 @@ func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent)
} }
func TestMiner(t *testing.T) { func TestMiner(t *testing.T) {
t.Parallel()
miner, mux, cleanup := createMiner(t) miner, mux, cleanup := createMiner(t)
defer cleanup(false) defer cleanup(false)
@ -128,6 +129,7 @@ func TestMiner(t *testing.T) {
// An initial FailedEvent should allow mining to stop on a subsequent // An initial FailedEvent should allow mining to stop on a subsequent
// downloader StartEvent. // downloader StartEvent.
func TestMinerDownloaderFirstFails(t *testing.T) { func TestMinerDownloaderFirstFails(t *testing.T) {
t.Parallel()
miner, mux, cleanup := createMiner(t) miner, mux, cleanup := createMiner(t)
defer cleanup(false) defer cleanup(false)
@ -161,6 +163,7 @@ func TestMinerDownloaderFirstFails(t *testing.T) {
} }
func TestMinerStartStopAfterDownloaderEvents(t *testing.T) { func TestMinerStartStopAfterDownloaderEvents(t *testing.T) {
t.Parallel()
miner, mux, cleanup := createMiner(t) miner, mux, cleanup := createMiner(t)
defer cleanup(false) defer cleanup(false)
@ -185,6 +188,7 @@ func TestMinerStartStopAfterDownloaderEvents(t *testing.T) {
} }
func TestStartWhileDownload(t *testing.T) { func TestStartWhileDownload(t *testing.T) {
t.Parallel()
miner, mux, cleanup := createMiner(t) miner, mux, cleanup := createMiner(t)
defer cleanup(false) defer cleanup(false)
waitForMiningState(t, miner, false) waitForMiningState(t, miner, false)
@ -199,6 +203,7 @@ func TestStartWhileDownload(t *testing.T) {
} }
func TestStartStopMiner(t *testing.T) { func TestStartStopMiner(t *testing.T) {
t.Parallel()
miner, _, cleanup := createMiner(t) miner, _, cleanup := createMiner(t)
defer cleanup(false) defer cleanup(false)
waitForMiningState(t, miner, false) waitForMiningState(t, miner, false)
@ -209,6 +214,7 @@ func TestStartStopMiner(t *testing.T) {
} }
func TestCloseMiner(t *testing.T) { func TestCloseMiner(t *testing.T) {
t.Parallel()
miner, _, cleanup := createMiner(t) miner, _, cleanup := createMiner(t)
defer cleanup(true) defer cleanup(true)
waitForMiningState(t, miner, false) waitForMiningState(t, miner, false)
@ -222,6 +228,7 @@ func TestCloseMiner(t *testing.T) {
// TestMinerSetEtherbase checks that etherbase becomes set even if mining isn't // TestMinerSetEtherbase checks that etherbase becomes set even if mining isn't
// possible at the moment // possible at the moment
func TestMinerSetEtherbase(t *testing.T) { func TestMinerSetEtherbase(t *testing.T) {
t.Parallel()
miner, mux, cleanup := createMiner(t) miner, mux, cleanup := createMiner(t)
defer cleanup(false) defer cleanup(false)
miner.Start() miner.Start()

View file

@ -30,10 +30,12 @@ import (
) )
func TestTransactionPriceNonceSortLegacy(t *testing.T) { func TestTransactionPriceNonceSortLegacy(t *testing.T) {
t.Parallel()
testTransactionPriceNonceSort(t, nil) testTransactionPriceNonceSort(t, nil)
} }
func TestTransactionPriceNonceSort1559(t *testing.T) { func TestTransactionPriceNonceSort1559(t *testing.T) {
t.Parallel()
testTransactionPriceNonceSort(t, big.NewInt(0)) testTransactionPriceNonceSort(t, big.NewInt(0))
testTransactionPriceNonceSort(t, big.NewInt(5)) testTransactionPriceNonceSort(t, big.NewInt(5))
testTransactionPriceNonceSort(t, big.NewInt(50)) testTransactionPriceNonceSort(t, big.NewInt(50))
@ -138,6 +140,7 @@ func testTransactionPriceNonceSort(t *testing.T, baseFee *big.Int) {
// Tests that if multiple transactions have the same price, the ones seen earlier // Tests that if multiple transactions have the same price, the ones seen earlier
// are prioritized to avoid network spam attacks aiming for a specific ordering. // are prioritized to avoid network spam attacks aiming for a specific ordering.
func TestTransactionTimeSort(t *testing.T) { func TestTransactionTimeSort(t *testing.T) {
t.Parallel()
// Generate a batch of accounts to start with // Generate a batch of accounts to start with
keys := make([]*ecdsa.PrivateKey, 5) keys := make([]*ecdsa.PrivateKey, 5)
for i := 0; i < len(keys); i++ { for i := 0; i < len(keys); i++ {

View file

@ -30,6 +30,7 @@ import (
) )
func TestBuildPayload(t *testing.T) { func TestBuildPayload(t *testing.T) {
t.Parallel()
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
recipient = common.HexToAddress("0xdeadbeef") recipient = common.HexToAddress("0xdeadbeef")
@ -82,6 +83,7 @@ func TestBuildPayload(t *testing.T) {
} }
func TestPayloadId(t *testing.T) { func TestPayloadId(t *testing.T) {
t.Parallel()
ids := make(map[string]int) ids := make(map[string]int)
for i, tt := range []*BuildPayloadArgs{ for i, tt := range []*BuildPayloadArgs{
{ {

View file

@ -167,6 +167,7 @@ func newTestWorker(t *testing.T, chainConfig *params.ChainConfig, engine consens
} }
func TestGenerateAndImportBlock(t *testing.T) { func TestGenerateAndImportBlock(t *testing.T) {
t.Parallel()
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
config = *params.AllCliqueProtocolChanges config = *params.AllCliqueProtocolChanges
@ -210,9 +211,11 @@ func TestGenerateAndImportBlock(t *testing.T) {
} }
func TestEmptyWorkEthash(t *testing.T) { func TestEmptyWorkEthash(t *testing.T) {
t.Parallel()
testEmptyWork(t, ethashChainConfig, ethash.NewFaker()) testEmptyWork(t, ethashChainConfig, ethash.NewFaker())
} }
func TestEmptyWorkClique(t *testing.T) { func TestEmptyWorkClique(t *testing.T) {
t.Parallel()
testEmptyWork(t, cliqueChainConfig, clique.New(cliqueChainConfig.Clique, rawdb.NewMemoryDatabase())) testEmptyWork(t, cliqueChainConfig, clique.New(cliqueChainConfig.Clique, rawdb.NewMemoryDatabase()))
} }
@ -252,10 +255,12 @@ func testEmptyWork(t *testing.T, chainConfig *params.ChainConfig, engine consens
} }
func TestAdjustIntervalEthash(t *testing.T) { func TestAdjustIntervalEthash(t *testing.T) {
t.Parallel()
testAdjustInterval(t, ethashChainConfig, ethash.NewFaker()) testAdjustInterval(t, ethashChainConfig, ethash.NewFaker())
} }
func TestAdjustIntervalClique(t *testing.T) { func TestAdjustIntervalClique(t *testing.T) {
t.Parallel()
testAdjustInterval(t, cliqueChainConfig, clique.New(cliqueChainConfig.Clique, rawdb.NewMemoryDatabase())) testAdjustInterval(t, cliqueChainConfig, clique.New(cliqueChainConfig.Clique, rawdb.NewMemoryDatabase()))
} }
@ -346,14 +351,17 @@ func testAdjustInterval(t *testing.T, chainConfig *params.ChainConfig, engine co
} }
func TestGetSealingWorkEthash(t *testing.T) { func TestGetSealingWorkEthash(t *testing.T) {
t.Parallel()
testGetSealingWork(t, ethashChainConfig, ethash.NewFaker()) testGetSealingWork(t, ethashChainConfig, ethash.NewFaker())
} }
func TestGetSealingWorkClique(t *testing.T) { func TestGetSealingWorkClique(t *testing.T) {
t.Parallel()
testGetSealingWork(t, cliqueChainConfig, clique.New(cliqueChainConfig.Clique, rawdb.NewMemoryDatabase())) testGetSealingWork(t, cliqueChainConfig, clique.New(cliqueChainConfig.Clique, rawdb.NewMemoryDatabase()))
} }
func TestGetSealingWorkPostMerge(t *testing.T) { func TestGetSealingWorkPostMerge(t *testing.T) {
t.Parallel()
local := new(params.ChainConfig) local := new(params.ChainConfig)
*local = *ethashChainConfig *local = *ethashChainConfig
local.TerminalTotalDifficulty = big.NewInt(0) local.TerminalTotalDifficulty = big.NewInt(0)

View file

@ -61,12 +61,12 @@ type Interface interface {
// "pmp:192.168.0.1" uses NAT-PMP with the given gateway address // "pmp:192.168.0.1" uses NAT-PMP with the given gateway address
func Parse(spec string) (Interface, error) { func Parse(spec string) (Interface, error) {
var ( var (
parts = strings.SplitN(spec, ":", 2) before, after, found = strings.Cut(spec, ":")
mech = strings.ToLower(parts[0]) mech = strings.ToLower(before)
ip net.IP ip net.IP
) )
if len(parts) > 1 { if found {
ip = net.ParseIP(parts[1]) ip = net.ParseIP(after)
if ip == nil { if ip == nil {
return nil, errors.New("invalid IP address") return nil, errors.New("invalid IP address")
} }
@ -86,7 +86,7 @@ func Parse(spec string) (Interface, error) {
case "pmp", "natpmp", "nat-pmp": case "pmp", "natpmp", "nat-pmp":
return PMP(ip), nil return PMP(ip), nil
default: default:
return nil, fmt.Errorf("unknown mechanism %q", parts[0]) return nil, fmt.Errorf("unknown mechanism %q", before)
} }
} }

View file

@ -479,12 +479,12 @@ func (s *Server) StreamNetworkEvents(w http.ResponseWriter, req *http.Request) {
func NewMsgFilters(filterParam string) (MsgFilters, error) { func NewMsgFilters(filterParam string) (MsgFilters, error) {
filters := make(MsgFilters) filters := make(MsgFilters)
for _, filter := range strings.Split(filterParam, "-") { for _, filter := range strings.Split(filterParam, "-") {
protoCodes := strings.SplitN(filter, ":", 2) proto, codes, found := strings.Cut(filter, ":")
if len(protoCodes) != 2 || protoCodes[0] == "" || protoCodes[1] == "" { if !found || proto == "" || codes == "" {
return nil, fmt.Errorf("invalid message filter: %s", filter) return nil, fmt.Errorf("invalid message filter: %s", filter)
} }
proto := protoCodes[0]
for _, code := range strings.Split(protoCodes[1], ",") { for _, code := range strings.Split(codes, ",") {
if code == "*" || code == "-1" { if code == "*" || code == "-1" {
filters[MsgFilter{Proto: proto, Code: -1}] = struct{}{} filters[MsgFilter{Proto: proto, Code: -1}] = struct{}{}
continue continue

View file

@ -180,7 +180,6 @@ var (
ShanghaiTime: newUint64(0), ShanghaiTime: newUint64(0),
TerminalTotalDifficulty: big.NewInt(0), TerminalTotalDifficulty: big.NewInt(0),
TerminalTotalDifficultyPassed: true, TerminalTotalDifficultyPassed: true,
IsDevMode: true,
} }
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
@ -331,7 +330,6 @@ type ChainConfig struct {
// Various consensus engines // Various consensus engines
Ethash *EthashConfig `json:"ethash,omitempty"` Ethash *EthashConfig `json:"ethash,omitempty"`
Clique *CliqueConfig `json:"clique,omitempty"` Clique *CliqueConfig `json:"clique,omitempty"`
IsDevMode bool `json:"isDev,omitempty"`
} }
// EthashConfig is the consensus engine configs for proof-of-work based sealing. // EthashConfig is the consensus engine configs for proof-of-work based sealing.

View file

@ -595,7 +595,7 @@ func TestClientSubscriptionChannelClose(t *testing.T) {
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
ch := make(chan int, 100) ch := make(chan int, 100)
sub, err := client.Subscribe(context.Background(), "nftest", ch, "someSubscription", maxClientSubscriptionBuffer-1, 1) sub, err := client.Subscribe(context.Background(), "nftest", ch, "someSubscription", 100, 1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View file

@ -46,6 +46,17 @@ type subscriptionResult struct {
Result json.RawMessage `json:"result,omitempty"` Result json.RawMessage `json:"result,omitempty"`
} }
type subscriptionResultEnc struct {
ID string `json:"subscription"`
Result any `json:"result"`
}
type jsonrpcSubscriptionNotification struct {
Version string `json:"jsonrpc"`
Method string `json:"method"`
Params subscriptionResultEnc `json:"params"`
}
// A value of this type can a JSON-RPC request, notification, successful response or // A value of this type can a JSON-RPC request, notification, successful response or
// error response. Which one it is depends on the fields. // error response. Which one it is depends on the fields.
type jsonrpcMessage struct { type jsonrpcMessage struct {
@ -86,8 +97,8 @@ func (msg *jsonrpcMessage) isUnsubscribe() bool {
} }
func (msg *jsonrpcMessage) namespace() string { func (msg *jsonrpcMessage) namespace() string {
elem := strings.SplitN(msg.Method, serviceMethodSeparator, 2) before, _, _ := strings.Cut(msg.Method, serviceMethodSeparator)
return elem[0] return before
} }
func (msg *jsonrpcMessage) String() string { func (msg *jsonrpcMessage) String() string {

View file

@ -93,13 +93,13 @@ func (r *serviceRegistry) registerName(name string, rcvr interface{}) error {
// callback returns the callback corresponding to the given RPC method name. // callback returns the callback corresponding to the given RPC method name.
func (r *serviceRegistry) callback(method string) *callback { func (r *serviceRegistry) callback(method string) *callback {
elem := strings.SplitN(method, serviceMethodSeparator, 2) before, after, found := strings.Cut(method, serviceMethodSeparator)
if len(elem) != 2 { if !found {
return nil return nil
} }
r.mu.Lock() r.mu.Lock()
defer r.mu.Unlock() defer r.mu.Unlock()
return r.services[elem[0]].callbacks[elem[1]] return r.services[before].callbacks[after]
} }
// subscription returns a subscription callback in the given service. // subscription returns a subscription callback in the given service.

View file

@ -105,7 +105,7 @@ type Notifier struct {
mu sync.Mutex mu sync.Mutex
sub *Subscription sub *Subscription
buffer []json.RawMessage buffer []any
callReturned bool callReturned bool
activated bool activated bool
} }
@ -129,12 +129,7 @@ func (n *Notifier) CreateSubscription() *Subscription {
// Notify sends a notification to the client with the given data as payload. // Notify sends a notification to the client with the given data as payload.
// If an error occurs the RPC connection is closed and the error is returned. // If an error occurs the RPC connection is closed and the error is returned.
func (n *Notifier) Notify(id ID, data interface{}) error { func (n *Notifier) Notify(id ID, data any) error {
enc, err := json.Marshal(data)
if err != nil {
return err
}
n.mu.Lock() n.mu.Lock()
defer n.mu.Unlock() defer n.mu.Unlock()
@ -144,9 +139,9 @@ func (n *Notifier) Notify(id ID, data interface{}) error {
panic("Notify with wrong ID") panic("Notify with wrong ID")
} }
if n.activated { if n.activated {
return n.send(n.sub, enc) return n.send(n.sub, data)
} }
n.buffer = append(n.buffer, enc) n.buffer = append(n.buffer, data)
return nil return nil
} }
@ -181,16 +176,16 @@ func (n *Notifier) activate() error {
return nil return nil
} }
func (n *Notifier) send(sub *Subscription, data json.RawMessage) error { func (n *Notifier) send(sub *Subscription, data any) error {
params, _ := json.Marshal(&subscriptionResult{ID: string(sub.ID), Result: data}) msg := jsonrpcSubscriptionNotification{
ctx := context.Background()
msg := &jsonrpcMessage{
Version: vsn, Version: vsn,
Method: n.namespace + notificationMethodSuffix, Method: n.namespace + notificationMethodSuffix,
Params: params, Params: subscriptionResultEnc{
ID: string(sub.ID),
Result: data,
},
} }
return n.h.conn.writeJSON(ctx, msg, false) return n.h.conn.writeJSON(context.Background(), &msg, false)
} }
// A Subscription is created by a notifier and tied to that notifier. The client can use // A Subscription is created by a notifier and tied to that notifier. The client can use

View file

@ -17,12 +17,19 @@
package rpc package rpc
import ( import (
"bytes"
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"math/big"
"net" "net"
"strings" "strings"
"testing" "testing"
"time" "time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
) )
func TestNewID(t *testing.T) { func TestNewID(t *testing.T) {
@ -218,3 +225,56 @@ func readAndValidateMessage(in *json.Decoder) (*subConfirmation, *subscriptionRe
return nil, nil, fmt.Errorf("unrecognized message: %v", msg) return nil, nil, fmt.Errorf("unrecognized message: %v", msg)
} }
} }
type mockConn struct {
enc *json.Encoder
}
// writeJSON writes a message to the connection.
func (c *mockConn) writeJSON(ctx context.Context, msg interface{}, isError bool) error {
return c.enc.Encode(msg)
}
// Closed returns a channel which is closed when the connection is closed.
func (c *mockConn) closed() <-chan interface{} { return nil }
// RemoteAddr returns the peer address of the connection.
func (c *mockConn) remoteAddr() string { return "" }
// BenchmarkNotify benchmarks the performance of notifying a subscription.
func BenchmarkNotify(b *testing.B) {
id := ID("test")
notifier := &Notifier{
h: &handler{conn: &mockConn{json.NewEncoder(io.Discard)}},
sub: &Subscription{ID: id},
activated: true,
}
msg := &types.Header{
ParentHash: common.HexToHash("0x01"),
Number: big.NewInt(100),
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
notifier.Notify(id, msg)
}
}
func TestNotify(t *testing.T) {
out := new(bytes.Buffer)
id := ID("test")
notifier := &Notifier{
h: &handler{conn: &mockConn{json.NewEncoder(out)}},
sub: &Subscription{ID: id},
activated: true,
}
msg := &types.Header{
ParentHash: common.HexToHash("0x01"),
Number: big.NewInt(100),
}
notifier.Notify(id, msg)
have := strings.TrimSpace(out.String())
want := `{"jsonrpc":"2.0","method":"_subscription","params":{"subscription":"test","result":{"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000001","sha3Uncles":"0x0000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":null,"number":"0x64","gasLimit":"0x0","gasUsed":"0x0","timestamp":"0x0","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000","baseFeePerGas":null,"withdrawalsRoot":null,"blobGasUsed":null,"excessBlobGas":null,"parentBeaconBlockRoot":null,"hash":"0xe5fb877dde471b45b9742bb4bb4b3d74a761e2fb7cb849a3d2b687eed90fb604"}}}`
if have != want {
t.Errorf("have:\n%v\nwant:\n%v\n", have, want)
}
}

View file

@ -169,6 +169,7 @@ func list(ui *headlessUi, api *core.SignerAPI, t *testing.T) ([]common.Address,
} }
func TestNewAcc(t *testing.T) { func TestNewAcc(t *testing.T) {
t.Parallel()
api, control := setup(t) api, control := setup(t)
verifyNum := func(num int) { verifyNum := func(num int) {
list, err := list(control, api, t) list, err := list(control, api, t)
@ -235,6 +236,7 @@ func mkTestTx(from common.MixedcaseAddress) apitypes.SendTxArgs {
} }
func TestSignTx(t *testing.T) { func TestSignTx(t *testing.T) {
t.Parallel()
var ( var (
list []common.Address list []common.Address
res, res2 *ethapi.SignTransactionResult res, res2 *ethapi.SignTransactionResult

View file

@ -27,6 +27,7 @@ import (
) )
func TestBytesPadding(t *testing.T) { func TestBytesPadding(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
Type string Type string
Input []byte Input []byte
@ -87,6 +88,7 @@ func TestBytesPadding(t *testing.T) {
} }
func TestParseAddress(t *testing.T) { func TestParseAddress(t *testing.T) {
t.Parallel()
tests := []struct { tests := []struct {
Input interface{} Input interface{}
Output []byte // nil => error Output []byte // nil => error
@ -136,6 +138,7 @@ func TestParseAddress(t *testing.T) {
} }
func TestParseBytes(t *testing.T) { func TestParseBytes(t *testing.T) {
t.Parallel()
for i, tt := range []struct { for i, tt := range []struct {
v interface{} v interface{}
exp []byte exp []byte
@ -170,6 +173,7 @@ func TestParseBytes(t *testing.T) {
} }
func TestParseInteger(t *testing.T) { func TestParseInteger(t *testing.T) {
t.Parallel()
for i, tt := range []struct { for i, tt := range []struct {
t string t string
v interface{} v interface{}
@ -200,6 +204,7 @@ func TestParseInteger(t *testing.T) {
} }
func TestConvertStringDataToSlice(t *testing.T) { func TestConvertStringDataToSlice(t *testing.T) {
t.Parallel()
slice := []string{"a", "b", "c"} slice := []string{"a", "b", "c"}
var it interface{} = slice var it interface{} = slice
_, err := convertDataToSlice(it) _, err := convertDataToSlice(it)
@ -209,6 +214,7 @@ func TestConvertStringDataToSlice(t *testing.T) {
} }
func TestConvertUint256DataToSlice(t *testing.T) { func TestConvertUint256DataToSlice(t *testing.T) {
t.Parallel()
slice := []*math.HexOrDecimal256{ slice := []*math.HexOrDecimal256{
math.NewHexOrDecimal256(1), math.NewHexOrDecimal256(1),
math.NewHexOrDecimal256(2), math.NewHexOrDecimal256(2),
@ -222,6 +228,7 @@ func TestConvertUint256DataToSlice(t *testing.T) {
} }
func TestConvertAddressDataToSlice(t *testing.T) { func TestConvertAddressDataToSlice(t *testing.T) {
t.Parallel()
slice := []common.Address{ slice := []common.Address{
common.HexToAddress("0x0000000000000000000000000000000000000001"), common.HexToAddress("0x0000000000000000000000000000000000000001"),
common.HexToAddress("0x0000000000000000000000000000000000000002"), common.HexToAddress("0x0000000000000000000000000000000000000002"),

View file

@ -19,6 +19,7 @@ package apitypes
import "testing" import "testing"
func TestIsPrimitive(t *testing.T) { func TestIsPrimitive(t *testing.T) {
t.Parallel()
// Expected positives // Expected positives
for i, tc := range []string{ for i, tc := range []string{
"int24", "int24[]", "uint88", "uint88[]", "uint", "uint[]", "int256", "int256[]", "int24", "int24[]", "uint88", "uint88[]", "uint", "uint[]", "int256", "int256[]",

View file

@ -183,6 +183,7 @@ var typedData = apitypes.TypedData{
} }
func TestSignData(t *testing.T) { func TestSignData(t *testing.T) {
t.Parallel()
api, control := setup(t) api, control := setup(t)
//Create two accounts //Create two accounts
createAccount(control, api, t) createAccount(control, api, t)
@ -248,6 +249,7 @@ func TestSignData(t *testing.T) {
} }
func TestDomainChainId(t *testing.T) { func TestDomainChainId(t *testing.T) {
t.Parallel()
withoutChainID := apitypes.TypedData{ withoutChainID := apitypes.TypedData{
Types: apitypes.Types{ Types: apitypes.Types{
"EIP712Domain": []apitypes.Type{ "EIP712Domain": []apitypes.Type{
@ -289,6 +291,7 @@ func TestDomainChainId(t *testing.T) {
} }
func TestHashStruct(t *testing.T) { func TestHashStruct(t *testing.T) {
t.Parallel()
hash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message) hash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -309,6 +312,7 @@ func TestHashStruct(t *testing.T) {
} }
func TestEncodeType(t *testing.T) { func TestEncodeType(t *testing.T) {
t.Parallel()
domainTypeEncoding := string(typedData.EncodeType("EIP712Domain")) domainTypeEncoding := string(typedData.EncodeType("EIP712Domain"))
if domainTypeEncoding != "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" { if domainTypeEncoding != "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" {
t.Errorf("Expected different encodeType result (got %s)", domainTypeEncoding) t.Errorf("Expected different encodeType result (got %s)", domainTypeEncoding)
@ -321,6 +325,7 @@ func TestEncodeType(t *testing.T) {
} }
func TestTypeHash(t *testing.T) { func TestTypeHash(t *testing.T) {
t.Parallel()
mailTypeHash := fmt.Sprintf("0x%s", common.Bytes2Hex(typedData.TypeHash(typedData.PrimaryType))) mailTypeHash := fmt.Sprintf("0x%s", common.Bytes2Hex(typedData.TypeHash(typedData.PrimaryType)))
if mailTypeHash != "0xa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2" { if mailTypeHash != "0xa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2" {
t.Errorf("Expected different typeHash result (got %s)", mailTypeHash) t.Errorf("Expected different typeHash result (got %s)", mailTypeHash)
@ -328,6 +333,7 @@ func TestTypeHash(t *testing.T) {
} }
func TestEncodeData(t *testing.T) { func TestEncodeData(t *testing.T) {
t.Parallel()
hash, err := typedData.EncodeData(typedData.PrimaryType, typedData.Message, 0) hash, err := typedData.EncodeData(typedData.PrimaryType, typedData.Message, 0)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -339,6 +345,7 @@ func TestEncodeData(t *testing.T) {
} }
func TestFormatter(t *testing.T) { func TestFormatter(t *testing.T) {
t.Parallel()
var d apitypes.TypedData var d apitypes.TypedData
err := json.Unmarshal([]byte(jsonTypedData), &d) err := json.Unmarshal([]byte(jsonTypedData), &d)
if err != nil { if err != nil {
@ -368,6 +375,7 @@ func sign(typedData apitypes.TypedData) ([]byte, []byte, error) {
} }
func TestJsonFiles(t *testing.T) { func TestJsonFiles(t *testing.T) {
t.Parallel()
testfiles, err := os.ReadDir("testdata/") testfiles, err := os.ReadDir("testdata/")
if err != nil { if err != nil {
t.Fatalf("failed reading files: %v", err) t.Fatalf("failed reading files: %v", err)
@ -402,6 +410,7 @@ func TestJsonFiles(t *testing.T) {
// TestFuzzerFiles tests some files that have been found by fuzzing to cause // TestFuzzerFiles tests some files that have been found by fuzzing to cause
// crashes or hangs. // crashes or hangs.
func TestFuzzerFiles(t *testing.T) { func TestFuzzerFiles(t *testing.T) {
t.Parallel()
corpusdir := path.Join("testdata", "fuzzing") corpusdir := path.Join("testdata", "fuzzing")
testfiles, err := os.ReadDir(corpusdir) testfiles, err := os.ReadDir(corpusdir)
if err != nil { if err != nil {
@ -514,6 +523,7 @@ var gnosisTx = `
// TestGnosisTypedData tests the scenario where a user submits a full EIP-712 // TestGnosisTypedData tests the scenario where a user submits a full EIP-712
// struct without using the gnosis-specific endpoint // struct without using the gnosis-specific endpoint
func TestGnosisTypedData(t *testing.T) { func TestGnosisTypedData(t *testing.T) {
t.Parallel()
var td apitypes.TypedData var td apitypes.TypedData
err := json.Unmarshal([]byte(gnosisTypedData), &td) err := json.Unmarshal([]byte(gnosisTypedData), &td)
if err != nil { if err != nil {
@ -532,6 +542,7 @@ func TestGnosisTypedData(t *testing.T) {
// TestGnosisCustomData tests the scenario where a user submits only the gnosis-safe // TestGnosisCustomData tests the scenario where a user submits only the gnosis-safe
// specific data, and we fill the TypedData struct on our side // specific data, and we fill the TypedData struct on our side
func TestGnosisCustomData(t *testing.T) { func TestGnosisCustomData(t *testing.T) {
t.Parallel()
var tx core.GnosisSafeTx var tx core.GnosisSafeTx
err := json.Unmarshal([]byte(gnosisTx), &tx) err := json.Unmarshal([]byte(gnosisTx), &tx)
if err != nil { if err != nil {
@ -644,6 +655,7 @@ var gnosisTxWithChainId = `
` `
func TestGnosisTypedDataWithChainId(t *testing.T) { func TestGnosisTypedDataWithChainId(t *testing.T) {
t.Parallel()
var td apitypes.TypedData var td apitypes.TypedData
err := json.Unmarshal([]byte(gnosisTypedDataWithChainId), &td) err := json.Unmarshal([]byte(gnosisTypedDataWithChainId), &td)
if err != nil { if err != nil {
@ -662,6 +674,7 @@ func TestGnosisTypedDataWithChainId(t *testing.T) {
// TestGnosisCustomData tests the scenario where a user submits only the gnosis-safe // TestGnosisCustomData tests the scenario where a user submits only the gnosis-safe
// specific data, and we fill the TypedData struct on our side // specific data, and we fill the TypedData struct on our side
func TestGnosisCustomDataWithChainId(t *testing.T) { func TestGnosisCustomDataWithChainId(t *testing.T) {
t.Parallel()
var tx core.GnosisSafeTx var tx core.GnosisSafeTx
err := json.Unmarshal([]byte(gnosisTxWithChainId), &tx) err := json.Unmarshal([]byte(gnosisTxWithChainId), &tx)
if err != nil { if err != nil {
@ -813,6 +826,7 @@ var complexTypedData = `
` `
func TestComplexTypedData(t *testing.T) { func TestComplexTypedData(t *testing.T) {
t.Parallel()
var td apitypes.TypedData var td apitypes.TypedData
err := json.Unmarshal([]byte(complexTypedData), &td) err := json.Unmarshal([]byte(complexTypedData), &td)
if err != nil { if err != nil {
@ -829,6 +843,7 @@ func TestComplexTypedData(t *testing.T) {
} }
func TestGnosisSafe(t *testing.T) { func TestGnosisSafe(t *testing.T) {
t.Parallel()
// json missing chain id // json missing chain id
js := "{\n \"safe\": \"0x899FcB1437DE65DC6315f5a69C017dd3F2837557\",\n \"to\": \"0x899FcB1437DE65DC6315f5a69C017dd3F2837557\",\n \"value\": \"0\",\n \"data\": \"0x0d582f13000000000000000000000000d3ed2b8756b942c98c851722f3bd507a17b4745f0000000000000000000000000000000000000000000000000000000000000005\",\n \"operation\": 0,\n \"gasToken\": \"0x0000000000000000000000000000000000000000\",\n \"safeTxGas\": 0,\n \"baseGas\": 0,\n \"gasPrice\": \"0\",\n \"refundReceiver\": \"0x0000000000000000000000000000000000000000\",\n \"nonce\": 0,\n \"executionDate\": null,\n \"submissionDate\": \"2022-02-23T14:09:00.018475Z\",\n \"modified\": \"2022-12-01T15:52:21.214357Z\",\n \"blockNumber\": null,\n \"transactionHash\": null,\n \"safeTxHash\": \"0x6f0f5cffee69087c9d2471e477a63cab2ae171cf433e754315d558d8836274f4\",\n \"executor\": null,\n \"isExecuted\": false,\n \"isSuccessful\": null,\n \"ethGasPrice\": null,\n \"maxFeePerGas\": null,\n \"maxPriorityFeePerGas\": null,\n \"gasUsed\": null,\n \"fee\": null,\n \"origin\": \"https://gnosis-safe.io\",\n \"dataDecoded\": {\n \"method\": \"addOwnerWithThreshold\",\n \"parameters\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"value\": \"0xD3Ed2b8756b942c98c851722F3bd507a17B4745F\"\n },\n {\n \"name\": \"_threshold\",\n \"type\": \"uint256\",\n \"value\": \"5\"\n }\n ]\n },\n \"confirmationsRequired\": 4,\n \"confirmations\": [\n {\n \"owner\": \"0x30B714E065B879F5c042A75Bb40a220A0BE27966\",\n \"submissionDate\": \"2022-03-01T14:56:22Z\",\n \"transactionHash\": \"0x6d0a9c83ac7578ef3be1f2afce089fb83b619583dfa779b82f4422fd64ff3ee9\",\n \"signature\": \"0x00000000000000000000000030b714e065b879f5c042a75bb40a220a0be27966000000000000000000000000000000000000000000000000000000000000000001\",\n \"signatureType\": \"APPROVED_HASH\"\n },\n {\n \"owner\": \"0x8300dFEa25Da0eb744fC0D98c23283F86AB8c10C\",\n \"submissionDate\": \"2022-12-01T15:52:21.214357Z\",\n \"transactionHash\": null,\n \"signature\": \"0xbce73de4cc6ee208e933a93c794dcb8ba1810f9848d1eec416b7be4dae9854c07dbf1720e60bbd310d2159197a380c941cfdb55b3ce58f9dd69efd395d7bef881b\",\n \"signatureType\": \"EOA\"\n }\n ],\n \"trusted\": true,\n \"signatures\": null\n}\n" js := "{\n \"safe\": \"0x899FcB1437DE65DC6315f5a69C017dd3F2837557\",\n \"to\": \"0x899FcB1437DE65DC6315f5a69C017dd3F2837557\",\n \"value\": \"0\",\n \"data\": \"0x0d582f13000000000000000000000000d3ed2b8756b942c98c851722f3bd507a17b4745f0000000000000000000000000000000000000000000000000000000000000005\",\n \"operation\": 0,\n \"gasToken\": \"0x0000000000000000000000000000000000000000\",\n \"safeTxGas\": 0,\n \"baseGas\": 0,\n \"gasPrice\": \"0\",\n \"refundReceiver\": \"0x0000000000000000000000000000000000000000\",\n \"nonce\": 0,\n \"executionDate\": null,\n \"submissionDate\": \"2022-02-23T14:09:00.018475Z\",\n \"modified\": \"2022-12-01T15:52:21.214357Z\",\n \"blockNumber\": null,\n \"transactionHash\": null,\n \"safeTxHash\": \"0x6f0f5cffee69087c9d2471e477a63cab2ae171cf433e754315d558d8836274f4\",\n \"executor\": null,\n \"isExecuted\": false,\n \"isSuccessful\": null,\n \"ethGasPrice\": null,\n \"maxFeePerGas\": null,\n \"maxPriorityFeePerGas\": null,\n \"gasUsed\": null,\n \"fee\": null,\n \"origin\": \"https://gnosis-safe.io\",\n \"dataDecoded\": {\n \"method\": \"addOwnerWithThreshold\",\n \"parameters\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"value\": \"0xD3Ed2b8756b942c98c851722F3bd507a17B4745F\"\n },\n {\n \"name\": \"_threshold\",\n \"type\": \"uint256\",\n \"value\": \"5\"\n }\n ]\n },\n \"confirmationsRequired\": 4,\n \"confirmations\": [\n {\n \"owner\": \"0x30B714E065B879F5c042A75Bb40a220A0BE27966\",\n \"submissionDate\": \"2022-03-01T14:56:22Z\",\n \"transactionHash\": \"0x6d0a9c83ac7578ef3be1f2afce089fb83b619583dfa779b82f4422fd64ff3ee9\",\n \"signature\": \"0x00000000000000000000000030b714e065b879f5c042a75bb40a220a0be27966000000000000000000000000000000000000000000000000000000000000000001\",\n \"signatureType\": \"APPROVED_HASH\"\n },\n {\n \"owner\": \"0x8300dFEa25Da0eb744fC0D98c23283F86AB8c10C\",\n \"submissionDate\": \"2022-12-01T15:52:21.214357Z\",\n \"transactionHash\": null,\n \"signature\": \"0xbce73de4cc6ee208e933a93c794dcb8ba1810f9848d1eec416b7be4dae9854c07dbf1720e60bbd310d2159197a380c941cfdb55b3ce58f9dd69efd395d7bef881b\",\n \"signatureType\": \"EOA\"\n }\n ],\n \"trusted\": true,\n \"signatures\": null\n}\n"
var gnosisTx core.GnosisSafeTx var gnosisTx core.GnosisSafeTx
@ -984,6 +999,7 @@ var complexTypedDataLCRefType = `
` `
func TestComplexTypedDataWithLowercaseReftype(t *testing.T) { func TestComplexTypedDataWithLowercaseReftype(t *testing.T) {
t.Parallel()
var td apitypes.TypedData var td apitypes.TypedData
err := json.Unmarshal([]byte(complexTypedDataLCRefType), &td) err := json.Unmarshal([]byte(complexTypedDataLCRefType), &td)
if err != nil { if err != nil {

View file

@ -19,6 +19,7 @@ package core
import "testing" import "testing"
func TestPasswordValidation(t *testing.T) { func TestPasswordValidation(t *testing.T) {
t.Parallel()
testcases := []struct { testcases := []struct {
pw string pw string
shouldFail bool shouldFail bool

View file

@ -52,6 +52,7 @@ func verify(t *testing.T, jsondata, calldata string, exp []interface{}) {
} }
func TestNewUnpacker(t *testing.T) { func TestNewUnpacker(t *testing.T) {
t.Parallel()
type unpackTest struct { type unpackTest struct {
jsondata string jsondata string
calldata string calldata string
@ -97,6 +98,7 @@ func TestNewUnpacker(t *testing.T) {
} }
func TestCalldataDecoding(t *testing.T) { func TestCalldataDecoding(t *testing.T) {
t.Parallel()
// send(uint256) : a52c101e // send(uint256) : a52c101e
// compareAndApprove(address,uint256,uint256) : 751e1079 // compareAndApprove(address,uint256,uint256) : 751e1079
// issue(address[],uint256) : 42958b54 // issue(address[],uint256) : 42958b54
@ -159,6 +161,7 @@ func TestCalldataDecoding(t *testing.T) {
} }
func TestMaliciousABIStrings(t *testing.T) { func TestMaliciousABIStrings(t *testing.T) {
t.Parallel()
tests := []string{ tests := []string{
"func(uint256,uint256,[]uint256)", "func(uint256,uint256,[]uint256)",
"func(uint256,uint256,uint256,)", "func(uint256,uint256,uint256,)",

View file

@ -17,8 +17,8 @@
package fourbyte package fourbyte
import ( import (
"encoding/json"
"fmt" "fmt"
"strings"
"testing" "testing"
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
@ -27,18 +27,19 @@ import (
// Tests that all the selectors contained in the 4byte database are valid. // Tests that all the selectors contained in the 4byte database are valid.
func TestEmbeddedDatabase(t *testing.T) { func TestEmbeddedDatabase(t *testing.T) {
t.Parallel()
db, err := New() db, err := New()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
var abistruct abi.ABI
for id, selector := range db.embedded { for id, selector := range db.embedded {
abistring, err := parseSelector(selector) abistring, err := parseSelector(selector)
if err != nil { if err != nil {
t.Errorf("Failed to convert selector to ABI: %v", err) t.Errorf("Failed to convert selector to ABI: %v", err)
continue continue
} }
abistruct, err := abi.JSON(strings.NewReader(string(abistring))) if err := json.Unmarshal(abistring, &abistruct); err != nil {
if err != nil {
t.Errorf("Failed to parse ABI: %v", err) t.Errorf("Failed to parse ABI: %v", err)
continue continue
} }
@ -55,6 +56,7 @@ func TestEmbeddedDatabase(t *testing.T) {
// Tests that custom 4byte datasets can be handled too. // Tests that custom 4byte datasets can be handled too.
func TestCustomDatabase(t *testing.T) { func TestCustomDatabase(t *testing.T) {
t.Parallel()
// Create a new custom 4byte database with no embedded component // Create a new custom 4byte database with no embedded component
tmpdir := t.TempDir() tmpdir := t.TempDir()
filename := fmt.Sprintf("%s/4byte_custom.json", tmpdir) filename := fmt.Sprintf("%s/4byte_custom.json", tmpdir)

View file

@ -73,6 +73,7 @@ type txtestcase struct {
} }
func TestTransactionValidation(t *testing.T) { func TestTransactionValidation(t *testing.T) {
t.Parallel()
var ( var (
// use empty db, there are other tests for the abi-specific stuff // use empty db, there are other tests for the abi-specific stuff
db = newEmpty() db = newEmpty()

View file

@ -124,6 +124,7 @@ func initRuleEngine(js string) (*rulesetUI, error) {
} }
func TestListRequest(t *testing.T) { func TestListRequest(t *testing.T) {
t.Parallel()
accs := make([]accounts.Account, 5) accs := make([]accounts.Account, 5)
for i := range accs { for i := range accs {
@ -152,6 +153,7 @@ func TestListRequest(t *testing.T) {
} }
func TestSignTxRequest(t *testing.T) { func TestSignTxRequest(t *testing.T) {
t.Parallel()
js := ` js := `
function ApproveTx(r){ function ApproveTx(r){
console.log("transaction.from", r.transaction.from); console.log("transaction.from", r.transaction.from);
@ -244,6 +246,7 @@ func (d *dummyUI) OnSignerStartup(info core.StartupInfo) {
// TestForwarding tests that the rule-engine correctly dispatches requests to the next caller // TestForwarding tests that the rule-engine correctly dispatches requests to the next caller
func TestForwarding(t *testing.T) { func TestForwarding(t *testing.T) {
t.Parallel()
js := "" js := ""
ui := &dummyUI{make([]string, 0)} ui := &dummyUI{make([]string, 0)}
jsBackend := storage.NewEphemeralStorage() jsBackend := storage.NewEphemeralStorage()
@ -271,6 +274,7 @@ func TestForwarding(t *testing.T) {
} }
func TestMissingFunc(t *testing.T) { func TestMissingFunc(t *testing.T) {
t.Parallel()
r, err := initRuleEngine(JS) r, err := initRuleEngine(JS)
if err != nil { if err != nil {
t.Errorf("Couldn't create evaluator %v", err) t.Errorf("Couldn't create evaluator %v", err)
@ -293,6 +297,7 @@ func TestMissingFunc(t *testing.T) {
t.Logf("Err %v", err) t.Logf("Err %v", err)
} }
func TestStorage(t *testing.T) { func TestStorage(t *testing.T) {
t.Parallel()
js := ` js := `
function testStorage(){ function testStorage(){
storage.put("mykey", "myvalue") storage.put("mykey", "myvalue")
@ -455,6 +460,7 @@ func dummySigned(value *big.Int) *types.Transaction {
} }
func TestLimitWindow(t *testing.T) { func TestLimitWindow(t *testing.T) {
t.Parallel()
r, err := initRuleEngine(ExampleTxWindow) r, err := initRuleEngine(ExampleTxWindow)
if err != nil { if err != nil {
t.Errorf("Couldn't create evaluator %v", err) t.Errorf("Couldn't create evaluator %v", err)
@ -540,6 +546,7 @@ func (d *dontCallMe) OnApprovedTx(tx ethapi.SignTransactionResult) {
// if it does, that would be bad since developers may rely on that to store data, // if it does, that would be bad since developers may rely on that to store data,
// instead of using the disk-based data storage // instead of using the disk-based data storage
func TestContextIsCleared(t *testing.T) { func TestContextIsCleared(t *testing.T) {
t.Parallel()
js := ` js := `
function ApproveTx(){ function ApproveTx(){
if (typeof foobar == 'undefined') { if (typeof foobar == 'undefined') {
@ -571,6 +578,7 @@ func TestContextIsCleared(t *testing.T) {
} }
func TestSignData(t *testing.T) { func TestSignData(t *testing.T) {
t.Parallel()
js := `function ApproveListing(){ js := `function ApproveListing(){
return "Approve" return "Approve"
} }

View file

@ -30,6 +30,7 @@ import (
) )
func TestEncryption(t *testing.T) { func TestEncryption(t *testing.T) {
t.Parallel()
// key := []byte("AES256Key-32Characters1234567890") // key := []byte("AES256Key-32Characters1234567890")
// plaintext := []byte(value) // plaintext := []byte(value)
key := []byte("AES256Key-32Characters1234567890") key := []byte("AES256Key-32Characters1234567890")
@ -52,6 +53,7 @@ func TestEncryption(t *testing.T) {
} }
func TestFileStorage(t *testing.T) { func TestFileStorage(t *testing.T) {
t.Parallel()
a := map[string]storedCredential{ a := map[string]storedCredential{
"secret": { "secret": {
Iv: common.Hex2Bytes("cdb30036279601aeee60f16b"), Iv: common.Hex2Bytes("cdb30036279601aeee60f16b"),
@ -90,6 +92,7 @@ func TestFileStorage(t *testing.T) {
} }
} }
func TestEnd2End(t *testing.T) { func TestEnd2End(t *testing.T) {
t.Parallel()
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(colorable.NewColorableStderr(), slog.LevelInfo, true))) log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(colorable.NewColorableStderr(), slog.LevelInfo, true)))
d := t.TempDir() d := t.TempDir()
@ -110,6 +113,7 @@ func TestEnd2End(t *testing.T) {
} }
func TestSwappedKeys(t *testing.T) { func TestSwappedKeys(t *testing.T) {
t.Parallel()
// It should not be possible to swap the keys/values, so that // It should not be possible to swap the keys/values, so that
// K1:V1, K2:V2 can be swapped into K1:V2, K2:V1 // K1:V1, K2:V2 can be swapped into K1:V2, K2:V1
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(colorable.NewColorableStderr(), slog.LevelInfo, true))) log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(colorable.NewColorableStderr(), slog.LevelInfo, true)))

View file

@ -330,6 +330,12 @@ func (t *BlockTest) validatePostState(statedb *state.StateDB) error {
if nonce2 != acct.Nonce { if nonce2 != acct.Nonce {
return fmt.Errorf("account nonce mismatch for addr: %s want: %d have: %d", addr, acct.Nonce, nonce2) return fmt.Errorf("account nonce mismatch for addr: %s want: %d have: %d", addr, acct.Nonce, nonce2)
} }
for k, v := range acct.Storage {
v2 := statedb.GetState(addr, k)
if v2 != v {
return fmt.Errorf("account storage mismatch for addr: %s, slot: %x, want: %x, have: %x", addr, k, v, v2)
}
}
} }
return nil return nil
} }

View file

@ -145,6 +145,7 @@ type nodeIterator struct {
err error // Failure set in case of an internal error in the iterator err error // Failure set in case of an internal error in the iterator
resolver NodeResolver // optional node resolver for avoiding disk hits resolver NodeResolver // optional node resolver for avoiding disk hits
pool []*nodeIteratorState // local pool for iteratorstates
} }
// errIteratorEnd is stored in nodeIterator.err when iteration is done. // errIteratorEnd is stored in nodeIterator.err when iteration is done.
@ -172,6 +173,24 @@ func newNodeIterator(trie *Trie, start []byte) NodeIterator {
return it return it
} }
func (it *nodeIterator) putInPool(item *nodeIteratorState) {
if len(it.pool) < 40 {
item.node = nil
it.pool = append(it.pool, item)
}
}
func (it *nodeIterator) getFromPool() *nodeIteratorState {
idx := len(it.pool) - 1
if idx < 0 {
return new(nodeIteratorState)
}
el := it.pool[idx]
it.pool[idx] = nil
it.pool = it.pool[:idx]
return el
}
func (it *nodeIterator) AddResolver(resolver NodeResolver) { func (it *nodeIterator) AddResolver(resolver NodeResolver) {
it.resolver = resolver it.resolver = resolver
} }
@ -423,8 +442,9 @@ func (st *nodeIteratorState) resolve(it *nodeIterator, path []byte) error {
return nil return nil
} }
func findChild(n *fullNode, index int, path []byte, ancestor common.Hash) (node, *nodeIteratorState, []byte, int) { func (it *nodeIterator) findChild(n *fullNode, index int, ancestor common.Hash) (node, *nodeIteratorState, []byte, int) {
var ( var (
path = it.path
child node child node
state *nodeIteratorState state *nodeIteratorState
childPath []byte childPath []byte
@ -433,13 +453,12 @@ func findChild(n *fullNode, index int, path []byte, ancestor common.Hash) (node,
if n.Children[index] != nil { if n.Children[index] != nil {
child = n.Children[index] child = n.Children[index]
hash, _ := child.cache() hash, _ := child.cache()
state = &nodeIteratorState{ state = it.getFromPool()
hash: common.BytesToHash(hash), state.hash = common.BytesToHash(hash)
node: child, state.node = child
parent: ancestor, state.parent = ancestor
index: -1, state.index = -1
pathlen: len(path), state.pathlen = len(path)
}
childPath = append(childPath, path...) childPath = append(childPath, path...)
childPath = append(childPath, byte(index)) childPath = append(childPath, byte(index))
return child, state, childPath, index return child, state, childPath, index
@ -452,7 +471,7 @@ func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Has
switch node := parent.node.(type) { switch node := parent.node.(type) {
case *fullNode: case *fullNode:
// Full node, move to the first non-nil child. // Full node, move to the first non-nil child.
if child, state, path, index := findChild(node, parent.index+1, it.path, ancestor); child != nil { if child, state, path, index := it.findChild(node, parent.index+1, ancestor); child != nil {
parent.index = index - 1 parent.index = index - 1
return state, path, true return state, path, true
} }
@ -460,13 +479,12 @@ func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Has
// Short node, return the pointer singleton child // Short node, return the pointer singleton child
if parent.index < 0 { if parent.index < 0 {
hash, _ := node.Val.cache() hash, _ := node.Val.cache()
state := &nodeIteratorState{ state := it.getFromPool()
hash: common.BytesToHash(hash), state.hash = common.BytesToHash(hash)
node: node.Val, state.node = node.Val
parent: ancestor, state.parent = ancestor
index: -1, state.index = -1
pathlen: len(it.path), state.pathlen = len(it.path)
}
path := append(it.path, node.Key...) path := append(it.path, node.Key...)
return state, path, true return state, path, true
} }
@ -480,7 +498,7 @@ func (it *nodeIterator) nextChildAt(parent *nodeIteratorState, ancestor common.H
switch n := parent.node.(type) { switch n := parent.node.(type) {
case *fullNode: case *fullNode:
// Full node, move to the first non-nil child before the desired key position // Full node, move to the first non-nil child before the desired key position
child, state, path, index := findChild(n, parent.index+1, it.path, ancestor) child, state, path, index := it.findChild(n, parent.index+1, ancestor)
if child == nil { if child == nil {
// No more children in this fullnode // No more children in this fullnode
return parent, it.path, false return parent, it.path, false
@ -492,7 +510,7 @@ func (it *nodeIterator) nextChildAt(parent *nodeIteratorState, ancestor common.H
} }
// The child is before the seek position. Try advancing // The child is before the seek position. Try advancing
for { for {
nextChild, nextState, nextPath, nextIndex := findChild(n, index+1, it.path, ancestor) nextChild, nextState, nextPath, nextIndex := it.findChild(n, index+1, ancestor)
// If we run out of children, or skipped past the target, return the // If we run out of children, or skipped past the target, return the
// previous one // previous one
if nextChild == nil || bytes.Compare(nextPath, key) >= 0 { if nextChild == nil || bytes.Compare(nextPath, key) >= 0 {
@ -506,13 +524,12 @@ func (it *nodeIterator) nextChildAt(parent *nodeIteratorState, ancestor common.H
// Short node, return the pointer singleton child // Short node, return the pointer singleton child
if parent.index < 0 { if parent.index < 0 {
hash, _ := n.Val.cache() hash, _ := n.Val.cache()
state := &nodeIteratorState{ state := it.getFromPool()
hash: common.BytesToHash(hash), state.hash = common.BytesToHash(hash)
node: n.Val, state.node = n.Val
parent: ancestor, state.parent = ancestor
index: -1, state.index = -1
pathlen: len(it.path), state.pathlen = len(it.path)
}
path := append(it.path, n.Key...) path := append(it.path, n.Key...)
return state, path, true return state, path, true
} }
@ -533,6 +550,8 @@ func (it *nodeIterator) pop() {
it.path = it.path[:last.pathlen] it.path = it.path[:last.pathlen]
it.stack[len(it.stack)-1] = nil it.stack[len(it.stack)-1] = nil
it.stack = it.stack[:len(it.stack)-1] it.stack = it.stack[:len(it.stack)-1]
// last is now unused
it.putInPool(last)
} }
func compareNodes(a, b NodeIterator) int { func compareNodes(a, b NodeIterator) int {

View file

@ -616,3 +616,15 @@ func isTrieNode(scheme string, key, val []byte) (bool, []byte, common.Hash) {
} }
return true, path, hash return true, path, hash
} }
func BenchmarkIterator(b *testing.B) {
diskDb, srcDb, tr, _ := makeTestTrie(rawdb.HashScheme)
root := tr.Hash()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
if err := checkTrieConsistency(diskDb, srcDb.Scheme(), root, false); err != nil {
b.Fatal(err)
}
}
}

View file

@ -19,6 +19,7 @@ package trie
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"math/rand"
"testing" "testing"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -571,7 +572,7 @@ func testIncompleteSync(t *testing.T, scheme string) {
hash := crypto.Keccak256Hash(result.Data) hash := crypto.Keccak256Hash(result.Data)
if hash != root { if hash != root {
addedKeys = append(addedKeys, result.Path) addedKeys = append(addedKeys, result.Path)
addedHashes = append(addedHashes, crypto.Keccak256Hash(result.Data)) addedHashes = append(addedHashes, hash)
} }
} }
// Fetch the next batch to retrieve // Fetch the next batch to retrieve
@ -587,6 +588,10 @@ func testIncompleteSync(t *testing.T, scheme string) {
} }
// Sanity check that removing any node from the database is detected // Sanity check that removing any node from the database is detected
for i, path := range addedKeys { for i, path := range addedKeys {
if rand.Int31n(100) > 5 {
// Only check 5 percent of added keys as a sanity check
continue
}
owner, inner := ResolvePath([]byte(path)) owner, inner := ResolvePath([]byte(path))
nodeHash := addedHashes[i] nodeHash := addedHashes[i]
value := rawdb.ReadTrieNode(diskdb, owner, inner, nodeHash, scheme) value := rawdb.ReadTrieNode(diskdb, owner, inner, nodeHash, scheme)