mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
Merge branch 'master' into slog
This commit is contained in:
commit
77b6db7b45
96 changed files with 585 additions and 174 deletions
|
|
@ -4,7 +4,7 @@ ARG VERSION=""
|
|||
ARG BUILDNUM=""
|
||||
|
||||
# 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
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ func (arguments Arguments) isTuple() bool {
|
|||
func (arguments Arguments) Unpack(data []byte) ([]interface{}, error) {
|
||||
if len(data) == 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
|
||||
}
|
||||
|
|
@ -95,7 +95,7 @@ func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte)
|
|||
}
|
||||
if len(data) == 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -846,7 +846,7 @@ func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error {
|
|||
defer b.mu.Unlock()
|
||||
|
||||
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
|
||||
block := b.blockchain.GetBlockByHash(b.pendingBlock.ParentHash())
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ func TestWaitDeployedCornerCases(t *testing.T) {
|
|||
backend.Commit()
|
||||
notContentCreation := errors.New("tx is not contract creation")
|
||||
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.
|
||||
|
|
@ -131,7 +131,7 @@ func TestWaitDeployedCornerCases(t *testing.T) {
|
|||
go func() {
|
||||
contextCanceled := errors.New("context canceled")
|
||||
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)
|
||||
}
|
||||
}()
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package abi
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
|
@ -84,10 +83,10 @@ func (e Error) String() string {
|
|||
|
||||
func (e *Error) Unpack(data []byte) (interface{}, error) {
|
||||
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]) {
|
||||
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:])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,15 +117,6 @@ func NewMethod(name string, rawName string, funType FunctionType, mutability str
|
|||
sig = fmt.Sprintf("%v(%v)", rawName, strings.Join(types, ","))
|
||||
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)
|
||||
switch funType {
|
||||
case Fallback:
|
||||
|
|
@ -135,7 +126,14 @@ func NewMethod(name string, rawName string, funType FunctionType, mutability str
|
|||
case 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{
|
||||
Name: name,
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ func packElement(t Type, reflectValue reflect.Value) ([]byte, error) {
|
|||
reflectValue = mustArrayToByteSlice(reflectValue)
|
||||
}
|
||||
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
|
||||
case FixedBytesTy, FunctionTy:
|
||||
|
|
@ -66,7 +66,7 @@ func packElement(t Type, reflectValue reflect.Value) ([]byte, error) {
|
|||
}
|
||||
return common.RightPadBytes(reflectValue.Bytes(), 32), nil
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ func setSlice(dst, src reflect.Value) error {
|
|||
dst.Set(slice)
|
||||
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 {
|
||||
|
|
@ -155,7 +155,7 @@ func setArray(dst, src reflect.Value) error {
|
|||
dst.Set(array)
|
||||
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 {
|
||||
|
|
@ -163,7 +163,7 @@ func setStruct(dst, src reflect.Value) error {
|
|||
srcField := src.Field(i)
|
||||
dstField := dst.Field(i)
|
||||
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 {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -206,13 +206,13 @@ var unpackTests = []unpackTest{
|
|||
def: `[{"type":"bool"}]`,
|
||||
enc: "",
|
||||
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}]`,
|
||||
enc: "",
|
||||
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}]`,
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ func waitWatcherStart(ks *KeyStore) bool {
|
|||
|
||||
func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error {
|
||||
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()
|
||||
if reflect.DeepEqual(list, wantAccounts) {
|
||||
// ks should have also received change notifications
|
||||
|
|
@ -350,7 +350,7 @@ func TestUpdatedKeyfileContents(t *testing.T) {
|
|||
return
|
||||
}
|
||||
// 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
|
||||
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
|
||||
time.Sleep(time.Second)
|
||||
os.Chtimes(file, time.Now().Add(-time.Second), time.Now().Add(-time.Second))
|
||||
|
||||
// Now replace file contents again
|
||||
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
|
||||
time.Sleep(time.Second)
|
||||
os.Chtimes(file, time.Now().Add(-time.Second), time.Now().Add(-time.Second))
|
||||
|
||||
// Now replace file contents with crap
|
||||
if err := os.WriteFile(file, []byte("foo"), 0600); err != nil {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ func TestKeyEncryptDecrypt(t *testing.T) {
|
|||
// Recrypt with a new password and start over
|
||||
password += "new data appended" // nolint: gosec
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ func (w *watcher) loop() {
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
log.Info("Filsystem watcher error", "err", err)
|
||||
log.Info("Filesystem watcher error", "err", err)
|
||||
case <-debounce.C:
|
||||
w.ac.scanAccounts()
|
||||
rescanTriggered = false
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
parts := strings.SplitN(account.URL.Path, "/", 2)
|
||||
if len(parts) != 2 {
|
||||
url, path, found := strings.Cut(account.URL.Path, "/")
|
||||
if !found {
|
||||
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 accounts.ParseDerivationPath(parts[1])
|
||||
return accounts.ParseDerivationPath(path)
|
||||
}
|
||||
|
||||
// Session represents a secured communication session with the wallet.
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func TestURLMarshalJSON(t *testing.T) {
|
|||
url := URL{Scheme: "https", Path: "ethereum.org"}
|
||||
json, err := url.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Errorf("unexpcted error: %v", err)
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if string(json) != "\"https://ethereum.org\"" {
|
||||
t.Errorf("expected: %v, got: %v", "\"https://ethereum.org\"", string(json))
|
||||
|
|
@ -66,7 +66,7 @@ func TestURLUnmarshalJSON(t *testing.T) {
|
|||
url := &URL{}
|
||||
err := url.UnmarshalJSON([]byte("\"https://ethereum.org\""))
|
||||
if err != nil {
|
||||
t.Errorf("unexpcted error: %v", err)
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if url.Scheme != "https" {
|
||||
t.Errorf("expected: %v, got: %v", "https", url.Scheme)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
)
|
||||
|
||||
func TestNameFilter(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := newNameFilter("Foo")
|
||||
require.Error(t, err)
|
||||
_, err = newNameFilter("too/many:colons:Foo")
|
||||
|
|
|
|||
|
|
@ -26,12 +26,13 @@ import (
|
|||
|
||||
// TestImportRaw tests clef --importraw
|
||||
func TestImportRaw(t *testing.T) {
|
||||
t.Parallel()
|
||||
keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name()))
|
||||
os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777)
|
||||
t.Cleanup(func() { os.Remove(keyPath) })
|
||||
|
||||
t.Parallel()
|
||||
t.Run("happy-path", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Run clef importraw
|
||||
clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath)
|
||||
clef.input("myverylongpassword").input("myverylongpassword")
|
||||
|
|
@ -43,6 +44,7 @@ func TestImportRaw(t *testing.T) {
|
|||
})
|
||||
// tests clef --importraw with mismatched passwords.
|
||||
t.Run("pw-mismatch", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Run clef importraw
|
||||
clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath)
|
||||
clef.input("myverylongpassword1").input("myverylongpassword2").WaitExit()
|
||||
|
|
@ -52,6 +54,7 @@ func TestImportRaw(t *testing.T) {
|
|||
})
|
||||
// tests clef --importraw with a too short password.
|
||||
t.Run("short-pw", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Run clef importraw
|
||||
clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath)
|
||||
clef.input("shorty").input("shorty").WaitExit()
|
||||
|
|
@ -64,12 +67,13 @@ func TestImportRaw(t *testing.T) {
|
|||
|
||||
// TestListAccounts tests clef --list-accounts
|
||||
func TestListAccounts(t *testing.T) {
|
||||
t.Parallel()
|
||||
keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name()))
|
||||
os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777)
|
||||
t.Cleanup(func() { os.Remove(keyPath) })
|
||||
|
||||
t.Parallel()
|
||||
t.Run("no-accounts", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "list-accounts")
|
||||
if out := string(clef.Output()); !strings.Contains(out, "The keystore is empty.") {
|
||||
t.Logf("Output\n%v", out)
|
||||
|
|
@ -77,6 +81,7 @@ func TestListAccounts(t *testing.T) {
|
|||
}
|
||||
})
|
||||
t.Run("one-account", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// First, we need to import
|
||||
clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath)
|
||||
clef.input("myverylongpassword").input("myverylongpassword").WaitExit()
|
||||
|
|
@ -91,12 +96,13 @@ func TestListAccounts(t *testing.T) {
|
|||
|
||||
// TestListWallets tests clef --list-wallets
|
||||
func TestListWallets(t *testing.T) {
|
||||
t.Parallel()
|
||||
keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name()))
|
||||
os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777)
|
||||
t.Cleanup(func() { os.Remove(keyPath) })
|
||||
|
||||
t.Parallel()
|
||||
t.Run("no-accounts", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "list-wallets")
|
||||
if out := string(clef.Output()); !strings.Contains(out, "There are no wallets.") {
|
||||
t.Logf("Output\n%v", out)
|
||||
|
|
@ -104,6 +110,7 @@ func TestListWallets(t *testing.T) {
|
|||
}
|
||||
})
|
||||
t.Run("one-account", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// First, we need to import
|
||||
clef := runClef(t, "--suppress-bootwarn", "--lightkdf", "importraw", keyPath)
|
||||
clef.input("myverylongpassword").input("myverylongpassword").WaitExit()
|
||||
|
|
|
|||
|
|
@ -582,6 +582,7 @@ func accountImport(c *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
if first != second {
|
||||
//lint:ignore ST1005 This is a message for the user
|
||||
return errors.New("Passwords do not match")
|
||||
}
|
||||
acc, err := internalApi.ImportRawKey(hex.EncodeToString(crypto.FromECDSA(pKey)), first)
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ func discv4Crawl(ctx *cli.Context) error {
|
|||
func discv4Test(ctx *cli.Context) error {
|
||||
// Configure test package globals.
|
||||
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.Listen1 = ctx.String(testListen1Flag.Name)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import (
|
|||
// This test checks that computeChanges/splitChanges create DNS changes in
|
||||
// leaf-added -> root-changed -> leaf-deleted order.
|
||||
func TestRoute53ChangeSort(t *testing.T) {
|
||||
t.Parallel()
|
||||
testTree0 := map[string]recordSet{
|
||||
"2kfjogvxdqtxxugbh7gs7naaai.n": {ttl: 3333, values: []string{
|
||||
`"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.
|
||||
func TestRoute53NoChange(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Existing record set.
|
||||
testTree0 := map[string]recordSet{
|
||||
"n": {ttl: rootTTL, values: []string{
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import (
|
|||
// TestEthProtocolNegotiation tests whether the test suite
|
||||
// can negotiate the highest eth protocol in a status message exchange
|
||||
func TestEthProtocolNegotiation(t *testing.T) {
|
||||
t.Parallel()
|
||||
var tests = []struct {
|
||||
conn *Conn
|
||||
caps []p2p.Cap
|
||||
|
|
@ -125,6 +126,7 @@ func TestEthProtocolNegotiation(t *testing.T) {
|
|||
// TestChain_GetHeaders tests whether the test suite can correctly
|
||||
// respond to a GetBlockHeaders request from a node.
|
||||
func TestChain_GetHeaders(t *testing.T) {
|
||||
t.Parallel()
|
||||
chainFile, err := filepath.Abs("./testdata/chain.rlp")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
|
|||
|
|
@ -683,7 +683,7 @@ func (s *Suite) snapGetTrieNodes(t *utesting.T, tc *trieNodesTest) error {
|
|||
hash := make([]byte, 32)
|
||||
trienodes := res.Nodes
|
||||
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 {
|
||||
hasher.Reset()
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ var (
|
|||
)
|
||||
|
||||
func TestEthSuite(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth, err := runGeth()
|
||||
if err != nil {
|
||||
t.Fatalf("could not run geth: %v", err)
|
||||
|
|
@ -56,6 +57,7 @@ func TestEthSuite(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSnapSuite(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth, err := runGeth()
|
||||
if err != nil {
|
||||
t.Fatalf("could not run geth: %v", err)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
)
|
||||
|
||||
func TestMessageSignVerify(t *testing.T) {
|
||||
t.Parallel()
|
||||
tmpdir := t.TempDir()
|
||||
|
||||
keyfile := filepath.Join(tmpdir, "the-keyfile")
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ var RunFlag = &cli.StringFlag{
|
|||
var blockTestCommand = &cli.Command{
|
||||
Action: blockTestCmd,
|
||||
Name: "blocktest",
|
||||
Usage: "executes the given blockchain tests",
|
||||
Usage: "Executes the given blockchain tests",
|
||||
ArgsUsage: "<file>",
|
||||
Flags: []cli.Flag{RunFlag},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import (
|
|||
var compileCommand = &cli.Command{
|
||||
Action: compileCmd,
|
||||
Name: "compile",
|
||||
Usage: "compiles easm source to evm binary",
|
||||
Usage: "Compiles easm source to evm binary",
|
||||
ArgsUsage: "<file>",
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import (
|
|||
var disasmCommand = &cli.Command{
|
||||
Action: disasmCmd,
|
||||
Name: "disasm",
|
||||
Usage: "disassembles evm binary",
|
||||
Usage: "Disassembles evm binary",
|
||||
ArgsUsage: "<file>",
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ var (
|
|||
var stateTransitionCommand = &cli.Command{
|
||||
Name: "transition",
|
||||
Aliases: []string{"t8n"},
|
||||
Usage: "executes a full state transition",
|
||||
Usage: "Executes a full state transition",
|
||||
Action: t8ntool.Transition,
|
||||
Flags: []cli.Flag{
|
||||
t8ntool.TraceFlag,
|
||||
|
|
@ -165,7 +165,7 @@ var stateTransitionCommand = &cli.Command{
|
|||
var transactionCommand = &cli.Command{
|
||||
Name: "transaction",
|
||||
Aliases: []string{"t9n"},
|
||||
Usage: "performs transaction validation",
|
||||
Usage: "Performs transaction validation",
|
||||
Action: t8ntool.Transaction,
|
||||
Flags: []cli.Flag{
|
||||
t8ntool.InputTxsFlag,
|
||||
|
|
@ -178,7 +178,7 @@ var transactionCommand = &cli.Command{
|
|||
var blockBuilderCommand = &cli.Command{
|
||||
Name: "block-builder",
|
||||
Aliases: []string{"b11r"},
|
||||
Usage: "builds a block",
|
||||
Usage: "Builds a block",
|
||||
Action: t8ntool.BuildBlock,
|
||||
Flags: []cli.Flag{
|
||||
t8ntool.OutputBasedir,
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ import (
|
|||
var runCommand = &cli.Command{
|
||||
Action: runCmd,
|
||||
Name: "run",
|
||||
Usage: "run arbitrary evm binary",
|
||||
Usage: "Run arbitrary evm binary",
|
||||
ArgsUsage: "<code>",
|
||||
Description: `The run command runs arbitrary EVM code.`,
|
||||
Flags: flags.Merge(vmFlags, traceFlags),
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ func (args *t8nOutput) get() (out []string) {
|
|||
}
|
||||
|
||||
func TestT8n(t *testing.T) {
|
||||
t.Parallel()
|
||||
tt := new(testT8n)
|
||||
tt.TestCmd = cmdtest.NewTestCmd(t, tt)
|
||||
for i, tc := range []struct {
|
||||
|
|
@ -338,6 +339,7 @@ func (args *t9nInput) get(base string) []string {
|
|||
}
|
||||
|
||||
func TestT9n(t *testing.T) {
|
||||
t.Parallel()
|
||||
tt := new(testT8n)
|
||||
tt.TestCmd = cmdtest.NewTestCmd(t, tt)
|
||||
for i, tc := range []struct {
|
||||
|
|
@ -473,6 +475,7 @@ func (args *b11rInput) get(base string) []string {
|
|||
}
|
||||
|
||||
func TestB11r(t *testing.T) {
|
||||
t.Parallel()
|
||||
tt := new(testT8n)
|
||||
tt.TestCmd = cmdtest.NewTestCmd(t, tt)
|
||||
for i, tc := range []struct {
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ func newFaucet(genesis *core.Genesis, port int, enodes []*enode.Node, network ui
|
|||
|
||||
lesBackend, err := les.New(stack, &cfg)
|
||||
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'
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
)
|
||||
|
||||
func TestFacebook(t *testing.T) {
|
||||
t.Parallel()
|
||||
// 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")
|
||||
for _, tt := range []struct {
|
||||
|
|
|
|||
|
|
@ -43,11 +43,13 @@ func tmpDatadirWithKeystore(t *testing.T) string {
|
|||
}
|
||||
|
||||
func TestAccountListEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth := runGeth(t, "account", "list")
|
||||
geth.ExpectExit()
|
||||
}
|
||||
|
||||
func TestAccountList(t *testing.T) {
|
||||
t.Parallel()
|
||||
datadir := tmpDatadirWithKeystore(t)
|
||||
var want = `
|
||||
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) {
|
||||
t.Parallel()
|
||||
geth := runGeth(t, "account", "new", "--lightkdf")
|
||||
defer geth.ExpectExit()
|
||||
geth.Expect(`
|
||||
|
|
@ -96,6 +99,7 @@ Path of the secret key file: .*UTC--.+--[0-9a-f]{40}
|
|||
}
|
||||
|
||||
func TestAccountImport(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct{ name, key, output string }{
|
||||
{
|
||||
name: "correct account",
|
||||
|
|
@ -118,6 +122,7 @@ func TestAccountImport(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAccountHelp(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth := runGeth(t, "account", "-h")
|
||||
geth.WaitExit()
|
||||
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) {
|
||||
t.Parallel()
|
||||
geth := runGeth(t, "account", "new", "--lightkdf")
|
||||
defer geth.ExpectExit()
|
||||
geth.Expect(`
|
||||
|
|
@ -159,6 +165,7 @@ Fatal: Passwords do not match
|
|||
}
|
||||
|
||||
func TestAccountUpdate(t *testing.T) {
|
||||
t.Parallel()
|
||||
datadir := tmpDatadirWithKeystore(t)
|
||||
geth := runGeth(t, "account", "update",
|
||||
"--datadir", datadir, "--lightkdf",
|
||||
|
|
@ -175,6 +182,7 @@ Repeat password: {{.InputLine "foobar2"}}
|
|||
}
|
||||
|
||||
func TestWalletImport(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
|
||||
defer geth.ExpectExit()
|
||||
geth.Expect(`
|
||||
|
|
@ -190,6 +198,7 @@ Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f}
|
|||
}
|
||||
|
||||
func TestWalletImportBadPassword(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
|
||||
defer geth.ExpectExit()
|
||||
geth.Expect(`
|
||||
|
|
@ -200,6 +209,7 @@ Fatal: could not decrypt key with given password
|
|||
}
|
||||
|
||||
func TestUnlockFlag(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "console", "--exec", "loadScript('testdata/empty.js')")
|
||||
geth.Expect(`
|
||||
|
|
@ -222,6 +232,7 @@ undefined
|
|||
}
|
||||
|
||||
func TestUnlockFlagWrongPassword(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--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
|
||||
func TestUnlockFlagMultiIndex(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--unlock", "0,2", "console", "--exec", "loadScript('testdata/empty.js')")
|
||||
|
||||
|
|
@ -266,6 +278,7 @@ undefined
|
|||
}
|
||||
|
||||
func TestUnlockFlagPasswordFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--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) {
|
||||
t.Parallel()
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--password",
|
||||
"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) {
|
||||
t.Parallel()
|
||||
store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--keystore",
|
||||
|
|
@ -336,6 +351,7 @@ undefined
|
|||
}
|
||||
|
||||
func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) {
|
||||
t.Parallel()
|
||||
store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--keystore",
|
||||
|
|
|
|||
|
|
@ -224,14 +224,21 @@ func initGenesis(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) {
|
||||
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 {
|
||||
utils.Fatalf("could not encode genesis: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// dump whatever already exists in the datadir
|
||||
stack, _ := makeConfigNode(ctx)
|
||||
for _, name := range []string{"chaindata", "lightchaindata"} {
|
||||
|
|
@ -256,7 +263,7 @@ func dumpGenesis(ctx *cli.Context) error {
|
|||
if ctx.IsSet(utils.DataDirFlag.Name) {
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// then terminated by closing the input stream.
|
||||
func TestConsoleWelcome(t *testing.T) {
|
||||
t.Parallel()
|
||||
coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182"
|
||||
|
||||
// Start a geth console, make sure it's cleaned up and terminate the console
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
|
||||
// TestExport does a basic test of "geth export", exporting the test-genesis.
|
||||
func TestExport(t *testing.T) {
|
||||
t.Parallel()
|
||||
outfile := fmt.Sprintf("%v/testExport.out", os.TempDir())
|
||||
defer os.Remove(outfile)
|
||||
geth := runGeth(t, "--datadir", initGeth(t), "export", outfile)
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ func startClient(t *testing.T, name string) *gethrpc {
|
|||
}
|
||||
|
||||
func TestPriorityClient(t *testing.T) {
|
||||
t.Parallel()
|
||||
lightServer := startLightServer(t)
|
||||
defer lightServer.killAndWait()
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ func censor(input string, start, end int) string {
|
|||
}
|
||||
|
||||
func TestLogging(t *testing.T) {
|
||||
t.Parallel()
|
||||
testConsoleLogging(t, "terminal", 6, 24)
|
||||
testConsoleLogging(t, "logfmt", 2, 26)
|
||||
}
|
||||
|
|
@ -98,6 +99,7 @@ func testConsoleLogging(t *testing.T, format string, tStart, tEnd int) {
|
|||
}
|
||||
|
||||
func TestVmodule(t *testing.T) {
|
||||
t.Parallel()
|
||||
checkOutput := func(level int, want, wantNot string) {
|
||||
t.Helper()
|
||||
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) {
|
||||
t.Parallel()
|
||||
var (
|
||||
have, want []byte
|
||||
err error
|
||||
|
|
@ -165,6 +168,7 @@ func TestFileOut(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRotatingFileOut(t *testing.T) {
|
||||
t.Parallel()
|
||||
var (
|
||||
have, want []byte
|
||||
err error
|
||||
|
|
|
|||
|
|
@ -30,14 +30,17 @@ import (
|
|||
)
|
||||
|
||||
func TestVerification(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Signatures generated with `minisign`. Legacy format, not pre-hashed file.
|
||||
t.Run("minisig-legacy", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// 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' )
|
||||
pub := "RWQkliYstQBOKOdtClfgC3IypIPX6TAmoEi7beZ4gyR3wsaezvqOMWsp"
|
||||
testVerification(t, pub, "./testdata/vcheck/minisig-sigs/")
|
||||
})
|
||||
t.Run("minisig-new", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// 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' )
|
||||
// `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`
|
||||
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")
|
||||
// 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' )
|
||||
|
|
@ -97,6 +101,7 @@ func versionUint(v string) int {
|
|||
|
||||
// TestMatching can be used to check that the regexps are correct
|
||||
func TestMatching(t *testing.T) {
|
||||
t.Parallel()
|
||||
data, _ := os.ReadFile("./testdata/vcheck/vulnerabilities.json")
|
||||
var vulns []vulnJson
|
||||
if err := json.Unmarshal(data, &vulns); err != nil {
|
||||
|
|
@ -141,6 +146,7 @@ func TestMatching(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGethPubKeysParseable(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, pubkey := range gethPubKeys {
|
||||
_, err := minisign.NewPublicKey(pubkey)
|
||||
if err != nil {
|
||||
|
|
@ -150,6 +156,7 @@ func TestGethPubKeysParseable(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestKeyID(t *testing.T) {
|
||||
t.Parallel()
|
||||
type args struct {
|
||||
id [8]byte
|
||||
}
|
||||
|
|
@ -163,7 +170,9 @@ func TestKeyID(t *testing.T) {
|
|||
{"third key", args{id: extractKeyId(gethPubKeys[2])}, "FD9813B2D2098484"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
if got := keyID(tt.args.id); got != tt.want {
|
||||
t.Errorf("keyID() = %v, want %v", got, tt.want)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -417,9 +417,7 @@ func rpcNode(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
func rpcSubscribe(client *rpc.Client, out io.Writer, method string, args ...string) error {
|
||||
parts := strings.SplitN(method, "_", 2)
|
||||
namespace := parts[0]
|
||||
method = parts[1]
|
||||
namespace, method, _ := strings.Cut(method, "_")
|
||||
ch := make(chan interface{})
|
||||
subArgs := make([]interface{}, len(args)+1)
|
||||
subArgs[0] = method
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
)
|
||||
|
||||
func TestRoundtrip(t *testing.T) {
|
||||
t.Parallel()
|
||||
for i, want := range []string{
|
||||
"0xf880806482520894d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0a1010000000000000000000000000000000000000000000000000000000000000001801ba0c16787a8e25e941d67691954642876c08f00996163ae7dfadbbfd6cd436f549da06180e5626cae31590f40641fe8f63734316c4bfeb4cdfab6714198c1044d2e28",
|
||||
"0xd5c0d3cb84746573742a2a808213378667617a6f6e6b",
|
||||
|
|
@ -51,6 +52,7 @@ func TestRoundtrip(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTextToRlp(t *testing.T) {
|
||||
t.Parallel()
|
||||
type tc struct {
|
||||
text string
|
||||
want string
|
||||
|
|
|
|||
|
|
@ -460,7 +460,7 @@ func ImportLDBData(db ethdb.Database, f string, startIndex int64, interrupt chan
|
|||
case OpBatchAdd:
|
||||
batch.Put(key, val)
|
||||
default:
|
||||
return fmt.Errorf("unknown op %d\n", op)
|
||||
return fmt.Errorf("unknown op %d", op)
|
||||
}
|
||||
if batch.ValueSize() > ethdb.IdealBatchSize {
|
||||
if err := batch.Write(); err != nil {
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ func testDeletion(t *testing.T, f string) {
|
|||
|
||||
// TestImportFutureFormat tests that we reject unsupported future versions.
|
||||
func TestImportFutureFormat(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := fmt.Sprintf("%v/tempdump-future", os.TempDir())
|
||||
defer func() {
|
||||
os.Remove(f)
|
||||
|
|
|
|||
|
|
@ -1872,11 +1872,26 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
|||
log.Info("Using developer account", "address", developer.Address)
|
||||
|
||||
// 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) {
|
||||
chaindb := tryMakeReadOnlyDatabase(ctx, stack)
|
||||
if rawdb.ReadCanonicalHash(chaindb, 0) != (common.Hash{}) {
|
||||
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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
)
|
||||
|
||||
func Test_SplitTagsFlag(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
args string
|
||||
|
|
@ -55,7 +56,9 @@ func Test_SplitTagsFlag(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
if got := SplitTagsFlag(tt.args); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("splitTagsFlag() = %v, want %v", got, tt.want)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
)
|
||||
|
||||
func TestGetPassPhraseWithList(t *testing.T) {
|
||||
t.Parallel()
|
||||
type args struct {
|
||||
text string
|
||||
confirmation bool
|
||||
|
|
@ -65,7 +66,9 @@ func TestGetPassPhraseWithList(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
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 {
|
||||
t.Errorf("GetPassPhraseWithList() = %v, want %v", got, tt.want)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ func (b *bridge) NewAccount(call jsre.Call) (goja.Value, error) {
|
|||
return nil, err
|
||||
}
|
||||
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
|
||||
case len(call.Arguments) == 1 && call.Argument(0).ToString() != nil:
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ func newTester(t *testing.T, confOverride func(*ethconfig.Config)) *tester {
|
|||
t.Fatalf("failed to create node: %v", err)
|
||||
}
|
||||
ethConf := ðconfig.Config{
|
||||
Genesis: core.DeveloperGenesisBlock(11_500_000, common.Address{}),
|
||||
Genesis: core.DeveloperGenesisBlock(11_500_000, nil),
|
||||
Miner: miner.Config{
|
||||
Etherbase: common.HexToAddress(testAddress),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -366,8 +366,9 @@ func TestValidation(t *testing.T) {
|
|||
// TODO(karalabe): Enable this when Cancun is specced
|
||||
//{params.MainnetChainConfig, 20999999, 1677999999, ID{Hash: checksumToBytes(0x71147644), Next: 1678000000}, ErrLocalIncompatibleOrStale},
|
||||
}
|
||||
genesis := core.DefaultGenesisBlock().ToBlock()
|
||||
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 {
|
||||
t.Errorf("test %d: validation error mismatch: have %v, want %v", i, err, tt.err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -580,16 +580,16 @@ func DefaultHoleskyGenesisBlock() *Genesis {
|
|||
}
|
||||
|
||||
// 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
|
||||
config := *params.AllDevChainProtocolChanges
|
||||
|
||||
// Assemble and return the genesis with the precompiles and faucet pre-funded
|
||||
return &Genesis{
|
||||
genesis := &Genesis{
|
||||
Config: &config,
|
||||
GasLimit: gasLimit,
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
Difficulty: big.NewInt(0),
|
||||
Difficulty: big.NewInt(1),
|
||||
Alloc: map[common.Address]GenesisAccount{
|
||||
common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover
|
||||
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{8}): {Balance: big.NewInt(1)}, // ECPairing
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// error here, as the outer code will presume errors are interrupts, not
|
||||
// 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
|
||||
}
|
||||
// Delete all stale snapshot states remaining
|
||||
|
|
|
|||
|
|
@ -426,10 +426,12 @@ func (test *snapshotTest) run() bool {
|
|||
state, _ = New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||
snapshotRevs = make([]int, len(test.snapshots))
|
||||
sindex = 0
|
||||
checkstates = make([]*StateDB, len(test.snapshots))
|
||||
)
|
||||
for i, action := range test.actions {
|
||||
if len(test.snapshots) > sindex && i == test.snapshots[sindex] {
|
||||
snapshotRevs[sindex] = state.Snapshot()
|
||||
checkstates[sindex] = state.Copy()
|
||||
sindex++
|
||||
}
|
||||
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
|
||||
// that is equivalent to fresh state with all actions up the snapshot applied.
|
||||
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])
|
||||
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)
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// to the add is finished. Only use this during tests for determinism!
|
||||
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
|
||||
var (
|
||||
errs = make([]error, len(txs))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// discards everything cheaper (legacy & dynamic fee) than that and moves any
|
||||
// gapped transactions back from the pending pool to the queue.
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ var (
|
|||
ErrTxTypeNotSupported = errors.New("transaction type not supported")
|
||||
ErrGasFeeCapTooLow = errors.New("fee cap less than base fee")
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -57,18 +57,18 @@ func (tx *txJSON) yParityValue() (*big.Int, error) {
|
|||
if tx.YParity != nil {
|
||||
val := uint64(*tx.YParity)
|
||||
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)
|
||||
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
|
||||
}
|
||||
if tx.V != 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.
|
||||
|
|
@ -294,9 +294,6 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
|
|||
return errors.New("missing required field 'input' in transaction")
|
||||
}
|
||||
itx.Data = *dec.Input
|
||||
if dec.V == nil {
|
||||
return errors.New("missing required field 'v' in transaction")
|
||||
}
|
||||
if dec.AccessList != nil {
|
||||
itx.AccessList = *dec.AccessList
|
||||
}
|
||||
|
|
@ -361,9 +358,6 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
|
|||
return errors.New("missing required field 'input' in transaction")
|
||||
}
|
||||
itx.Data = *dec.Input
|
||||
if dec.V == nil {
|
||||
return errors.New("missing required field 'v' in transaction")
|
||||
}
|
||||
if dec.AccessList != nil {
|
||||
itx.AccessList = *dec.AccessList
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,10 +82,6 @@ type SimulatedBeacon struct {
|
|||
}
|
||||
|
||||
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()
|
||||
current := engine.ForkchoiceStateV1{
|
||||
HeadBlockHash: block.Hash(),
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ func TestSimulatedBeaconSendWithdrawals(t *testing.T) {
|
|||
|
||||
// short period (1 second) for testing purposes
|
||||
var gasLimit uint64 = 10_000_000
|
||||
genesis := core.DeveloperGenesisBlock(gasLimit, testAddr)
|
||||
genesis := core.DeveloperGenesisBlock(gasLimit, &testAddr)
|
||||
node, ethService, mock := startSimulatedBeaconEthService(t, genesis)
|
||||
_ = mock
|
||||
defer node.Close()
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) {
|
|||
|
||||
// special case for pending logs
|
||||
if beginPending && !endPending {
|
||||
return nil, errors.New("invalid block range")
|
||||
return nil, errInvalidBlockRange
|
||||
}
|
||||
|
||||
// Short-cut if all we care about is pending logs
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ func TestFilters(t *testing.T) {
|
|||
},
|
||||
{
|
||||
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())
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ func (db *Database) Len() int {
|
|||
// keyvalue is a key-value tuple tagged with a deletion field to allow creating
|
||||
// memory-database write batches.
|
||||
type keyvalue struct {
|
||||
key []byte
|
||||
key string
|
||||
value []byte
|
||||
delete bool
|
||||
}
|
||||
|
|
@ -222,14 +222,14 @@ type batch struct {
|
|||
|
||||
// Put inserts the given value into the batch for later committing.
|
||||
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)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete inserts the a key removal into the batch for later committing.
|
||||
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)
|
||||
return nil
|
||||
}
|
||||
|
|
@ -249,10 +249,10 @@ func (b *batch) Write() error {
|
|||
}
|
||||
for _, keyvalue := range b.writes {
|
||||
if keyvalue.delete {
|
||||
delete(b.db.db, string(keyvalue.key))
|
||||
delete(b.db.db, keyvalue.key)
|
||||
continue
|
||||
}
|
||||
b.db.db[string(keyvalue.key)] = keyvalue.value
|
||||
b.db.db[keyvalue.key] = keyvalue.value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -267,12 +267,12 @@ func (b *batch) Reset() {
|
|||
func (b *batch) Replay(w ethdb.KeyValueWriter) error {
|
||||
for _, keyvalue := range b.writes {
|
||||
if keyvalue.delete {
|
||||
if err := w.Delete(keyvalue.key); err != nil {
|
||||
if err := w.Delete([]byte(keyvalue.key)); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err := w.Put(keyvalue.key, keyvalue.value); err != nil {
|
||||
if err := w.Put([]byte(keyvalue.key), keyvalue.value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package memorydb
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
"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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -609,9 +609,12 @@ func (b *batch) Replay(w ethdb.KeyValueWriter) error {
|
|||
|
||||
// pebbleIterator is a wrapper of underlying iterator in storage engine.
|
||||
// The purpose of this structure is to implement the missing APIs.
|
||||
//
|
||||
// The pebble iterator is not thread-safe.
|
||||
type pebbleIterator struct {
|
||||
iter *pebble.Iterator
|
||||
moved bool
|
||||
iter *pebble.Iterator
|
||||
moved bool
|
||||
released bool
|
||||
}
|
||||
|
||||
// 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),
|
||||
})
|
||||
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
|
||||
|
|
@ -658,4 +661,9 @@ func (iter *pebbleIterator) Value() []byte {
|
|||
|
||||
// Release releases associated resources. Release should always succeed and can
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1033,7 +1033,7 @@ var formatOutputInt = function (param) {
|
|||
*
|
||||
* @method formatOutputUInt
|
||||
* @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 value = param.staticPart() || "0";
|
||||
|
|
|
|||
|
|
@ -338,7 +338,7 @@ func (h *serverHandler) measure(setup *benchmarkSetup, count int) error {
|
|||
case <-h.closeCh:
|
||||
clientPipe.Close()
|
||||
serverPipe.Close()
|
||||
return errors.New("Benchmark cancelled")
|
||||
return errors.New("benchmark cancelled")
|
||||
}
|
||||
|
||||
setup.totalTime += time.Duration(mclock.Now() - start)
|
||||
|
|
|
|||
|
|
@ -1000,7 +1000,7 @@ func (p *clientPeer) Handshake(td *big.Int, head common.Hash, headNum uint64, ge
|
|||
}
|
||||
}
|
||||
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.
|
||||
// The values announced in the handshake are dummy values for compatibility reasons and should be ignored.
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ func TestHandshake(t *testing.T) {
|
|||
return err
|
||||
}
|
||||
if reqType != announceTypeSigned {
|
||||
return errors.New("Expected announceTypeSigned")
|
||||
return errors.New("expected announceTypeSigned")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ func (vt *ValueTracker) loadFromDb(mapping []string) error {
|
|||
}
|
||||
if version != vtVersion {
|
||||
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
|
||||
if err := rlp.Decode(r, &vte); err != nil {
|
||||
|
|
@ -295,7 +295,7 @@ loop:
|
|||
} else {
|
||||
if vte.RefBasketMapping >= uint(len(vt.mappings)) {
|
||||
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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,5 +23,5 @@ import "errors"
|
|||
|
||||
// ReadDiskStats retrieves the disk IO stats belonging to the current process.
|
||||
func ReadDiskStats(stats *DiskStats) error {
|
||||
return errors.New("Not implemented")
|
||||
return errors.New("not implemented")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ func TestGaugeFloat64Snapshot(t *testing.T) {
|
|||
g.Update(47.0)
|
||||
snapshot := g.Snapshot()
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ func TestGetOrRegisterGaugeFloat64(t *testing.T) {
|
|||
r := NewRegistry()
|
||||
NewRegisteredGaugeFloat64("foo", r).Update(47.0)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent)
|
|||
}
|
||||
|
||||
func TestMiner(t *testing.T) {
|
||||
t.Parallel()
|
||||
miner, mux, cleanup := createMiner(t)
|
||||
defer cleanup(false)
|
||||
|
||||
|
|
@ -128,6 +129,7 @@ func TestMiner(t *testing.T) {
|
|||
// An initial FailedEvent should allow mining to stop on a subsequent
|
||||
// downloader StartEvent.
|
||||
func TestMinerDownloaderFirstFails(t *testing.T) {
|
||||
t.Parallel()
|
||||
miner, mux, cleanup := createMiner(t)
|
||||
defer cleanup(false)
|
||||
|
||||
|
|
@ -161,6 +163,7 @@ func TestMinerDownloaderFirstFails(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMinerStartStopAfterDownloaderEvents(t *testing.T) {
|
||||
t.Parallel()
|
||||
miner, mux, cleanup := createMiner(t)
|
||||
defer cleanup(false)
|
||||
|
||||
|
|
@ -185,6 +188,7 @@ func TestMinerStartStopAfterDownloaderEvents(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestStartWhileDownload(t *testing.T) {
|
||||
t.Parallel()
|
||||
miner, mux, cleanup := createMiner(t)
|
||||
defer cleanup(false)
|
||||
waitForMiningState(t, miner, false)
|
||||
|
|
@ -199,6 +203,7 @@ func TestStartWhileDownload(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestStartStopMiner(t *testing.T) {
|
||||
t.Parallel()
|
||||
miner, _, cleanup := createMiner(t)
|
||||
defer cleanup(false)
|
||||
waitForMiningState(t, miner, false)
|
||||
|
|
@ -209,6 +214,7 @@ func TestStartStopMiner(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCloseMiner(t *testing.T) {
|
||||
t.Parallel()
|
||||
miner, _, cleanup := createMiner(t)
|
||||
defer cleanup(true)
|
||||
waitForMiningState(t, miner, false)
|
||||
|
|
@ -222,6 +228,7 @@ func TestCloseMiner(t *testing.T) {
|
|||
// TestMinerSetEtherbase checks that etherbase becomes set even if mining isn't
|
||||
// possible at the moment
|
||||
func TestMinerSetEtherbase(t *testing.T) {
|
||||
t.Parallel()
|
||||
miner, mux, cleanup := createMiner(t)
|
||||
defer cleanup(false)
|
||||
miner.Start()
|
||||
|
|
|
|||
|
|
@ -30,10 +30,12 @@ import (
|
|||
)
|
||||
|
||||
func TestTransactionPriceNonceSortLegacy(t *testing.T) {
|
||||
t.Parallel()
|
||||
testTransactionPriceNonceSort(t, nil)
|
||||
}
|
||||
|
||||
func TestTransactionPriceNonceSort1559(t *testing.T) {
|
||||
t.Parallel()
|
||||
testTransactionPriceNonceSort(t, big.NewInt(0))
|
||||
testTransactionPriceNonceSort(t, big.NewInt(5))
|
||||
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
|
||||
// are prioritized to avoid network spam attacks aiming for a specific ordering.
|
||||
func TestTransactionTimeSort(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Generate a batch of accounts to start with
|
||||
keys := make([]*ecdsa.PrivateKey, 5)
|
||||
for i := 0; i < len(keys); i++ {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import (
|
|||
)
|
||||
|
||||
func TestBuildPayload(t *testing.T) {
|
||||
t.Parallel()
|
||||
var (
|
||||
db = rawdb.NewMemoryDatabase()
|
||||
recipient = common.HexToAddress("0xdeadbeef")
|
||||
|
|
@ -82,6 +83,7 @@ func TestBuildPayload(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPayloadId(t *testing.T) {
|
||||
t.Parallel()
|
||||
ids := make(map[string]int)
|
||||
for i, tt := range []*BuildPayloadArgs{
|
||||
{
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ func newTestWorker(t *testing.T, chainConfig *params.ChainConfig, engine consens
|
|||
}
|
||||
|
||||
func TestGenerateAndImportBlock(t *testing.T) {
|
||||
t.Parallel()
|
||||
var (
|
||||
db = rawdb.NewMemoryDatabase()
|
||||
config = *params.AllCliqueProtocolChanges
|
||||
|
|
@ -210,9 +211,11 @@ func TestGenerateAndImportBlock(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestEmptyWorkEthash(t *testing.T) {
|
||||
t.Parallel()
|
||||
testEmptyWork(t, ethashChainConfig, ethash.NewFaker())
|
||||
}
|
||||
func TestEmptyWorkClique(t *testing.T) {
|
||||
t.Parallel()
|
||||
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) {
|
||||
t.Parallel()
|
||||
testAdjustInterval(t, ethashChainConfig, ethash.NewFaker())
|
||||
}
|
||||
|
||||
func TestAdjustIntervalClique(t *testing.T) {
|
||||
t.Parallel()
|
||||
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) {
|
||||
t.Parallel()
|
||||
testGetSealingWork(t, ethashChainConfig, ethash.NewFaker())
|
||||
}
|
||||
|
||||
func TestGetSealingWorkClique(t *testing.T) {
|
||||
t.Parallel()
|
||||
testGetSealingWork(t, cliqueChainConfig, clique.New(cliqueChainConfig.Clique, rawdb.NewMemoryDatabase()))
|
||||
}
|
||||
|
||||
func TestGetSealingWorkPostMerge(t *testing.T) {
|
||||
t.Parallel()
|
||||
local := new(params.ChainConfig)
|
||||
*local = *ethashChainConfig
|
||||
local.TerminalTotalDifficulty = big.NewInt(0)
|
||||
|
|
|
|||
|
|
@ -61,12 +61,12 @@ type Interface interface {
|
|||
// "pmp:192.168.0.1" uses NAT-PMP with the given gateway address
|
||||
func Parse(spec string) (Interface, error) {
|
||||
var (
|
||||
parts = strings.SplitN(spec, ":", 2)
|
||||
mech = strings.ToLower(parts[0])
|
||||
ip net.IP
|
||||
before, after, found = strings.Cut(spec, ":")
|
||||
mech = strings.ToLower(before)
|
||||
ip net.IP
|
||||
)
|
||||
if len(parts) > 1 {
|
||||
ip = net.ParseIP(parts[1])
|
||||
if found {
|
||||
ip = net.ParseIP(after)
|
||||
if ip == nil {
|
||||
return nil, errors.New("invalid IP address")
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ func Parse(spec string) (Interface, error) {
|
|||
case "pmp", "natpmp", "nat-pmp":
|
||||
return PMP(ip), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown mechanism %q", parts[0])
|
||||
return nil, fmt.Errorf("unknown mechanism %q", before)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -479,12 +479,12 @@ func (s *Server) StreamNetworkEvents(w http.ResponseWriter, req *http.Request) {
|
|||
func NewMsgFilters(filterParam string) (MsgFilters, error) {
|
||||
filters := make(MsgFilters)
|
||||
for _, filter := range strings.Split(filterParam, "-") {
|
||||
protoCodes := strings.SplitN(filter, ":", 2)
|
||||
if len(protoCodes) != 2 || protoCodes[0] == "" || protoCodes[1] == "" {
|
||||
proto, codes, found := strings.Cut(filter, ":")
|
||||
if !found || proto == "" || codes == "" {
|
||||
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" {
|
||||
filters[MsgFilter{Proto: proto, Code: -1}] = struct{}{}
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -180,7 +180,6 @@ var (
|
|||
ShanghaiTime: newUint64(0),
|
||||
TerminalTotalDifficulty: big.NewInt(0),
|
||||
TerminalTotalDifficultyPassed: true,
|
||||
IsDevMode: true,
|
||||
}
|
||||
|
||||
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
|
||||
|
|
@ -329,9 +328,8 @@ type ChainConfig struct {
|
|||
TerminalTotalDifficultyPassed bool `json:"terminalTotalDifficultyPassed,omitempty"`
|
||||
|
||||
// Various consensus engines
|
||||
Ethash *EthashConfig `json:"ethash,omitempty"`
|
||||
Clique *CliqueConfig `json:"clique,omitempty"`
|
||||
IsDevMode bool `json:"isDev,omitempty"`
|
||||
Ethash *EthashConfig `json:"ethash,omitempty"`
|
||||
Clique *CliqueConfig `json:"clique,omitempty"`
|
||||
}
|
||||
|
||||
// EthashConfig is the consensus engine configs for proof-of-work based sealing.
|
||||
|
|
|
|||
|
|
@ -595,7 +595,7 @@ func TestClientSubscriptionChannelClose(t *testing.T) {
|
|||
|
||||
for i := 0; i < 100; i++ {
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
|||
15
rpc/json.go
15
rpc/json.go
|
|
@ -46,6 +46,17 @@ type subscriptionResult struct {
|
|||
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
|
||||
// error response. Which one it is depends on the fields.
|
||||
type jsonrpcMessage struct {
|
||||
|
|
@ -86,8 +97,8 @@ func (msg *jsonrpcMessage) isUnsubscribe() bool {
|
|||
}
|
||||
|
||||
func (msg *jsonrpcMessage) namespace() string {
|
||||
elem := strings.SplitN(msg.Method, serviceMethodSeparator, 2)
|
||||
return elem[0]
|
||||
before, _, _ := strings.Cut(msg.Method, serviceMethodSeparator)
|
||||
return before
|
||||
}
|
||||
|
||||
func (msg *jsonrpcMessage) String() string {
|
||||
|
|
|
|||
|
|
@ -93,13 +93,13 @@ func (r *serviceRegistry) registerName(name string, rcvr interface{}) error {
|
|||
|
||||
// callback returns the callback corresponding to the given RPC method name.
|
||||
func (r *serviceRegistry) callback(method string) *callback {
|
||||
elem := strings.SplitN(method, serviceMethodSeparator, 2)
|
||||
if len(elem) != 2 {
|
||||
before, after, found := strings.Cut(method, serviceMethodSeparator)
|
||||
if !found {
|
||||
return nil
|
||||
}
|
||||
r.mu.Lock()
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ type Notifier struct {
|
|||
|
||||
mu sync.Mutex
|
||||
sub *Subscription
|
||||
buffer []json.RawMessage
|
||||
buffer []any
|
||||
callReturned 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.
|
||||
// If an error occurs the RPC connection is closed and the error is returned.
|
||||
func (n *Notifier) Notify(id ID, data interface{}) error {
|
||||
enc, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func (n *Notifier) Notify(id ID, data any) error {
|
||||
n.mu.Lock()
|
||||
defer n.mu.Unlock()
|
||||
|
||||
|
|
@ -144,9 +139,9 @@ func (n *Notifier) Notify(id ID, data interface{}) error {
|
|||
panic("Notify with wrong ID")
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
|
|
@ -181,16 +176,16 @@ func (n *Notifier) activate() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (n *Notifier) send(sub *Subscription, data json.RawMessage) error {
|
||||
params, _ := json.Marshal(&subscriptionResult{ID: string(sub.ID), Result: data})
|
||||
ctx := context.Background()
|
||||
|
||||
msg := &jsonrpcMessage{
|
||||
func (n *Notifier) send(sub *Subscription, data any) error {
|
||||
msg := jsonrpcSubscriptionNotification{
|
||||
Version: vsn,
|
||||
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
|
||||
|
|
|
|||
|
|
@ -17,12 +17,19 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"net"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ func list(ui *headlessUi, api *core.SignerAPI, t *testing.T) ([]common.Address,
|
|||
}
|
||||
|
||||
func TestNewAcc(t *testing.T) {
|
||||
t.Parallel()
|
||||
api, control := setup(t)
|
||||
verifyNum := func(num int) {
|
||||
list, err := list(control, api, t)
|
||||
|
|
@ -235,6 +236,7 @@ func mkTestTx(from common.MixedcaseAddress) apitypes.SendTxArgs {
|
|||
}
|
||||
|
||||
func TestSignTx(t *testing.T) {
|
||||
t.Parallel()
|
||||
var (
|
||||
list []common.Address
|
||||
res, res2 *ethapi.SignTransactionResult
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
)
|
||||
|
||||
func TestBytesPadding(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
Type string
|
||||
Input []byte
|
||||
|
|
@ -87,6 +88,7 @@ func TestBytesPadding(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestParseAddress(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
Input interface{}
|
||||
Output []byte // nil => error
|
||||
|
|
@ -136,6 +138,7 @@ func TestParseAddress(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestParseBytes(t *testing.T) {
|
||||
t.Parallel()
|
||||
for i, tt := range []struct {
|
||||
v interface{}
|
||||
exp []byte
|
||||
|
|
@ -170,6 +173,7 @@ func TestParseBytes(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestParseInteger(t *testing.T) {
|
||||
t.Parallel()
|
||||
for i, tt := range []struct {
|
||||
t string
|
||||
v interface{}
|
||||
|
|
@ -200,6 +204,7 @@ func TestParseInteger(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConvertStringDataToSlice(t *testing.T) {
|
||||
t.Parallel()
|
||||
slice := []string{"a", "b", "c"}
|
||||
var it interface{} = slice
|
||||
_, err := convertDataToSlice(it)
|
||||
|
|
@ -209,6 +214,7 @@ func TestConvertStringDataToSlice(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConvertUint256DataToSlice(t *testing.T) {
|
||||
t.Parallel()
|
||||
slice := []*math.HexOrDecimal256{
|
||||
math.NewHexOrDecimal256(1),
|
||||
math.NewHexOrDecimal256(2),
|
||||
|
|
@ -222,6 +228,7 @@ func TestConvertUint256DataToSlice(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConvertAddressDataToSlice(t *testing.T) {
|
||||
t.Parallel()
|
||||
slice := []common.Address{
|
||||
common.HexToAddress("0x0000000000000000000000000000000000000001"),
|
||||
common.HexToAddress("0x0000000000000000000000000000000000000002"),
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package apitypes
|
|||
import "testing"
|
||||
|
||||
func TestIsPrimitive(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Expected positives
|
||||
for i, tc := range []string{
|
||||
"int24", "int24[]", "uint88", "uint88[]", "uint", "uint[]", "int256", "int256[]",
|
||||
|
|
|
|||
|
|
@ -183,6 +183,7 @@ var typedData = apitypes.TypedData{
|
|||
}
|
||||
|
||||
func TestSignData(t *testing.T) {
|
||||
t.Parallel()
|
||||
api, control := setup(t)
|
||||
//Create two accounts
|
||||
createAccount(control, api, t)
|
||||
|
|
@ -248,6 +249,7 @@ func TestSignData(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDomainChainId(t *testing.T) {
|
||||
t.Parallel()
|
||||
withoutChainID := apitypes.TypedData{
|
||||
Types: apitypes.Types{
|
||||
"EIP712Domain": []apitypes.Type{
|
||||
|
|
@ -289,6 +291,7 @@ func TestDomainChainId(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestHashStruct(t *testing.T) {
|
||||
t.Parallel()
|
||||
hash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -309,6 +312,7 @@ func TestHashStruct(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestEncodeType(t *testing.T) {
|
||||
t.Parallel()
|
||||
domainTypeEncoding := string(typedData.EncodeType("EIP712Domain"))
|
||||
if domainTypeEncoding != "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" {
|
||||
t.Errorf("Expected different encodeType result (got %s)", domainTypeEncoding)
|
||||
|
|
@ -321,6 +325,7 @@ func TestEncodeType(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTypeHash(t *testing.T) {
|
||||
t.Parallel()
|
||||
mailTypeHash := fmt.Sprintf("0x%s", common.Bytes2Hex(typedData.TypeHash(typedData.PrimaryType)))
|
||||
if mailTypeHash != "0xa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2" {
|
||||
t.Errorf("Expected different typeHash result (got %s)", mailTypeHash)
|
||||
|
|
@ -328,6 +333,7 @@ func TestTypeHash(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestEncodeData(t *testing.T) {
|
||||
t.Parallel()
|
||||
hash, err := typedData.EncodeData(typedData.PrimaryType, typedData.Message, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -339,6 +345,7 @@ func TestEncodeData(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFormatter(t *testing.T) {
|
||||
t.Parallel()
|
||||
var d apitypes.TypedData
|
||||
err := json.Unmarshal([]byte(jsonTypedData), &d)
|
||||
if err != nil {
|
||||
|
|
@ -368,6 +375,7 @@ func sign(typedData apitypes.TypedData) ([]byte, []byte, error) {
|
|||
}
|
||||
|
||||
func TestJsonFiles(t *testing.T) {
|
||||
t.Parallel()
|
||||
testfiles, err := os.ReadDir("testdata/")
|
||||
if err != nil {
|
||||
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
|
||||
// crashes or hangs.
|
||||
func TestFuzzerFiles(t *testing.T) {
|
||||
t.Parallel()
|
||||
corpusdir := path.Join("testdata", "fuzzing")
|
||||
testfiles, err := os.ReadDir(corpusdir)
|
||||
if err != nil {
|
||||
|
|
@ -514,6 +523,7 @@ var gnosisTx = `
|
|||
// TestGnosisTypedData tests the scenario where a user submits a full EIP-712
|
||||
// struct without using the gnosis-specific endpoint
|
||||
func TestGnosisTypedData(t *testing.T) {
|
||||
t.Parallel()
|
||||
var td apitypes.TypedData
|
||||
err := json.Unmarshal([]byte(gnosisTypedData), &td)
|
||||
if err != nil {
|
||||
|
|
@ -532,6 +542,7 @@ func TestGnosisTypedData(t *testing.T) {
|
|||
// TestGnosisCustomData tests the scenario where a user submits only the gnosis-safe
|
||||
// specific data, and we fill the TypedData struct on our side
|
||||
func TestGnosisCustomData(t *testing.T) {
|
||||
t.Parallel()
|
||||
var tx core.GnosisSafeTx
|
||||
err := json.Unmarshal([]byte(gnosisTx), &tx)
|
||||
if err != nil {
|
||||
|
|
@ -644,6 +655,7 @@ var gnosisTxWithChainId = `
|
|||
`
|
||||
|
||||
func TestGnosisTypedDataWithChainId(t *testing.T) {
|
||||
t.Parallel()
|
||||
var td apitypes.TypedData
|
||||
err := json.Unmarshal([]byte(gnosisTypedDataWithChainId), &td)
|
||||
if err != nil {
|
||||
|
|
@ -662,6 +674,7 @@ func TestGnosisTypedDataWithChainId(t *testing.T) {
|
|||
// TestGnosisCustomData tests the scenario where a user submits only the gnosis-safe
|
||||
// specific data, and we fill the TypedData struct on our side
|
||||
func TestGnosisCustomDataWithChainId(t *testing.T) {
|
||||
t.Parallel()
|
||||
var tx core.GnosisSafeTx
|
||||
err := json.Unmarshal([]byte(gnosisTxWithChainId), &tx)
|
||||
if err != nil {
|
||||
|
|
@ -813,6 +826,7 @@ var complexTypedData = `
|
|||
`
|
||||
|
||||
func TestComplexTypedData(t *testing.T) {
|
||||
t.Parallel()
|
||||
var td apitypes.TypedData
|
||||
err := json.Unmarshal([]byte(complexTypedData), &td)
|
||||
if err != nil {
|
||||
|
|
@ -829,6 +843,7 @@ func TestComplexTypedData(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGnosisSafe(t *testing.T) {
|
||||
t.Parallel()
|
||||
// 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"
|
||||
var gnosisTx core.GnosisSafeTx
|
||||
|
|
@ -984,6 +999,7 @@ var complexTypedDataLCRefType = `
|
|||
`
|
||||
|
||||
func TestComplexTypedDataWithLowercaseReftype(t *testing.T) {
|
||||
t.Parallel()
|
||||
var td apitypes.TypedData
|
||||
err := json.Unmarshal([]byte(complexTypedDataLCRefType), &td)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package core
|
|||
import "testing"
|
||||
|
||||
func TestPasswordValidation(t *testing.T) {
|
||||
t.Parallel()
|
||||
testcases := []struct {
|
||||
pw string
|
||||
shouldFail bool
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ func verify(t *testing.T, jsondata, calldata string, exp []interface{}) {
|
|||
}
|
||||
|
||||
func TestNewUnpacker(t *testing.T) {
|
||||
t.Parallel()
|
||||
type unpackTest struct {
|
||||
jsondata string
|
||||
calldata string
|
||||
|
|
@ -97,6 +98,7 @@ func TestNewUnpacker(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCalldataDecoding(t *testing.T) {
|
||||
t.Parallel()
|
||||
// send(uint256) : a52c101e
|
||||
// compareAndApprove(address,uint256,uint256) : 751e1079
|
||||
// issue(address[],uint256) : 42958b54
|
||||
|
|
@ -159,6 +161,7 @@ func TestCalldataDecoding(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMaliciousABIStrings(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []string{
|
||||
"func(uint256,uint256,[]uint256)",
|
||||
"func(uint256,uint256,uint256,)",
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@
|
|||
package fourbyte
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
|
|
@ -27,18 +27,19 @@ import (
|
|||
|
||||
// Tests that all the selectors contained in the 4byte database are valid.
|
||||
func TestEmbeddedDatabase(t *testing.T) {
|
||||
t.Parallel()
|
||||
db, err := New()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var abistruct abi.ABI
|
||||
for id, selector := range db.embedded {
|
||||
abistring, err := parseSelector(selector)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to convert selector to ABI: %v", err)
|
||||
continue
|
||||
}
|
||||
abistruct, err := abi.JSON(strings.NewReader(string(abistring)))
|
||||
if err != nil {
|
||||
if err := json.Unmarshal(abistring, &abistruct); err != nil {
|
||||
t.Errorf("Failed to parse ABI: %v", err)
|
||||
continue
|
||||
}
|
||||
|
|
@ -55,6 +56,7 @@ func TestEmbeddedDatabase(t *testing.T) {
|
|||
|
||||
// Tests that custom 4byte datasets can be handled too.
|
||||
func TestCustomDatabase(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Create a new custom 4byte database with no embedded component
|
||||
tmpdir := t.TempDir()
|
||||
filename := fmt.Sprintf("%s/4byte_custom.json", tmpdir)
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ type txtestcase struct {
|
|||
}
|
||||
|
||||
func TestTransactionValidation(t *testing.T) {
|
||||
t.Parallel()
|
||||
var (
|
||||
// use empty db, there are other tests for the abi-specific stuff
|
||||
db = newEmpty()
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ func initRuleEngine(js string) (*rulesetUI, error) {
|
|||
}
|
||||
|
||||
func TestListRequest(t *testing.T) {
|
||||
t.Parallel()
|
||||
accs := make([]accounts.Account, 5)
|
||||
|
||||
for i := range accs {
|
||||
|
|
@ -152,6 +153,7 @@ func TestListRequest(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSignTxRequest(t *testing.T) {
|
||||
t.Parallel()
|
||||
js := `
|
||||
function ApproveTx(r){
|
||||
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
|
||||
func TestForwarding(t *testing.T) {
|
||||
t.Parallel()
|
||||
js := ""
|
||||
ui := &dummyUI{make([]string, 0)}
|
||||
jsBackend := storage.NewEphemeralStorage()
|
||||
|
|
@ -271,6 +274,7 @@ func TestForwarding(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMissingFunc(t *testing.T) {
|
||||
t.Parallel()
|
||||
r, err := initRuleEngine(JS)
|
||||
if err != nil {
|
||||
t.Errorf("Couldn't create evaluator %v", err)
|
||||
|
|
@ -293,6 +297,7 @@ func TestMissingFunc(t *testing.T) {
|
|||
t.Logf("Err %v", err)
|
||||
}
|
||||
func TestStorage(t *testing.T) {
|
||||
t.Parallel()
|
||||
js := `
|
||||
function testStorage(){
|
||||
storage.put("mykey", "myvalue")
|
||||
|
|
@ -455,6 +460,7 @@ func dummySigned(value *big.Int) *types.Transaction {
|
|||
}
|
||||
|
||||
func TestLimitWindow(t *testing.T) {
|
||||
t.Parallel()
|
||||
r, err := initRuleEngine(ExampleTxWindow)
|
||||
if err != nil {
|
||||
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,
|
||||
// instead of using the disk-based data storage
|
||||
func TestContextIsCleared(t *testing.T) {
|
||||
t.Parallel()
|
||||
js := `
|
||||
function ApproveTx(){
|
||||
if (typeof foobar == 'undefined') {
|
||||
|
|
@ -571,6 +578,7 @@ func TestContextIsCleared(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSignData(t *testing.T) {
|
||||
t.Parallel()
|
||||
js := `function ApproveListing(){
|
||||
return "Approve"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import (
|
|||
)
|
||||
|
||||
func TestEncryption(t *testing.T) {
|
||||
t.Parallel()
|
||||
// key := []byte("AES256Key-32Characters1234567890")
|
||||
// plaintext := []byte(value)
|
||||
key := []byte("AES256Key-32Characters1234567890")
|
||||
|
|
@ -52,6 +53,7 @@ func TestEncryption(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFileStorage(t *testing.T) {
|
||||
t.Parallel()
|
||||
a := map[string]storedCredential{
|
||||
"secret": {
|
||||
Iv: common.Hex2Bytes("cdb30036279601aeee60f16b"),
|
||||
|
|
@ -90,6 +92,7 @@ func TestFileStorage(t *testing.T) {
|
|||
}
|
||||
}
|
||||
func TestEnd2End(t *testing.T) {
|
||||
t.Parallel()
|
||||
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(colorable.NewColorableStderr(), slog.LevelInfo, true)))
|
||||
|
||||
d := t.TempDir()
|
||||
|
|
@ -110,6 +113,7 @@ func TestEnd2End(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSwappedKeys(t *testing.T) {
|
||||
t.Parallel()
|
||||
// It should not be possible to swap the keys/values, so that
|
||||
// K1:V1, K2:V2 can be swapped into K1:V2, K2:V1
|
||||
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(colorable.NewColorableStderr(), slog.LevelInfo, true)))
|
||||
|
|
|
|||
|
|
@ -330,6 +330,12 @@ func (t *BlockTest) validatePostState(statedb *state.StateDB) error {
|
|||
if nonce2 != acct.Nonce {
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,8 @@ type nodeIterator struct {
|
|||
path []byte // Path to the current node
|
||||
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.
|
||||
|
|
@ -172,6 +173,24 @@ func newNodeIterator(trie *Trie, start []byte) NodeIterator {
|
|||
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) {
|
||||
it.resolver = resolver
|
||||
}
|
||||
|
|
@ -423,8 +442,9 @@ func (st *nodeIteratorState) resolve(it *nodeIterator, path []byte) error {
|
|||
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 (
|
||||
path = it.path
|
||||
child node
|
||||
state *nodeIteratorState
|
||||
childPath []byte
|
||||
|
|
@ -433,13 +453,12 @@ func findChild(n *fullNode, index int, path []byte, ancestor common.Hash) (node,
|
|||
if n.Children[index] != nil {
|
||||
child = n.Children[index]
|
||||
hash, _ := child.cache()
|
||||
state = &nodeIteratorState{
|
||||
hash: common.BytesToHash(hash),
|
||||
node: child,
|
||||
parent: ancestor,
|
||||
index: -1,
|
||||
pathlen: len(path),
|
||||
}
|
||||
state = it.getFromPool()
|
||||
state.hash = common.BytesToHash(hash)
|
||||
state.node = child
|
||||
state.parent = ancestor
|
||||
state.index = -1
|
||||
state.pathlen = len(path)
|
||||
childPath = append(childPath, path...)
|
||||
childPath = append(childPath, byte(index))
|
||||
return child, state, childPath, index
|
||||
|
|
@ -452,7 +471,7 @@ func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Has
|
|||
switch node := parent.node.(type) {
|
||||
case *fullNode:
|
||||
// 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
|
||||
return state, path, true
|
||||
}
|
||||
|
|
@ -460,13 +479,12 @@ func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Has
|
|||
// Short node, return the pointer singleton child
|
||||
if parent.index < 0 {
|
||||
hash, _ := node.Val.cache()
|
||||
state := &nodeIteratorState{
|
||||
hash: common.BytesToHash(hash),
|
||||
node: node.Val,
|
||||
parent: ancestor,
|
||||
index: -1,
|
||||
pathlen: len(it.path),
|
||||
}
|
||||
state := it.getFromPool()
|
||||
state.hash = common.BytesToHash(hash)
|
||||
state.node = node.Val
|
||||
state.parent = ancestor
|
||||
state.index = -1
|
||||
state.pathlen = len(it.path)
|
||||
path := append(it.path, node.Key...)
|
||||
return state, path, true
|
||||
}
|
||||
|
|
@ -480,7 +498,7 @@ func (it *nodeIterator) nextChildAt(parent *nodeIteratorState, ancestor common.H
|
|||
switch n := parent.node.(type) {
|
||||
case *fullNode:
|
||||
// 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 {
|
||||
// No more children in this fullnode
|
||||
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
|
||||
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
|
||||
// previous one
|
||||
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
|
||||
if parent.index < 0 {
|
||||
hash, _ := n.Val.cache()
|
||||
state := &nodeIteratorState{
|
||||
hash: common.BytesToHash(hash),
|
||||
node: n.Val,
|
||||
parent: ancestor,
|
||||
index: -1,
|
||||
pathlen: len(it.path),
|
||||
}
|
||||
state := it.getFromPool()
|
||||
state.hash = common.BytesToHash(hash)
|
||||
state.node = n.Val
|
||||
state.parent = ancestor
|
||||
state.index = -1
|
||||
state.pathlen = len(it.path)
|
||||
path := append(it.path, n.Key...)
|
||||
return state, path, true
|
||||
}
|
||||
|
|
@ -533,6 +550,8 @@ func (it *nodeIterator) pop() {
|
|||
it.path = it.path[:last.pathlen]
|
||||
it.stack[len(it.stack)-1] = nil
|
||||
it.stack = it.stack[:len(it.stack)-1]
|
||||
// last is now unused
|
||||
it.putInPool(last)
|
||||
}
|
||||
|
||||
func compareNodes(a, b NodeIterator) int {
|
||||
|
|
|
|||
|
|
@ -616,3 +616,15 @@ func isTrieNode(scheme string, key, val []byte) (bool, []byte, common.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package trie
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -571,7 +572,7 @@ func testIncompleteSync(t *testing.T, scheme string) {
|
|||
hash := crypto.Keccak256Hash(result.Data)
|
||||
if hash != root {
|
||||
addedKeys = append(addedKeys, result.Path)
|
||||
addedHashes = append(addedHashes, crypto.Keccak256Hash(result.Data))
|
||||
addedHashes = append(addedHashes, hash)
|
||||
}
|
||||
}
|
||||
// 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
|
||||
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))
|
||||
nodeHash := addedHashes[i]
|
||||
value := rawdb.ReadTrieNode(diskdb, owner, inner, nodeHash, scheme)
|
||||
|
|
|
|||
Loading…
Reference in a new issue