mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
dev: fix: some wsl lint issues
This commit is contained in:
parent
2c87219c80
commit
3af5e435c7
145 changed files with 1488 additions and 15 deletions
|
|
@ -124,6 +124,7 @@ func (b *SimulatedBackend) Commit() common.Hash {
|
||||||
if _, err := b.blockchain.InsertChain([]*types.Block{b.pendingBlock}); err != nil {
|
if _, err := b.blockchain.InsertChain([]*types.Block{b.pendingBlock}); err != nil {
|
||||||
panic(err) // This cannot happen unless the simulator is wrong, fail in that case
|
panic(err) // This cannot happen unless the simulator is wrong, fail in that case
|
||||||
}
|
}
|
||||||
|
|
||||||
blockHash := b.pendingBlock.Hash()
|
blockHash := b.pendingBlock.Hash()
|
||||||
|
|
||||||
// Using the last inserted block here makes it possible to build on a side
|
// Using the last inserted block here makes it possible to build on a side
|
||||||
|
|
@ -669,6 +670,8 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
|
||||||
evmContext := core.NewEVMBlockContext(header, b.blockchain, nil)
|
evmContext := core.NewEVMBlockContext(header, b.blockchain, nil)
|
||||||
vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{NoBaseFee: true})
|
vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{NoBaseFee: true})
|
||||||
gasPool := new(core.GasPool).AddGas(math.MaxUint64)
|
gasPool := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
|
|
||||||
|
//nolint:contextcheck
|
||||||
return core.ApplyMessage(vmEnv, msg, gasPool, context.Background())
|
return core.ApplyMessage(vmEnv, msg, gasPool, context.Background())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -873,6 +876,7 @@ func (fb *filterBackend) GetBody(ctx context.Context, hash common.Hash, number r
|
||||||
if body := fb.bc.GetBody(hash); body != nil {
|
if body := fb.bc.GetBody(hash); body != nil {
|
||||||
return body, nil
|
return body, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, errors.New("block body not found")
|
return nil, errors.New("block body not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1349,6 +1349,7 @@ func TestCommitReturnValue(t *testing.T) {
|
||||||
|
|
||||||
testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
|
testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
|
||||||
sim := simTestBackend(testAddr)
|
sim := simTestBackend(testAddr)
|
||||||
|
|
||||||
defer sim.Close()
|
defer sim.Close()
|
||||||
|
|
||||||
startBlockHeight := sim.blockchain.CurrentBlock().Number.Uint64()
|
startBlockHeight := sim.blockchain.CurrentBlock().Number.Uint64()
|
||||||
|
|
@ -1380,6 +1381,7 @@ func TestCommitReturnValue(t *testing.T) {
|
||||||
if h2 == h2fork {
|
if h2 == h2fork {
|
||||||
t.Error("The block in the fork and the original block are the same block!")
|
t.Error("The block in the fork and the original block are the same block!")
|
||||||
}
|
}
|
||||||
|
|
||||||
if sim.blockchain.GetHeader(h2fork, startBlockHeight+2) == nil {
|
if sim.blockchain.GetHeader(h2fork, startBlockHeight+2) == nil {
|
||||||
t.Error("Could not retrieve the just created block (side-chain)")
|
t.Error("Could not retrieve the just created block (side-chain)")
|
||||||
}
|
}
|
||||||
|
|
@ -1392,6 +1394,7 @@ func TestAdjustTimeAfterFork(t *testing.T) {
|
||||||
|
|
||||||
testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
|
testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
|
||||||
sim := simTestBackend(testAddr)
|
sim := simTestBackend(testAddr)
|
||||||
|
|
||||||
defer sim.Close()
|
defer sim.Close()
|
||||||
|
|
||||||
sim.Commit() // h1
|
sim.Commit() // h1
|
||||||
|
|
|
||||||
|
|
@ -199,9 +199,11 @@ func TestUnpackAnonymousLogIntoMap(t *testing.T) {
|
||||||
|
|
||||||
var received map[string]interface{}
|
var received map[string]interface{}
|
||||||
err := bc.UnpackLogIntoMap(received, "received", mockLog)
|
err := bc.UnpackLogIntoMap(received, "received", mockLog)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("unpacking anonymous event is not supported")
|
t.Error("unpacking anonymous event is not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err.Error() != "no event signature" {
|
if err.Error() != "no event signature" {
|
||||||
t.Errorf("expected error 'no event signature', got '%s'", err)
|
t.Errorf("expected error 'no event signature', got '%s'", err)
|
||||||
}
|
}
|
||||||
|
|
@ -384,6 +386,7 @@ func TestCall(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
var method, methodWithArg = "something", "somethingArrrrg"
|
var method, methodWithArg = "something", "somethingArrrrg"
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name, method string
|
name, method string
|
||||||
opts *bind.CallOpts
|
opts *bind.CallOpts
|
||||||
|
|
@ -482,6 +485,7 @@ func TestCall(t *testing.T) {
|
||||||
results: &[]interface{}{0},
|
results: &[]interface{}{0},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
bc := bind.NewBoundContract(common.HexToAddress("0x0"), abi.ABI{
|
bc := bind.NewBoundContract(common.HexToAddress("0x0"), abi.ABI{
|
||||||
Methods: map[string]abi.Method{
|
Methods: map[string]abi.Method{
|
||||||
|
|
@ -496,15 +500,19 @@ func TestCall(t *testing.T) {
|
||||||
},
|
},
|
||||||
}, test.mc, nil, nil)
|
}, test.mc, nil, nil)
|
||||||
err := bc.Call(test.opts, test.results, test.method)
|
err := bc.Call(test.opts, test.results, test.method)
|
||||||
|
|
||||||
if test.wantErr || test.wantErrExact != nil {
|
if test.wantErr || test.wantErrExact != nil {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("%q expected error", test.name)
|
t.Fatalf("%q expected error", test.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.wantErrExact != nil && !errors.Is(err, test.wantErrExact) {
|
if test.wantErrExact != nil && !errors.Is(err, test.wantErrExact) {
|
||||||
t.Fatalf("%q expected error %q but got %q", test.name, test.wantErrExact, err)
|
t.Fatalf("%q expected error %q but got %q", test.name, test.wantErrExact, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("%q unexpected error: %v", test.name, err)
|
t.Fatalf("%q unexpected error: %v", test.name, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,7 @@ func abigen(c *cli.Context) error {
|
||||||
utils.Fatalf("No destination package specified (--pkg)")
|
utils.Fatalf("No destination package specified (--pkg)")
|
||||||
}
|
}
|
||||||
var lang bind.Lang
|
var lang bind.Lang
|
||||||
|
|
||||||
switch c.String(langFlag.Name) {
|
switch c.String(langFlag.Name) {
|
||||||
case "go":
|
case "go":
|
||||||
lang = bind.LangGo
|
lang = bind.LangGo
|
||||||
|
|
@ -120,6 +121,7 @@ func abigen(c *cli.Context) error {
|
||||||
abi []byte
|
abi []byte
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
input := c.String(abiFlag.Name)
|
input := c.String(abiFlag.Name)
|
||||||
if input == "-" {
|
if input == "-" {
|
||||||
abi, err = io.ReadAll(os.Stdin)
|
abi, err = io.ReadAll(os.Stdin)
|
||||||
|
|
@ -132,6 +134,7 @@ func abigen(c *cli.Context) error {
|
||||||
abis = append(abis, string(abi))
|
abis = append(abis, string(abi))
|
||||||
|
|
||||||
var bin []byte
|
var bin []byte
|
||||||
|
|
||||||
if binFile := c.String(binFlag.Name); binFile != "" {
|
if binFile := c.String(binFlag.Name); binFile != "" {
|
||||||
if bin, err = os.ReadFile(binFile); err != nil {
|
if bin, err = os.ReadFile(binFile); err != nil {
|
||||||
utils.Fatalf("Failed to read input bytecode: %v", err)
|
utils.Fatalf("Failed to read input bytecode: %v", err)
|
||||||
|
|
@ -225,6 +228,7 @@ func abigen(c *cli.Context) error {
|
||||||
fmt.Printf("%s\n", code)
|
fmt.Printf("%s\n", code)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.WriteFile(c.String(outFlag.Name), []byte(code), 0600); err != nil {
|
if err := os.WriteFile(c.String(outFlag.Name), []byte(code), 0600); err != nil {
|
||||||
utils.Fatalf("Failed to write ABI binding: %v", err)
|
utils.Fatalf("Failed to write ABI binding: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ func newNameFilter(patterns ...string) (*nameFilter, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,7 +41,9 @@ func (f *nameFilter) add(pattern string) error {
|
||||||
f.files[file] = true
|
f.files[file] = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
f.fulls[pattern] = true
|
f.fulls[pattern] = true
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ func getCheckpoint(ctx *cli.Context, client *rpc.Client) *params.TrustedCheckpoi
|
||||||
|
|
||||||
if ctx.IsSet(indexFlag.Name) {
|
if ctx.IsSet(indexFlag.Name) {
|
||||||
var result [3]string
|
var result [3]string
|
||||||
|
|
||||||
index := uint64(ctx.Int64(indexFlag.Name))
|
index := uint64(ctx.Int64(indexFlag.Name))
|
||||||
if err := client.Call(&result, "les_getCheckpoint", index); err != nil {
|
if err := client.Call(&result, "les_getCheckpoint", index); err != nil {
|
||||||
utils.Fatalf("Failed to get local checkpoint %v, please ensure the les API is exposed", err)
|
utils.Fatalf("Failed to get local checkpoint %v, please ensure the les API is exposed", err)
|
||||||
|
|
|
||||||
|
|
@ -329,6 +329,7 @@ func initializeSecrets(c *cli.Context) error {
|
||||||
return fmt.Errorf("failed to read enough random")
|
return fmt.Errorf("failed to read enough random")
|
||||||
}
|
}
|
||||||
n, p := keystore.StandardScryptN, keystore.StandardScryptP
|
n, p := keystore.StandardScryptN, keystore.StandardScryptP
|
||||||
|
|
||||||
if c.Bool(utils.LightKDFFlag.Name) {
|
if c.Bool(utils.LightKDFFlag.Name) {
|
||||||
n, p = keystore.LightScryptN, keystore.LightScryptP
|
n, p = keystore.LightScryptN, keystore.LightScryptP
|
||||||
}
|
}
|
||||||
|
|
@ -385,6 +386,7 @@ func attestFile(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf(err.Error())
|
utils.Fatalf(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
configDir := ctx.String(configdirFlag.Name)
|
configDir := ctx.String(configdirFlag.Name)
|
||||||
vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10]))
|
vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10]))
|
||||||
confKey := crypto.Keccak256([]byte("config"), stretchedKey)
|
confKey := crypto.Keccak256([]byte("config"), stretchedKey)
|
||||||
|
|
@ -401,15 +403,18 @@ func initInternalApi(c *cli.Context) (*core.UIServerAPI, core.UIClientAPI, error
|
||||||
if err := initialize(c); err != nil {
|
if err := initialize(c); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ui = core.NewCommandlineUI()
|
ui = core.NewCommandlineUI()
|
||||||
pwStorage storage.Storage = &storage.NoStorage{}
|
pwStorage storage.Storage = &storage.NoStorage{}
|
||||||
ksLoc = c.String(keystoreFlag.Name)
|
ksLoc = c.String(keystoreFlag.Name)
|
||||||
lightKdf = c.Bool(utils.LightKDFFlag.Name)
|
lightKdf = c.Bool(utils.LightKDFFlag.Name)
|
||||||
)
|
)
|
||||||
|
|
||||||
am := core.StartClefAccountManager(ksLoc, true, lightKdf, "")
|
am := core.StartClefAccountManager(ksLoc, true, lightKdf, "")
|
||||||
api := core.NewSignerAPI(am, 0, true, ui, nil, false, pwStorage)
|
api := core.NewSignerAPI(am, 0, true, ui, nil, false, pwStorage)
|
||||||
internalApi := core.NewUIServerAPI(api)
|
internalApi := core.NewUIServerAPI(api)
|
||||||
|
|
||||||
return internalApi, ui, nil
|
return internalApi, ui, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -432,6 +437,7 @@ func setCredential(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf(err.Error())
|
utils.Fatalf(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
configDir := ctx.String(configdirFlag.Name)
|
configDir := ctx.String(configdirFlag.Name)
|
||||||
vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10]))
|
vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10]))
|
||||||
pwkey := crypto.Keccak256([]byte("credentials"), stretchedKey)
|
pwkey := crypto.Keccak256([]byte("credentials"), stretchedKey)
|
||||||
|
|
@ -460,6 +466,7 @@ func removeCredential(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf(err.Error())
|
utils.Fatalf(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
configDir := ctx.String(configdirFlag.Name)
|
configDir := ctx.String(configdirFlag.Name)
|
||||||
vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10]))
|
vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10]))
|
||||||
pwkey := crypto.Keccak256([]byte("credentials"), stretchedKey)
|
pwkey := crypto.Keccak256([]byte("credentials"), stretchedKey)
|
||||||
|
|
@ -501,10 +508,13 @@ func newAccount(c *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
addr, err := internalApi.New(context.Background())
|
addr, err := internalApi.New(context.Background())
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fmt.Printf("Generated account %v\n", addr.String())
|
fmt.Printf("Generated account %v\n", addr.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -513,17 +523,23 @@ func listAccounts(c *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
accs, err := internalApi.ListAccounts(context.Background())
|
accs, err := internalApi.ListAccounts(context.Background())
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(accs) == 0 {
|
if len(accs) == 0 {
|
||||||
fmt.Println("\nThe keystore is empty.")
|
fmt.Println("\nThe keystore is empty.")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
for _, account := range accs {
|
for _, account := range accs {
|
||||||
fmt.Printf("%v (%v)\n", account.Address, account.URL)
|
fmt.Printf("%v (%v)\n", account.Address, account.URL)
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -532,18 +548,25 @@ func listWallets(c *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
wallets := internalApi.ListWallets()
|
wallets := internalApi.ListWallets()
|
||||||
|
|
||||||
if len(wallets) == 0 {
|
if len(wallets) == 0 {
|
||||||
fmt.Println("\nThere are no wallets.")
|
fmt.Println("\nThere are no wallets.")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
for i, wallet := range wallets {
|
for i, wallet := range wallets {
|
||||||
fmt.Printf("- Wallet %d at %v (%v %v)\n", i, wallet.URL, wallet.Status, wallet.Failure)
|
fmt.Printf("- Wallet %d at %v (%v %v)\n", i, wallet.URL, wallet.Status, wallet.Failure)
|
||||||
|
|
||||||
for j, acc := range wallet.Accounts {
|
for j, acc := range wallet.Accounts {
|
||||||
fmt.Printf(" -Account %d: %v (%v)\n", j, acc.Address, acc.URL)
|
fmt.Printf(" -Account %d: %v (%v)\n", j, acc.Address, acc.URL)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -552,14 +575,19 @@ func accountImport(c *cli.Context) error {
|
||||||
if c.Args().Len() != 1 {
|
if c.Args().Len() != 1 {
|
||||||
return errors.New("<keyfile> must be given as first argument.")
|
return errors.New("<keyfile> must be given as first argument.")
|
||||||
}
|
}
|
||||||
|
|
||||||
internalApi, ui, err := initInternalApi(c)
|
internalApi, ui, err := initInternalApi(c)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pKey, err := crypto.LoadECDSA(c.Args().First())
|
pKey, err := crypto.LoadECDSA(c.Args().First())
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
readPw := func(prompt string) (string, error) {
|
readPw := func(prompt string) (string, error) {
|
||||||
resp, err := ui.OnInputRequired(core.UserInputRequest{
|
resp, err := ui.OnInputRequired(core.UserInputRequest{
|
||||||
Title: "Password",
|
Title: "Password",
|
||||||
|
|
@ -569,23 +597,31 @@ func accountImport(c *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp.Text, nil
|
return resp.Text, nil
|
||||||
}
|
}
|
||||||
first, err := readPw("Please enter a password for the imported account")
|
first, err := readPw("Please enter a password for the imported account")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
second, err := readPw("Please repeat the password you just entered")
|
second, err := readPw("Please repeat the password you just entered")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if first != second {
|
if first != second {
|
||||||
return errors.New("Passwords do not match")
|
return errors.New("Passwords do not match")
|
||||||
}
|
}
|
||||||
|
|
||||||
acc, err := internalApi.ImportRawKey(hex.EncodeToString(crypto.FromECDSA(pKey)), first)
|
acc, err := internalApi.ImportRawKey(hex.EncodeToString(crypto.FromECDSA(pKey)), first)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.ShowInfo(fmt.Sprintf(`Key imported:
|
ui.ShowInfo(fmt.Sprintf(`Key imported:
|
||||||
Address %v
|
Address %v
|
||||||
Keystore file: %v
|
Keystore file: %v
|
||||||
|
|
@ -595,6 +631,7 @@ access to the key and all associated funds!
|
||||||
|
|
||||||
Make sure to backup keystore and passwords in a safe location.`,
|
Make sure to backup keystore and passwords in a safe location.`,
|
||||||
acc.Address, acc.URL.Path))
|
acc.Address, acc.URL.Path))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -630,6 +667,7 @@ func signer(c *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
ui core.UIClientAPI
|
ui core.UIClientAPI
|
||||||
)
|
)
|
||||||
|
|
||||||
if c.Bool(stdiouiFlag.Name) {
|
if c.Bool(stdiouiFlag.Name) {
|
||||||
log.Info("Using stdin/stdout as UI-channel")
|
log.Info("Using stdin/stdout as UI-channel")
|
||||||
ui = core.NewStdIOUI()
|
ui = core.NewStdIOUI()
|
||||||
|
|
@ -650,6 +688,7 @@ func signer(c *cli.Context) error {
|
||||||
api core.ExternalAPI
|
api core.ExternalAPI
|
||||||
pwStorage storage.Storage = &storage.NoStorage{}
|
pwStorage storage.Storage = &storage.NoStorage{}
|
||||||
)
|
)
|
||||||
|
|
||||||
configDir := c.String(configdirFlag.Name)
|
configDir := c.String(configdirFlag.Name)
|
||||||
if stretchedKey, err := readMasterKey(c, ui); err != nil {
|
if stretchedKey, err := readMasterKey(c, ui); err != nil {
|
||||||
log.Warn("Failed to open master, rules disabled", "err", err)
|
log.Warn("Failed to open master, rules disabled", "err", err)
|
||||||
|
|
@ -727,6 +766,7 @@ func signer(c *cli.Context) error {
|
||||||
Service: api,
|
Service: api,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Bool(utils.HTTPEnabledFlag.Name) {
|
if c.Bool(utils.HTTPEnabledFlag.Name) {
|
||||||
vhosts := utils.SplitAndTrim(c.String(utils.HTTPVirtualHostsFlag.Name))
|
vhosts := utils.SplitAndTrim(c.String(utils.HTTPVirtualHostsFlag.Name))
|
||||||
cors := utils.SplitAndTrim(c.String(utils.HTTPCORSDomainFlag.Name))
|
cors := utils.SplitAndTrim(c.String(utils.HTTPCORSDomainFlag.Name))
|
||||||
|
|
@ -756,6 +796,7 @@ func signer(c *cli.Context) error {
|
||||||
log.Info("HTTP endpoint closed", "url", extapiURL)
|
log.Info("HTTP endpoint closed", "url", extapiURL)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.Bool(utils.IPCDisabledFlag.Name) {
|
if !c.Bool(utils.IPCDisabledFlag.Name) {
|
||||||
givenPath := c.String(utils.IPCPathFlag.Name)
|
givenPath := c.String(utils.IPCPathFlag.Name)
|
||||||
ipcapiURL = ipcEndpoint(filepath.Join(givenPath, "clef.ipc"), configDir)
|
ipcapiURL = ipcEndpoint(filepath.Join(givenPath, "clef.ipc"), configDir)
|
||||||
|
|
@ -769,6 +810,7 @@ func signer(c *cli.Context) error {
|
||||||
log.Info("IPC endpoint closed", "url", ipcapiURL)
|
log.Info("IPC endpoint closed", "url", ipcapiURL)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Bool(testFlag.Name) {
|
if c.Bool(testFlag.Name) {
|
||||||
log.Info("Performing UI test")
|
log.Info("Performing UI test")
|
||||||
go testExternalUI(apiImpl)
|
go testExternalUI(apiImpl)
|
||||||
|
|
@ -816,6 +858,7 @@ func readMasterKey(ctx *cli.Context, ui core.UIClientAPI) ([]byte, error) {
|
||||||
file string
|
file string
|
||||||
configDir = ctx.String(configdirFlag.Name)
|
configDir = ctx.String(configdirFlag.Name)
|
||||||
)
|
)
|
||||||
|
|
||||||
if ctx.IsSet(signerSecretFlag.Name) {
|
if ctx.IsSet(signerSecretFlag.Name) {
|
||||||
file = ctx.String(signerSecretFlag.Name)
|
file = ctx.String(signerSecretFlag.Name)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -824,6 +867,7 @@ func readMasterKey(ctx *cli.Context, ui core.UIClientAPI) ([]byte, error) {
|
||||||
if err := checkFile(file); err != nil {
|
if err := checkFile(file); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cipherKey, err := os.ReadFile(file)
|
cipherKey, err := os.ReadFile(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -1215,5 +1259,6 @@ These data types are defined in the channel between clef and the UI`)
|
||||||
for _, elem := range output {
|
for _, elem := range output {
|
||||||
fmt.Println(elem)
|
fmt.Println(elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ func TestMain(m *testing.M) {
|
||||||
if reexec.Init() {
|
if reexec.Init() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Exit(m.Run())
|
os.Exit(m.Run())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,9 +64,11 @@ func runClef(t *testing.T, args ...string) *testproc {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
os.RemoveAll(ddir)
|
os.RemoveAll(ddir)
|
||||||
})
|
})
|
||||||
|
|
||||||
return runWithKeystore(t, ddir, args...)
|
return runWithKeystore(t, ddir, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,6 +84,7 @@ func runWithKeystore(t *testing.T, keystore string, args ...string) *testproc {
|
||||||
// Boot "clef". This actually runs the test binary but the TestMain
|
// Boot "clef". This actually runs the test binary but the TestMain
|
||||||
// function will prevent any tests from running.
|
// function will prevent any tests from running.
|
||||||
tt.Run(registeredName, args...)
|
tt.Run(registeredName, args...)
|
||||||
|
|
||||||
return tt
|
return tt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ func (c *crawler) run(timeout time.Duration, nthreads int) nodeSet {
|
||||||
doneCh = make(chan enode.Iterator, len(c.iters))
|
doneCh = make(chan enode.Iterator, len(c.iters))
|
||||||
liveIters = len(c.iters)
|
liveIters = len(c.iters)
|
||||||
)
|
)
|
||||||
|
|
||||||
if nthreads < 1 {
|
if nthreads < 1 {
|
||||||
nthreads = 1
|
nthreads = 1
|
||||||
}
|
}
|
||||||
|
|
@ -86,6 +87,7 @@ func (c *crawler) run(timeout time.Duration, nthreads int) nodeSet {
|
||||||
for _, it := range c.iters {
|
for _, it := range c.iters {
|
||||||
go c.runIterator(doneCh, it)
|
go c.runIterator(doneCh, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
added uint64
|
added uint64
|
||||||
updated uint64
|
updated uint64
|
||||||
|
|
@ -94,10 +96,13 @@ func (c *crawler) run(timeout time.Duration, nthreads int) nodeSet {
|
||||||
removed uint64
|
removed uint64
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
)
|
)
|
||||||
|
|
||||||
wg.Add(nthreads)
|
wg.Add(nthreads)
|
||||||
|
|
||||||
for i := 0; i < nthreads; i++ {
|
for i := 0; i < nthreads; i++ {
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case n := <-c.ch:
|
case n := <-c.ch:
|
||||||
|
|
@ -183,6 +188,7 @@ func (c *crawler) updateNode(n *enode.Node) int {
|
||||||
// Request the node record.
|
// Request the node record.
|
||||||
status := nodeUpdated
|
status := nodeUpdated
|
||||||
node.LastCheck = truncNow()
|
node.LastCheck = truncNow()
|
||||||
|
|
||||||
if nn, err := c.disc.RequestENR(n); err != nil {
|
if nn, err := c.disc.RequestENR(n); err != nil {
|
||||||
if node.Score == 0 {
|
if node.Score == 0 {
|
||||||
// Node doesn't implement EIP-868.
|
// Node doesn't implement EIP-868.
|
||||||
|
|
@ -206,10 +212,13 @@ func (c *crawler) updateNode(n *enode.Node) int {
|
||||||
if node.Score <= 0 {
|
if node.Score <= 0 {
|
||||||
log.Debug("Removing node", "id", n.ID())
|
log.Debug("Removing node", "id", n.ID())
|
||||||
delete(c.output, n.ID())
|
delete(c.output, n.ID())
|
||||||
|
|
||||||
return nodeRemoved
|
return nodeRemoved
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("Updating node", "id", n.ID(), "seq", n.Seq(), "score", node.Score)
|
log.Debug("Updating node", "id", n.ID(), "seq", n.Seq(), "score", node.Score)
|
||||||
c.output[n.ID()] = node
|
c.output[n.ID()] = node
|
||||||
|
|
||||||
return status
|
return status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -282,18 +282,25 @@ func parseExtAddr(spec string) (ip net.IP, port int, ok bool) {
|
||||||
if ip != nil {
|
if ip != nil {
|
||||||
return ip, 0, true
|
return ip, 0, true
|
||||||
}
|
}
|
||||||
|
|
||||||
host, portstr, err := net.SplitHostPort(spec)
|
host, portstr, err := net.SplitHostPort(spec)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, false
|
return nil, 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
ip = net.ParseIP(host)
|
ip = net.ParseIP(host)
|
||||||
|
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return nil, 0, false
|
return nil, 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
port, err = strconv.Atoi(portstr)
|
port, err = strconv.Atoi(portstr)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, false
|
return nil, 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return ip, port, true
|
return ip, port, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -326,7 +333,9 @@ func listen(ctx *cli.Context, ln *enode.LocalNode) *net.UDPConn {
|
||||||
if !ok {
|
if !ok {
|
||||||
exit(fmt.Errorf("-%s: invalid external address %q", extAddrFlag.Name, extAddr))
|
exit(fmt.Errorf("-%s: invalid external address %q", extAddrFlag.Name, extAddr))
|
||||||
}
|
}
|
||||||
|
|
||||||
ln.SetStaticIP(ip)
|
ln.SetStaticIP(ip)
|
||||||
|
|
||||||
if port != 0 {
|
if port != 0 {
|
||||||
ln.SetFallbackUDP(port)
|
ln.SetFallbackUDP(port)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,7 @@ func (c *cloudflareClient) uploadRecords(name string, records map[string]string)
|
||||||
|
|
||||||
// Iterate over the new records and inject anything missing.
|
// Iterate over the new records and inject anything missing.
|
||||||
log.Info("Updating DNS entries")
|
log.Info("Updating DNS entries")
|
||||||
|
|
||||||
created := 0
|
created := 0
|
||||||
updated := 0
|
updated := 0
|
||||||
skipped := 0
|
skipped := 0
|
||||||
|
|
@ -156,9 +157,11 @@ func (c *cloudflareClient) uploadRecords(name string, records map[string]string)
|
||||||
return fmt.Errorf("failed to publish %s: %v", path, err)
|
return fmt.Errorf("failed to publish %s: %v", path, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Updated DNS entries", "new", created, "updated", updated, "untouched", skipped)
|
log.Info("Updated DNS entries", "new", created, "updated", updated, "untouched", skipped)
|
||||||
// Iterate over the old records and delete anything stale.
|
// Iterate over the old records and delete anything stale.
|
||||||
deleted := 0
|
deleted := 0
|
||||||
|
|
||||||
log.Info("Deleting stale DNS entries")
|
log.Info("Deleting stale DNS entries")
|
||||||
for path, entry := range existing {
|
for path, entry := range existing {
|
||||||
if _, ok := records[path]; ok {
|
if _, ok := records[path]; ok {
|
||||||
|
|
@ -171,6 +174,7 @@ func (c *cloudflareClient) uploadRecords(name string, records map[string]string)
|
||||||
return fmt.Errorf("failed to delete %s: %v", path, err)
|
return fmt.Errorf("failed to delete %s: %v", path, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Deleted stale DNS entries", "count", deleted)
|
log.Info("Deleted stale DNS entries", "count", deleted)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -279,6 +279,7 @@ func makeDeletionChanges(records map[string]recordSet, keep map[string]string) [
|
||||||
if _, ok := keep[path]; ok {
|
if _, ok := keep[path]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug(fmt.Sprintf("Deleting %s = %s", path, strings.Join(set.values, "")))
|
log.Debug(fmt.Sprintf("Deleting %s = %s", path, strings.Join(set.values, "")))
|
||||||
changes = append(changes, newTXTChange("DELETE", path, set.ttl, set.values...))
|
changes = append(changes, newTXTChange("DELETE", path, set.ttl, set.values...))
|
||||||
}
|
}
|
||||||
|
|
@ -345,6 +346,7 @@ func (c *route53Client) collectRecords(name string) (map[string]recordSet, error
|
||||||
var req route53.ListResourceRecordSetsInput
|
var req route53.ListResourceRecordSetsInput
|
||||||
req.HostedZoneId = &c.zoneID
|
req.HostedZoneId = &c.zoneID
|
||||||
existing := make(map[string]recordSet)
|
existing := make(map[string]recordSet)
|
||||||
|
|
||||||
log.Info("Loading existing TXT records", "name", name, "zone", c.zoneID)
|
log.Info("Loading existing TXT records", "name", name, "zone", c.zoneID)
|
||||||
for page := 0; ; page++ {
|
for page := 0; ; page++ {
|
||||||
log.Debug("Loading existing TXT records", "name", name, "zone", c.zoneID, "page", page)
|
log.Debug("Loading existing TXT records", "name", name, "zone", c.zoneID, "page", page)
|
||||||
|
|
|
||||||
|
|
@ -381,6 +381,7 @@ func writeTreeMetadata(directory string, def *dnsDefinition) {
|
||||||
exit(err)
|
exit(err)
|
||||||
}
|
}
|
||||||
metaFile, _ := treeDefinitionFiles(directory)
|
metaFile, _ := treeDefinitionFiles(directory)
|
||||||
|
|
||||||
if err := os.WriteFile(metaFile, metaJSON, 0644); err != nil {
|
if err := os.WriteFile(metaFile, metaJSON, 0644); err != nil {
|
||||||
exit(err)
|
exit(err)
|
||||||
}
|
}
|
||||||
|
|
@ -410,6 +411,7 @@ func writeTXTJSON(file string, txt map[string]string) {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.WriteFile(file, txtJSON, 0644); err != nil {
|
if err := os.WriteFile(file, txtJSON, 0644); err != nil {
|
||||||
exit(err)
|
exit(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,7 @@ func loadChain(chainfile string, genesis string) (*Chain, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
gblock := gen.ToBlock()
|
gblock := gen.ToBlock()
|
||||||
|
|
||||||
blocks, err := blocksFromFile(chainfile, gblock)
|
blocks, err := blocksFromFile(chainfile, gblock)
|
||||||
|
|
|
||||||
|
|
@ -208,14 +208,18 @@ loop:
|
||||||
// node, and one for receiving messages from the node.
|
// node, and one for receiving messages from the node.
|
||||||
func (s *Suite) createSendAndRecvConns() (*Conn, *Conn, error) {
|
func (s *Suite) createSendAndRecvConns() (*Conn, *Conn, error) {
|
||||||
sendConn, err := s.dial()
|
sendConn, err := s.dial()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("dial failed: %v", err)
|
return nil, nil, fmt.Errorf("dial failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
recvConn, err := s.dial()
|
recvConn, err := s.dial()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendConn.Close()
|
sendConn.Close()
|
||||||
return nil, nil, fmt.Errorf("dial failed: %v", err)
|
return nil, nil, fmt.Errorf("dial failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return sendConn, recvConn, nil
|
return sendConn, recvConn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,10 +239,12 @@ func (c *Conn) readAndServe(chain *Chain, timeout time.Duration) Message {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errorf("could not get headers for inbound header request: %v", err)
|
return errorf("could not get headers for inbound header request: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := &BlockHeaders{
|
resp := &BlockHeaders{
|
||||||
RequestId: msg.ReqID(),
|
RequestId: msg.ReqID(),
|
||||||
BlockHeadersPacket: eth.BlockHeadersPacket(headers),
|
BlockHeadersPacket: eth.BlockHeadersPacket(headers),
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.Write(resp); err != nil {
|
if err := c.Write(resp); err != nil {
|
||||||
return errorf("could not write to connection: %v", err)
|
return errorf("could not write to connection: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -246,6 +252,7 @@ func (c *Conn) readAndServe(chain *Chain, timeout time.Duration) Message {
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return errorf("no message received within %v", timeout)
|
return errorf("no message received within %v", timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -263,10 +270,13 @@ func (c *Conn) headersRequest(request *GetBlockHeaders, chain *Chain, reqID uint
|
||||||
// wait for response
|
// wait for response
|
||||||
msg := c.waitForResponse(chain, timeout, request.RequestId)
|
msg := c.waitForResponse(chain, timeout, request.RequestId)
|
||||||
resp, ok := msg.(*BlockHeaders)
|
resp, ok := msg.(*BlockHeaders)
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unexpected message received: %s", pretty.Sdump(msg))
|
return nil, fmt.Errorf("unexpected message received: %s", pretty.Sdump(msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
headers := []*types.Header(resp.BlockHeadersPacket)
|
headers := []*types.Header(resp.BlockHeadersPacket)
|
||||||
|
|
||||||
return headers, nil
|
return headers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -591,21 +601,26 @@ func (s *Suite) hashAnnounce() error {
|
||||||
// Announcement sent, now wait for a header request
|
// Announcement sent, now wait for a header request
|
||||||
msg := sendConn.Read()
|
msg := sendConn.Read()
|
||||||
blockHeaderReq, ok := msg.(*GetBlockHeaders)
|
blockHeaderReq, ok := msg.(*GetBlockHeaders)
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("unexpected %s", pretty.Sdump(msg))
|
return fmt.Errorf("unexpected %s", pretty.Sdump(msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
if blockHeaderReq.Amount != 1 {
|
if blockHeaderReq.Amount != 1 {
|
||||||
return fmt.Errorf("unexpected number of block headers requested: %v", blockHeaderReq.Amount)
|
return fmt.Errorf("unexpected number of block headers requested: %v", blockHeaderReq.Amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
if blockHeaderReq.Origin.Hash != announcement.Hash {
|
if blockHeaderReq.Origin.Hash != announcement.Hash {
|
||||||
return fmt.Errorf("unexpected block header requested. Announced:\n %v\n Remote request:\n%v",
|
return fmt.Errorf("unexpected block header requested. Announced:\n %v\n Remote request:\n%v",
|
||||||
pretty.Sdump(announcement),
|
pretty.Sdump(announcement),
|
||||||
pretty.Sdump(blockHeaderReq))
|
pretty.Sdump(blockHeaderReq))
|
||||||
}
|
}
|
||||||
|
|
||||||
err = sendConn.Write(&BlockHeaders{
|
err = sendConn.Write(&BlockHeaders{
|
||||||
RequestId: blockHeaderReq.ReqID(),
|
RequestId: blockHeaderReq.ReqID(),
|
||||||
BlockHeadersPacket: eth.BlockHeadersPacket{nextBlock.Header()},
|
BlockHeadersPacket: eth.BlockHeadersPacket{nextBlock.Header()},
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to write to connection: %v", err)
|
return fmt.Errorf("failed to write to connection: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -357,6 +357,7 @@ func (s *Suite) TestSnapTrieNodes(t *utesting.T) {
|
||||||
for i := 1; i <= 65; i++ {
|
for i := 1; i <= 65; i++ {
|
||||||
accPaths = append(accPaths, pathTo(i))
|
accPaths = append(accPaths, pathTo(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
empty := types.EmptyCodeHash
|
empty := types.EmptyCodeHash
|
||||||
for i, tc := range []trieNodesTest{
|
for i, tc := range []trieNodesTest{
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -197,13 +197,16 @@ func (s *Suite) TestSimultaneousRequests(t *utesting.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to get expected headers for request 1: %v", err)
|
t.Fatalf("failed to get expected headers for request 1: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected2, err := s.chain.GetHeaders(req2)
|
expected2, err := s.chain.GetHeaders(req2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to get expected headers for request 2: %v", err)
|
t.Fatalf("failed to get expected headers for request 2: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !headersMatch(expected1, headers1.BlockHeadersPacket) {
|
if !headersMatch(expected1, headers1.BlockHeadersPacket) {
|
||||||
t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected1, headers1)
|
t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected1, headers1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !headersMatch(expected2, headers2.BlockHeadersPacket) {
|
if !headersMatch(expected2, headers2.BlockHeadersPacket) {
|
||||||
t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected2, headers2)
|
t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected2, headers2)
|
||||||
}
|
}
|
||||||
|
|
@ -245,6 +248,7 @@ func (s *Suite) TestSameRequestID(t *utesting.T) {
|
||||||
if err = conn.Write(request1); err != nil {
|
if err = conn.Write(request1); err != nil {
|
||||||
t.Fatalf("failed to write to connection: %v", err)
|
t.Fatalf("failed to write to connection: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = conn.Write(request2); err != nil {
|
if err = conn.Write(request2); err != nil {
|
||||||
t.Fatalf("failed to write to connection: %v", err)
|
t.Fatalf("failed to write to connection: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -266,13 +270,16 @@ func (s *Suite) TestSameRequestID(t *utesting.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to get expected block headers: %v", err)
|
t.Fatalf("failed to get expected block headers: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected2, err := s.chain.GetHeaders(request2)
|
expected2, err := s.chain.GetHeaders(request2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to get expected block headers: %v", err)
|
t.Fatalf("failed to get expected block headers: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !headersMatch(expected1, headers1.BlockHeadersPacket) {
|
if !headersMatch(expected1, headers1.BlockHeadersPacket) {
|
||||||
t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected1, headers1)
|
t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected1, headers1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !headersMatch(expected2, headers2.BlockHeadersPacket) {
|
if !headersMatch(expected2, headers2.BlockHeadersPacket) {
|
||||||
t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected2, headers2)
|
t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected2, headers2)
|
||||||
}
|
}
|
||||||
|
|
@ -299,6 +306,7 @@ func (s *Suite) TestZeroRequestID(t *utesting.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to get block headers: %v", err)
|
t.Fatalf("failed to get block headers: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected, err := s.chain.GetHeaders(req)
|
expected, err := s.chain.GetHeaders(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to get expected block headers: %v", err)
|
t.Fatalf("failed to get expected block headers: %v", err)
|
||||||
|
|
@ -336,8 +344,10 @@ func (s *Suite) TestGetBlockBodies(t *utesting.T) {
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Fatalf("unexpected: %s", pretty.Sdump(msg))
|
t.Fatalf("unexpected: %s", pretty.Sdump(msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
bodies := resp.BlockBodiesPacket
|
bodies := resp.BlockBodiesPacket
|
||||||
t.Logf("received %d block bodies", len(bodies))
|
t.Logf("received %d block bodies", len(bodies))
|
||||||
|
|
||||||
if len(bodies) != len(req.GetBlockBodiesPacket) {
|
if len(bodies) != len(req.GetBlockBodiesPacket) {
|
||||||
t.Fatalf("wrong bodies in response: expected %d bodies, "+
|
t.Fatalf("wrong bodies in response: expected %d bodies, "+
|
||||||
"got %d", len(req.GetBlockBodiesPacket), len(bodies))
|
"got %d", len(req.GetBlockBodiesPacket), len(bodies))
|
||||||
|
|
@ -372,6 +382,7 @@ func (s *Suite) TestLargeAnnounce(t *utesting.T) {
|
||||||
|
|
||||||
for i, blockAnnouncement := range blocks[0:3] {
|
for i, blockAnnouncement := range blocks[0:3] {
|
||||||
t.Logf("Testing malicious announcement: %v\n", i)
|
t.Logf("Testing malicious announcement: %v\n", i)
|
||||||
|
|
||||||
conn, err := s.dial()
|
conn, err := s.dial()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("dial failed: %v", err)
|
t.Fatalf("dial failed: %v", err)
|
||||||
|
|
@ -480,10 +491,12 @@ func (s *Suite) TestLargeTxRequest(t *utesting.T) {
|
||||||
for _, hash := range hashMap {
|
for _, hash := range hashMap {
|
||||||
hashes = append(hashes, hash)
|
hashes = append(hashes, hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
getTxReq := &GetPooledTransactions{
|
getTxReq := &GetPooledTransactions{
|
||||||
RequestId: 1234,
|
RequestId: 1234,
|
||||||
GetPooledTransactionsPacket: hashes,
|
GetPooledTransactionsPacket: hashes,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = conn.Write(getTxReq); err != nil {
|
if err = conn.Write(getTxReq); err != nil {
|
||||||
t.Fatalf("could not write to conn: %v", err)
|
t.Fatalf("could not write to conn: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -514,9 +527,11 @@ func (s *Suite) TestNewPooledTxs(t *utesting.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to generate transactions: %v", err)
|
t.Fatalf("failed to generate transactions: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hashes := make([]common.Hash, len(txs))
|
hashes := make([]common.Hash, len(txs))
|
||||||
types := make([]byte, len(txs))
|
types := make([]byte, len(txs))
|
||||||
sizes := make([]uint32, len(txs))
|
sizes := make([]uint32, len(txs))
|
||||||
|
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
hashes[i] = tx.Hash()
|
hashes[i] = tx.Hash()
|
||||||
types[i] = tx.Type()
|
types[i] = tx.Type()
|
||||||
|
|
@ -534,10 +549,13 @@ func (s *Suite) TestNewPooledTxs(t *utesting.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var ann Message = NewPooledTransactionHashes{Types: types, Sizes: sizes, Hashes: hashes}
|
var ann Message = NewPooledTransactionHashes{Types: types, Sizes: sizes, Hashes: hashes}
|
||||||
|
|
||||||
if conn.negotiatedProtoVersion < eth.ETH68 {
|
if conn.negotiatedProtoVersion < eth.ETH68 {
|
||||||
ann = NewPooledTransactionHashes66(hashes)
|
ann = NewPooledTransactionHashes66(hashes)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = conn.Write(ann)
|
err = conn.Write(ann)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to write to connection: %v", err)
|
t.Fatalf("failed to write to connection: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,11 @@ func TestEthSuite(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("could not create new test suite: %v", err)
|
t.Fatalf("could not create new test suite: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range suite.EthTests() {
|
for _, test := range suite.EthTests() {
|
||||||
|
test := test
|
||||||
t.Run(test.Name, func(t *testing.T) {
|
t.Run(test.Name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
result := utesting.RunTAP([]utesting.Test{{Name: test.Name, Fn: test.Fn}}, os.Stdout)
|
result := utesting.RunTAP([]utesting.Test{{Name: test.Name, Fn: test.Fn}}, os.Stdout)
|
||||||
if result[0].Failed {
|
if result[0].Failed {
|
||||||
t.Fatal()
|
t.Fatal()
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,7 @@ func sendSuccessfulTx(s *Suite, tx *types.Transaction, prevTx *types.Transaction
|
||||||
if len(txHashes) != len(msg.Sizes) {
|
if len(txHashes) != len(msg.Sizes) {
|
||||||
return fmt.Errorf("invalid msg size lengths: hashes: %v sizes: %v", len(txHashes), len(msg.Sizes))
|
return fmt.Errorf("invalid msg size lengths: hashes: %v sizes: %v", len(txHashes), len(msg.Sizes))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(txHashes) != len(msg.Types) {
|
if len(txHashes) != len(msg.Types) {
|
||||||
return fmt.Errorf("invalid msg type lengths: hashes: %v types: %v", len(txHashes), len(msg.Types))
|
return fmt.Errorf("invalid msg type lengths: hashes: %v types: %v", len(txHashes), len(msg.Types))
|
||||||
}
|
}
|
||||||
|
|
@ -124,11 +125,13 @@ func sendSuccessfulTx(s *Suite, tx *types.Transaction, prevTx *types.Transaction
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for index, gotHash := range txHashes {
|
for index, gotHash := range txHashes {
|
||||||
if gotHash == tx.Hash() {
|
if gotHash == tx.Hash() {
|
||||||
if msg.Sizes[index] != uint32(tx.Size()) {
|
if msg.Sizes[index] != uint32(tx.Size()) {
|
||||||
return fmt.Errorf("invalid tx size: got %v want %v", msg.Sizes[index], tx.Size())
|
return fmt.Errorf("invalid tx size: got %v want %v", msg.Sizes[index], tx.Size())
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg.Types[index] != tx.Type() {
|
if msg.Types[index] != tx.Type() {
|
||||||
return fmt.Errorf("invalid tx type: got %v want %v", msg.Types[index], tx.Type())
|
return fmt.Errorf("invalid tx type: got %v want %v", msg.Types[index], tx.Type())
|
||||||
}
|
}
|
||||||
|
|
@ -136,6 +139,7 @@ func sendSuccessfulTx(s *Suite, tx *types.Transaction, prevTx *types.Transaction
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("missing transaction announcement: got %v missing %v", txHashes, tx.Hash())
|
return fmt.Errorf("missing transaction announcement: got %v missing %v", txHashes, tx.Hash())
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -165,6 +169,7 @@ func (s *Suite) sendMaliciousTxs(t *utesting.T) error {
|
||||||
|
|
||||||
for i, tx := range badTxs {
|
for i, tx := range badTxs {
|
||||||
t.Logf("Testing malicious tx propagation: %v\n", i)
|
t.Logf("Testing malicious tx propagation: %v\n", i)
|
||||||
|
|
||||||
if err = sendMaliciousTx(s, tx); err != nil {
|
if err = sendMaliciousTx(s, tx); err != nil {
|
||||||
return fmt.Errorf("malicious tx test failed:\ntx: %v\nerror: %v", tx, err)
|
return fmt.Errorf("malicious tx test failed:\ntx: %v\nerror: %v", tx, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -183,24 +183,28 @@ func (c *Conn) Read() Message {
|
||||||
if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
|
if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
|
||||||
return errorf("could not rlp decode message: %v", err)
|
return errorf("could not rlp decode message: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*GetBlockHeaders)(ethMsg)
|
return (*GetBlockHeaders)(ethMsg)
|
||||||
case (BlockHeaders{}).Code():
|
case (BlockHeaders{}).Code():
|
||||||
ethMsg := new(eth.BlockHeadersPacket66)
|
ethMsg := new(eth.BlockHeadersPacket66)
|
||||||
if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
|
if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
|
||||||
return errorf("could not rlp decode message: %v", err)
|
return errorf("could not rlp decode message: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*BlockHeaders)(ethMsg)
|
return (*BlockHeaders)(ethMsg)
|
||||||
case (GetBlockBodies{}).Code():
|
case (GetBlockBodies{}).Code():
|
||||||
ethMsg := new(eth.GetBlockBodiesPacket66)
|
ethMsg := new(eth.GetBlockBodiesPacket66)
|
||||||
if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
|
if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
|
||||||
return errorf("could not rlp decode message: %v", err)
|
return errorf("could not rlp decode message: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*GetBlockBodies)(ethMsg)
|
return (*GetBlockBodies)(ethMsg)
|
||||||
case (BlockBodies{}).Code():
|
case (BlockBodies{}).Code():
|
||||||
ethMsg := new(eth.BlockBodiesPacket66)
|
ethMsg := new(eth.BlockBodiesPacket66)
|
||||||
if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
|
if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
|
||||||
return errorf("could not rlp decode message: %v", err)
|
return errorf("could not rlp decode message: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*BlockBodies)(ethMsg)
|
return (*BlockBodies)(ethMsg)
|
||||||
case (NewBlock{}).Code():
|
case (NewBlock{}).Code():
|
||||||
msg = new(NewBlock)
|
msg = new(NewBlock)
|
||||||
|
|
@ -214,18 +218,21 @@ func (c *Conn) Read() Message {
|
||||||
if err := rlp.DecodeBytes(rawData, ethMsg); err == nil {
|
if err := rlp.DecodeBytes(rawData, ethMsg); err == nil {
|
||||||
return ethMsg
|
return ethMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = new(NewPooledTransactionHashes66)
|
msg = new(NewPooledTransactionHashes66)
|
||||||
case (GetPooledTransactions{}.Code()):
|
case (GetPooledTransactions{}.Code()):
|
||||||
ethMsg := new(eth.GetPooledTransactionsPacket66)
|
ethMsg := new(eth.GetPooledTransactionsPacket66)
|
||||||
if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
|
if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
|
||||||
return errorf("could not rlp decode message: %v", err)
|
return errorf("could not rlp decode message: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*GetPooledTransactions)(ethMsg)
|
return (*GetPooledTransactions)(ethMsg)
|
||||||
case (PooledTransactions{}.Code()):
|
case (PooledTransactions{}.Code()):
|
||||||
ethMsg := new(eth.PooledTransactionsPacket66)
|
ethMsg := new(eth.PooledTransactionsPacket66)
|
||||||
if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
|
if err := rlp.DecodeBytes(rawData, ethMsg); err != nil {
|
||||||
return errorf("could not rlp decode message: %v", err)
|
return errorf("could not rlp decode message: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*PooledTransactions)(ethMsg)
|
return (*PooledTransactions)(ethMsg)
|
||||||
default:
|
default:
|
||||||
msg = errorf("invalid message code: %d", code)
|
msg = errorf("invalid message code: %d", code)
|
||||||
|
|
@ -235,8 +242,10 @@ func (c *Conn) Read() Message {
|
||||||
if err := rlp.DecodeBytes(rawData, msg); err != nil {
|
if err := rlp.DecodeBytes(rawData, msg); err != nil {
|
||||||
return errorf("could not rlp decode message: %v", err)
|
return errorf("could not rlp decode message: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
return errorf("invalid message: %s", string(rawData))
|
return errorf("invalid message: %s", string(rawData))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,9 @@ func keyToID(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(n.ID())
|
fmt.Println(n.ID())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +113,9 @@ func keyToURL(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(n.URLv4())
|
fmt.Println(n.URLv4())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,7 +124,9 @@ func keyToRecord(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(n.String())
|
fmt.Println(n.String())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,16 +147,20 @@ func makeRecord(ctx *cli.Context) (*enode.Node, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var r enr.Record
|
var r enr.Record
|
||||||
|
|
||||||
if host != "" {
|
if host != "" {
|
||||||
ip := net.ParseIP(host)
|
ip := net.ParseIP(host)
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return nil, fmt.Errorf("invalid IP address %q", host)
|
return nil, fmt.Errorf("invalid IP address %q", host)
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Set(enr.IP(ip))
|
r.Set(enr.IP(ip))
|
||||||
}
|
}
|
||||||
|
|
||||||
if udp != 0 {
|
if udp != 0 {
|
||||||
r.Set(enr.UDP(udp))
|
r.Set(enr.UDP(udp))
|
||||||
}
|
}
|
||||||
|
|
||||||
if tcp != 0 {
|
if tcp != 0 {
|
||||||
r.Set(enr.TCP(tcp))
|
r.Set(enr.TCP(tcp))
|
||||||
}
|
}
|
||||||
|
|
@ -158,5 +168,6 @@ func makeRecord(ctx *cli.Context) (*enode.Node, error) {
|
||||||
if err := enode.SignV4(&r, key); err != nil {
|
if err := enode.SignV4(&r, key); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return enode.New(enode.ValidSchemes, &r)
|
return enode.New(enode.ValidSchemes, &r)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,14 +63,17 @@ func main() {
|
||||||
func commandHasFlag(ctx *cli.Context, flag cli.Flag) bool {
|
func commandHasFlag(ctx *cli.Context, flag cli.Flag) bool {
|
||||||
names := flag.Names()
|
names := flag.Names()
|
||||||
set := make(map[string]struct{}, len(names))
|
set := make(map[string]struct{}, len(names))
|
||||||
|
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
set[name] = struct{}{}
|
set[name] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fn := range ctx.FlagNames() {
|
for _, fn := range ctx.FlagNames() {
|
||||||
if _, ok := set[fn]; ok {
|
if _, ok := set[fn]; ok {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,6 +82,7 @@ func getNodeArg(ctx *cli.Context) *enode.Node {
|
||||||
if ctx.NArg() < 1 {
|
if ctx.NArg() < 1 {
|
||||||
exit("missing node as command-line argument")
|
exit("missing node as command-line argument")
|
||||||
}
|
}
|
||||||
|
|
||||||
n, err := parseNode(ctx.Args().First())
|
n, err := parseNode(ctx.Args().First())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
exit(err)
|
exit(err)
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ func writeNodesJSON(file string, nodes nodeSet) {
|
||||||
os.Stdout.Write(nodesJSON)
|
os.Stdout.Write(nodesJSON)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.WriteFile(file, nodesJSON, 0644); err != nil {
|
if err := os.WriteFile(file, nodesJSON, 0644); err != nil {
|
||||||
exit(err)
|
exit(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -105,10 +105,12 @@ func rlpxEthTest(ctx *cli.Context) error {
|
||||||
if ctx.NArg() < 3 {
|
if ctx.NArg() < 3 {
|
||||||
exit("missing path to chain.rlp as command-line argument")
|
exit("missing path to chain.rlp as command-line argument")
|
||||||
}
|
}
|
||||||
|
|
||||||
suite, err := ethtest.NewSuite(getNodeArg(ctx), ctx.Args().Get(1), ctx.Args().Get(2))
|
suite, err := ethtest.NewSuite(getNodeArg(ctx), ctx.Args().Get(1), ctx.Args().Get(2))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
exit(err)
|
exit(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return runTests(ctx, suite.EthTests())
|
return runTests(ctx, suite.EthTests())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,6 +119,7 @@ func rlpxSnapTest(ctx *cli.Context) error {
|
||||||
if ctx.NArg() < 3 {
|
if ctx.NArg() < 3 {
|
||||||
exit("missing path to chain.rlp as command-line argument")
|
exit("missing path to chain.rlp as command-line argument")
|
||||||
}
|
}
|
||||||
|
|
||||||
suite, err := ethtest.NewSuite(getNodeArg(ctx), ctx.Args().Get(1), ctx.Args().Get(2))
|
suite, err := ethtest.NewSuite(getNodeArg(ctx), ctx.Args().Get(1), ctx.Args().Get(2))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
exit(err)
|
exit(err)
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,7 @@ func getMessage(ctx *cli.Context, msgarg int) []byte {
|
||||||
if ctx.NArg() > msgarg {
|
if ctx.NArg() > msgarg {
|
||||||
utils.Fatalf("Can't use --msgfile and message argument at the same time.")
|
utils.Fatalf("Can't use --msgfile and message argument at the same time.")
|
||||||
}
|
}
|
||||||
|
|
||||||
msg, err := os.ReadFile(file)
|
msg, err := os.ReadFile(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Can't read message file: %v", err)
|
utils.Fatalf("Can't read message file: %v", err)
|
||||||
|
|
@ -155,6 +156,7 @@ func getMessage(ctx *cli.Context, msgarg int) []byte {
|
||||||
} else if ctx.NArg() == msgarg+1 {
|
} else if ctx.NArg() == msgarg+1 {
|
||||||
return []byte(ctx.Args().Get(msgarg))
|
return []byte(ctx.Args().Get(msgarg))
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.Fatalf("Invalid number of arguments: want %d, got %d", msgarg+1, ctx.NArg())
|
utils.Fatalf("Invalid number of arguments: want %d, got %d", msgarg+1, ctx.NArg())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,14 +48,18 @@ func blockTestCmd(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tests map[string]tests.BlockTest
|
var tests map[string]tests.BlockTest
|
||||||
|
|
||||||
if err = json.Unmarshal(src, &tests); err != nil {
|
if err = json.Unmarshal(src, &tests); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
if err := test.Run(false); err != nil {
|
if err := test.Run(false); err != nil {
|
||||||
return fmt.Errorf("test %v: %w", i, err)
|
return fmt.Errorf("test %v: %w", i, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,7 @@ func (i *bbInput) ToBlock() *types.Block {
|
||||||
if header.Difficulty != nil {
|
if header.Difficulty != nil {
|
||||||
header.Difficulty = i.Header.Difficulty
|
header.Difficulty = i.Header.Difficulty
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.NewBlockWithHeader(header).WithBody(i.Txs, i.Ommers).WithWithdrawals(i.Withdrawals)
|
return types.NewBlockWithHeader(header).WithBody(i.Txs, i.Ommers).WithWithdrawals(i.Withdrawals)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -317,11 +318,13 @@ func readInput(ctx *cli.Context) (*bbInput, error) {
|
||||||
}
|
}
|
||||||
inputData.OmmersRlp = ommers
|
inputData.OmmersRlp = ommers
|
||||||
}
|
}
|
||||||
|
|
||||||
if withdrawalsStr != stdinSelector && withdrawalsStr != "" {
|
if withdrawalsStr != stdinSelector && withdrawalsStr != "" {
|
||||||
var withdrawals []*types.Withdrawal
|
var withdrawals []*types.Withdrawal
|
||||||
if err := readFile(withdrawalsStr, "withdrawals", &withdrawals); err != nil {
|
if err := readFile(withdrawalsStr, "withdrawals", &withdrawals); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
inputData.Withdrawals = withdrawals
|
inputData.Withdrawals = withdrawals
|
||||||
}
|
}
|
||||||
if txsStr != stdinSelector {
|
if txsStr != stdinSelector {
|
||||||
|
|
@ -367,6 +370,7 @@ func dispatchBlock(ctx *cli.Context, baseDir string, block *types.Block) error {
|
||||||
Rlp hexutil.Bytes `json:"rlp"`
|
Rlp hexutil.Bytes `json:"rlp"`
|
||||||
Hash common.Hash `json:"hash"`
|
Hash common.Hash `json:"hash"`
|
||||||
}
|
}
|
||||||
|
|
||||||
enc := blockInfo{
|
enc := blockInfo{
|
||||||
Rlp: raw,
|
Rlp: raw,
|
||||||
Hash: block.Hash(),
|
Hash: block.Hash(),
|
||||||
|
|
|
||||||
|
|
@ -175,6 +175,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
vmConfig.Tracer = tracer
|
vmConfig.Tracer = tracer
|
||||||
|
|
||||||
statedb.SetTxContext(tx.Hash(), txIndex)
|
statedb.SetTxContext(tx.Hash(), txIndex)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -190,6 +191,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
statedb.RevertToSnapshot(snapshot)
|
statedb.RevertToSnapshot(snapshot)
|
||||||
log.Info("rejected tx", "index", i, "hash", tx.Hash(), "from", msg.From, "error", err)
|
log.Info("rejected tx", "index", i, "hash", tx.Hash(), "from", msg.From, "error", err)
|
||||||
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
|
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
|
||||||
|
|
||||||
gaspool.SetGas(prevGas)
|
gaspool.SetGas(prevGas)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -285,6 +287,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
GasUsed: (math.HexOrDecimal64)(gasUsed),
|
GasUsed: (math.HexOrDecimal64)(gasUsed),
|
||||||
BaseFee: (*math.HexOrDecimal256)(vmContext.BaseFee),
|
BaseFee: (*math.HexOrDecimal256)(vmContext.BaseFee),
|
||||||
}
|
}
|
||||||
|
|
||||||
if pre.Env.Withdrawals != nil {
|
if pre.Env.Withdrawals != nil {
|
||||||
h := types.DeriveSha(types.Withdrawals(pre.Env.Withdrawals), trie.NewStackTrie(nil))
|
h := types.DeriveSha(types.Withdrawals(pre.Env.Withdrawals), trie.NewStackTrie(nil))
|
||||||
execRs.WithdrawalsRoot = &h
|
execRs.WithdrawalsRoot = &h
|
||||||
|
|
|
||||||
|
|
@ -265,8 +265,10 @@ func Transition(ctx *cli.Context) error {
|
||||||
if chainConfig.IsShanghai(prestate.Env.Number) && prestate.Env.Withdrawals == nil {
|
if chainConfig.IsShanghai(prestate.Env.Number) && prestate.Env.Withdrawals == nil {
|
||||||
return NewError(ErrorConfig, errors.New("Shanghai config but missing 'withdrawals' in env section"))
|
return NewError(ErrorConfig, errors.New("Shanghai config but missing 'withdrawals' in env section"))
|
||||||
}
|
}
|
||||||
|
|
||||||
isMerged := chainConfig.TerminalTotalDifficulty != nil && chainConfig.TerminalTotalDifficulty.BitLen() == 0
|
isMerged := chainConfig.TerminalTotalDifficulty != nil && chainConfig.TerminalTotalDifficulty.BitLen() == 0
|
||||||
env := prestate.Env
|
env := prestate.Env
|
||||||
|
|
||||||
if isMerged {
|
if isMerged {
|
||||||
// post-merge:
|
// post-merge:
|
||||||
// - random must be supplied
|
// - random must be supplied
|
||||||
|
|
@ -277,6 +279,7 @@ func Transition(ctx *cli.Context) error {
|
||||||
case env.Difficulty != nil && env.Difficulty.BitLen() != 0:
|
case env.Difficulty != nil && env.Difficulty.BitLen() != 0:
|
||||||
return NewError(ErrorConfig, errors.New("post-merge difficulty must be zero (or omitted) in env"))
|
return NewError(ErrorConfig, errors.New("post-merge difficulty must be zero (or omitted) in env"))
|
||||||
}
|
}
|
||||||
|
|
||||||
prestate.Env.Difficulty = nil
|
prestate.Env.Difficulty = nil
|
||||||
} else if env.Difficulty == nil {
|
} else if env.Difficulty == nil {
|
||||||
// pre-merge:
|
// pre-merge:
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ func runCmd(ctx *cli.Context) error {
|
||||||
genesisConfig *core.Genesis
|
genesisConfig *core.Genesis
|
||||||
preimages = ctx.Bool(DumpFlag.Name)
|
preimages = ctx.Bool(DumpFlag.Name)
|
||||||
)
|
)
|
||||||
|
|
||||||
if ctx.Bool(MachineFlag.Name) {
|
if ctx.Bool(MachineFlag.Name) {
|
||||||
tracer = logger.NewJSONLogger(logconfig, os.Stdout)
|
tracer = logger.NewJSONLogger(logconfig, os.Stdout)
|
||||||
} else if ctx.Bool(DebugFlag.Name) {
|
} else if ctx.Bool(DebugFlag.Name) {
|
||||||
|
|
@ -136,6 +137,7 @@ func runCmd(ctx *cli.Context) error {
|
||||||
} else {
|
} else {
|
||||||
debugLogger = logger.NewStructLogger(logconfig)
|
debugLogger = logger.NewStructLogger(logconfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.String(GenesisFlag.Name) != "" {
|
if ctx.String(GenesisFlag.Name) != "" {
|
||||||
gen := readGenesis(ctx.String(GenesisFlag.Name))
|
gen := readGenesis(ctx.String(GenesisFlag.Name))
|
||||||
genesisConfig = gen
|
genesisConfig = gen
|
||||||
|
|
@ -149,6 +151,7 @@ func runCmd(ctx *cli.Context) error {
|
||||||
statedb, _ = state.New(common.Hash{}, sdb, nil)
|
statedb, _ = state.New(common.Hash{}, sdb, nil)
|
||||||
genesisConfig = new(core.Genesis)
|
genesisConfig = new(core.Genesis)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.String(SenderFlag.Name) != "" {
|
if ctx.String(SenderFlag.Name) != "" {
|
||||||
sender = common.HexToAddress(ctx.String(SenderFlag.Name))
|
sender = common.HexToAddress(ctx.String(SenderFlag.Name))
|
||||||
}
|
}
|
||||||
|
|
@ -159,6 +162,7 @@ func runCmd(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var code []byte
|
var code []byte
|
||||||
|
|
||||||
codeFileFlag := ctx.String(CodeFileFlag.Name)
|
codeFileFlag := ctx.String(CodeFileFlag.Name)
|
||||||
codeFlag := ctx.String(CodeFlag.Name)
|
codeFlag := ctx.String(CodeFlag.Name)
|
||||||
|
|
||||||
|
|
@ -202,6 +206,7 @@ func runCmd(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
code = common.Hex2Bytes(bin)
|
code = common.Hex2Bytes(bin)
|
||||||
}
|
}
|
||||||
|
|
||||||
initialGas := ctx.Uint64(GasFlag.Name)
|
initialGas := ctx.Uint64(GasFlag.Name)
|
||||||
if genesisConfig.GasLimit != 0 {
|
if genesisConfig.GasLimit != 0 {
|
||||||
initialGas = genesisConfig.GasLimit
|
initialGas = genesisConfig.GasLimit
|
||||||
|
|
@ -241,6 +246,7 @@ func runCmd(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var hexInput []byte
|
var hexInput []byte
|
||||||
|
|
||||||
if inputFileFlag := ctx.String(InputFileFlag.Name); inputFileFlag != "" {
|
if inputFileFlag := ctx.String(InputFileFlag.Name); inputFileFlag != "" {
|
||||||
var err error
|
var err error
|
||||||
if hexInput, err = os.ReadFile(inputFileFlag); err != nil {
|
if hexInput, err = os.ReadFile(inputFileFlag); err != nil {
|
||||||
|
|
@ -250,14 +256,18 @@ func runCmd(ctx *cli.Context) error {
|
||||||
} else {
|
} else {
|
||||||
hexInput = []byte(ctx.String(InputFlag.Name))
|
hexInput = []byte(ctx.String(InputFlag.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
hexInput = bytes.TrimSpace(hexInput)
|
hexInput = bytes.TrimSpace(hexInput)
|
||||||
|
|
||||||
if len(hexInput)%2 != 0 {
|
if len(hexInput)%2 != 0 {
|
||||||
fmt.Println("input length must be even")
|
fmt.Println("input length must be even")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
input := common.FromHex(string(hexInput))
|
input := common.FromHex(string(hexInput))
|
||||||
|
|
||||||
var execFunc func() ([]byte, uint64, error)
|
var execFunc func() ([]byte, uint64, error)
|
||||||
|
|
||||||
if ctx.Bool(CreateFlag.Name) {
|
if ctx.Bool(CreateFlag.Name) {
|
||||||
input = append(code, input...)
|
input = append(code, input...)
|
||||||
execFunc = func() ([]byte, uint64, error) {
|
execFunc = func() ([]byte, uint64, error) {
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ func stateTestCmd(ctx *cli.Context) error {
|
||||||
if s != nil {
|
if s != nil {
|
||||||
root := s.IntermediateRoot(false)
|
root := s.IntermediateRoot(false)
|
||||||
result.Root = &root
|
result.Root = &root
|
||||||
|
|
||||||
if ctx.Bool(MachineFlag.Name) {
|
if ctx.Bool(MachineFlag.Name) {
|
||||||
fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root)
|
fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root)
|
||||||
}
|
}
|
||||||
|
|
@ -110,6 +111,7 @@ func stateTestCmd(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Test failed, mark as so and dump any state to aid debugging
|
// Test failed, mark as so and dump any state to aid debugging
|
||||||
result.Pass, result.Error = false, err.Error()
|
result.Pass, result.Error = false, err.Error()
|
||||||
|
|
||||||
if ctx.Bool(DumpFlag.Name) && s != nil {
|
if ctx.Bool(DumpFlag.Name) && s != nil {
|
||||||
dump := s.RawDump(nil)
|
dump := s.RawDump(nil)
|
||||||
result.State = &dump
|
result.State = &dump
|
||||||
|
|
|
||||||
|
|
@ -420,6 +420,7 @@ func (args *b11rInput) get(base string) []string {
|
||||||
out = append(out, "--input.ommers")
|
out = append(out, "--input.ommers")
|
||||||
out = append(out, fmt.Sprintf("%v/%v", base, opt))
|
out = append(out, fmt.Sprintf("%v/%v", base, opt))
|
||||||
}
|
}
|
||||||
|
|
||||||
if opt := args.inWithdrawals; opt != "" {
|
if opt := args.inWithdrawals; opt != "" {
|
||||||
out = append(out, "--input.withdrawals")
|
out = append(out, "--input.withdrawals")
|
||||||
out = append(out, fmt.Sprintf("%v/%v", base, opt))
|
out = append(out, fmt.Sprintf("%v/%v", base, opt))
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,7 @@ func main() {
|
||||||
pass := strings.TrimSuffix(string(blob), "\n")
|
pass := strings.TrimSuffix(string(blob), "\n")
|
||||||
|
|
||||||
ks := keystore.NewKeyStore(filepath.Join(os.Getenv("HOME"), ".faucet", "keys"), keystore.StandardScryptN, keystore.StandardScryptP)
|
ks := keystore.NewKeyStore(filepath.Join(os.Getenv("HOME"), ".faucet", "keys"), keystore.StandardScryptN, keystore.StandardScryptP)
|
||||||
|
|
||||||
if blob, err = os.ReadFile(*accJSONFlag); err != nil {
|
if blob, err = os.ReadFile(*accJSONFlag); err != nil {
|
||||||
log.Crit("Failed to read account key contents", "file", *accJSONFlag, "err", err)
|
log.Crit("Failed to read account key contents", "file", *accJSONFlag, "err", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -236,6 +236,7 @@ func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrErr
|
||||||
}
|
}
|
||||||
fmt.Println("Testing your password against all of them...")
|
fmt.Println("Testing your password against all of them...")
|
||||||
var match *accounts.Account
|
var match *accounts.Account
|
||||||
|
|
||||||
for i, a := range err.Matches {
|
for i, a := range err.Matches {
|
||||||
if e := ks.Unlock(a, auth); e == nil {
|
if e := ks.Unlock(a, auth); e == nil {
|
||||||
match = &err.Matches[i]
|
match = &err.Matches[i]
|
||||||
|
|
@ -302,9 +303,11 @@ func accountUpdate(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
stack, _ := makeConfigNode(ctx)
|
stack, _ := makeConfigNode(ctx)
|
||||||
backends := stack.AccountManager().Backends(keystore.KeyStoreType)
|
backends := stack.AccountManager().Backends(keystore.KeyStoreType)
|
||||||
|
|
||||||
if len(backends) == 0 {
|
if len(backends) == 0 {
|
||||||
utils.Fatalf("Keystore is not available")
|
utils.Fatalf("Keystore is not available")
|
||||||
}
|
}
|
||||||
|
|
||||||
ks := backends[0].(*keystore.KeyStore)
|
ks := backends[0].(*keystore.KeyStore)
|
||||||
|
|
||||||
for _, addr := range ctx.Args().Slice() {
|
for _, addr := range ctx.Args().Slice() {
|
||||||
|
|
@ -321,6 +324,7 @@ func importWallet(ctx *cli.Context) error {
|
||||||
if ctx.Args().Len() != 1 {
|
if ctx.Args().Len() != 1 {
|
||||||
utils.Fatalf("keyfile must be given as the only argument")
|
utils.Fatalf("keyfile must be given as the only argument")
|
||||||
}
|
}
|
||||||
|
|
||||||
keyfile := ctx.Args().First()
|
keyfile := ctx.Args().First()
|
||||||
keyJSON, err := os.ReadFile(keyfile)
|
keyJSON, err := os.ReadFile(keyfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -334,6 +338,7 @@ func importWallet(ctx *cli.Context) error {
|
||||||
if len(backends) == 0 {
|
if len(backends) == 0 {
|
||||||
utils.Fatalf("Keystore is not available")
|
utils.Fatalf("Keystore is not available")
|
||||||
}
|
}
|
||||||
|
|
||||||
ks := backends[0].(*keystore.KeyStore)
|
ks := backends[0].(*keystore.KeyStore)
|
||||||
acct, err := ks.ImportPreSaleKey(keyJSON, passphrase)
|
acct, err := ks.ImportPreSaleKey(keyJSON, passphrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -347,6 +352,7 @@ func accountImport(ctx *cli.Context) error {
|
||||||
if ctx.Args().Len() != 1 {
|
if ctx.Args().Len() != 1 {
|
||||||
utils.Fatalf("keyfile must be given as the only argument")
|
utils.Fatalf("keyfile must be given as the only argument")
|
||||||
}
|
}
|
||||||
|
|
||||||
keyfile := ctx.Args().First()
|
keyfile := ctx.Args().First()
|
||||||
key, err := crypto.LoadECDSA(keyfile)
|
key, err := crypto.LoadECDSA(keyfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -359,6 +365,7 @@ func accountImport(ctx *cli.Context) error {
|
||||||
if len(backends) == 0 {
|
if len(backends) == 0 {
|
||||||
utils.Fatalf("Keystore is not available")
|
utils.Fatalf("Keystore is not available")
|
||||||
}
|
}
|
||||||
|
|
||||||
ks := backends[0].(*keystore.KeyStore)
|
ks := backends[0].(*keystore.KeyStore)
|
||||||
acct, err := ks.ImportECDSA(key, passphrase)
|
acct, err := ks.ImportECDSA(key, passphrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ func TestAccountListEmpty(t *testing.T) {
|
||||||
|
|
||||||
func TestAccountList(t *testing.T) {
|
func TestAccountList(t *testing.T) {
|
||||||
datadir := tmpDatadirWithKeystore(t)
|
datadir := tmpDatadirWithKeystore(t)
|
||||||
|
|
||||||
var want = `
|
var want = `
|
||||||
Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8
|
Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8
|
||||||
Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}/keystore/aaa
|
Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}/keystore/aaa
|
||||||
|
|
@ -122,12 +123,14 @@ func TestAccountHelp(t *testing.T) {
|
||||||
|
|
||||||
geth := runGeth(t, "account", "-h")
|
geth := runGeth(t, "account", "-h")
|
||||||
geth.WaitExit()
|
geth.WaitExit()
|
||||||
|
|
||||||
if have, want := geth.ExitStatus(), 0; have != want {
|
if have, want := geth.ExitStatus(), 0; have != want {
|
||||||
t.Errorf("exit error, have %d want %d", have, want)
|
t.Errorf("exit error, have %d want %d", have, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
geth = runGeth(t, "account", "import", "-h")
|
geth = runGeth(t, "account", "import", "-h")
|
||||||
geth.WaitExit()
|
geth.WaitExit()
|
||||||
|
|
||||||
if have, want := geth.ExitStatus(), 0; have != want {
|
if have, want := geth.ExitStatus(), 0; have != want {
|
||||||
t.Errorf("exit error, have %d want %d", have, want)
|
t.Errorf("exit error, have %d want %d", have, want)
|
||||||
}
|
}
|
||||||
|
|
@ -136,13 +139,16 @@ func TestAccountHelp(t *testing.T) {
|
||||||
func importAccountWithExpect(t *testing.T, key string, expected string) {
|
func importAccountWithExpect(t *testing.T, key string, expected string) {
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
keyfile := filepath.Join(dir, "key.prv")
|
keyfile := filepath.Join(dir, "key.prv")
|
||||||
|
|
||||||
if err := os.WriteFile(keyfile, []byte(key), 0600); err != nil {
|
if err := os.WriteFile(keyfile, []byte(key), 0600); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
passwordFile := filepath.Join(dir, "password.txt")
|
passwordFile := filepath.Join(dir, "password.txt")
|
||||||
|
|
||||||
if err := os.WriteFile(passwordFile, []byte("foobar"), 0600); err != nil {
|
if err := os.WriteFile(passwordFile, []byte("foobar"), 0600); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
geth := runGeth(t, "--lightkdf", "account", "import", "-password", passwordFile, keyfile)
|
geth := runGeth(t, "--lightkdf", "account", "import", "-password", passwordFile, keyfile)
|
||||||
defer geth.ExpectExit()
|
defer geth.ExpectExit()
|
||||||
geth.Expect(expected)
|
geth.Expect(expected)
|
||||||
|
|
|
||||||
|
|
@ -36,26 +36,31 @@ func (t *testHandler) ServeHTTP(out http.ResponseWriter, in *http.Request) {
|
||||||
// that custom headers are forwarded to the target.
|
// that custom headers are forwarded to the target.
|
||||||
func TestAttachWithHeaders(t *testing.T) {
|
func TestAttachWithHeaders(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
ln, err := net.Listen("tcp", "localhost:0")
|
ln, err := net.Listen("tcp", "localhost:0")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
port := ln.Addr().(*net.TCPAddr).Port
|
|
||||||
testReceiveHeaders(t, ln, "attach", "-H", "first: one", "-H", "second: two", fmt.Sprintf("http://localhost:%d", port))
|
|
||||||
// This way to do it fails due to flag ordering:
|
// This way to do it fails due to flag ordering:
|
||||||
//
|
|
||||||
// testReceiveHeaders(t, ln, "-H", "first: one", "-H", "second: two", "attach", fmt.Sprintf("http://localhost:%d", port))
|
// testReceiveHeaders(t, ln, "-H", "first: one", "-H", "second: two", "attach", fmt.Sprintf("http://localhost:%d", port))
|
||||||
// This is fixed in a follow-up PR.
|
// This is fixed in a follow-up PR.
|
||||||
|
port := ln.Addr().(*net.TCPAddr).Port
|
||||||
|
testReceiveHeaders(t, ln, "attach", "-H", "first: one", "-H", "second: two", fmt.Sprintf("http://localhost:%d", port))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestAttachWithHeaders tests that 'geth db --remotedb' with custom headers works, i.e
|
// TestAttachWithHeaders tests that 'geth db --remotedb' with custom headers works, i.e
|
||||||
// that custom headers are forwarded to the target.
|
// that custom headers are forwarded to the target.
|
||||||
func TestRemoteDbWithHeaders(t *testing.T) {
|
func TestRemoteDbWithHeaders(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
ln, err := net.Listen("tcp", "localhost:0")
|
ln, err := net.Listen("tcp", "localhost:0")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
port := ln.Addr().(*net.TCPAddr).Port
|
port := ln.Addr().(*net.TCPAddr).Port
|
||||||
testReceiveHeaders(t, ln, "db", "metadata", "--remotedb", fmt.Sprintf("http://localhost:%d", port), "-H", "first: one", "-H", "second: two")
|
testReceiveHeaders(t, ln, "db", "metadata", "--remotedb", fmt.Sprintf("http://localhost:%d", port), "-H", "first: one", "-H", "second: two")
|
||||||
}
|
}
|
||||||
|
|
@ -64,6 +69,7 @@ func testReceiveHeaders(t *testing.T, ln net.Listener, gethArgs ...string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
var ok uint32
|
var ok uint32
|
||||||
|
|
||||||
server := &http.Server{
|
server := &http.Server{
|
||||||
Addr: "localhost:0",
|
Addr: "localhost:0",
|
||||||
Handler: &testHandler{func(w http.ResponseWriter, r *http.Request) {
|
Handler: &testHandler{func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
@ -77,8 +83,10 @@ func testReceiveHeaders(t *testing.T, ln net.Listener, gethArgs ...string) {
|
||||||
atomic.StoreUint32(&ok, 1)
|
atomic.StoreUint32(&ok, 1)
|
||||||
}}}
|
}}}
|
||||||
go server.Serve(ln)
|
go server.Serve(ln)
|
||||||
|
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
runGeth(t, gethArgs...).WaitExit()
|
runGeth(t, gethArgs...).WaitExit()
|
||||||
|
|
||||||
if atomic.LoadUint32(&ok) != 1 {
|
if atomic.LoadUint32(&ok) != 1 {
|
||||||
t.Fatal("Test fail, expected invocation to succeed")
|
t.Fatal("Test fail, expected invocation to succeed")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,7 @@ func initGenesis(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Failed to open database: %v", err)
|
utils.Fatalf("Failed to open database: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
triedb := trie.NewDatabaseWithConfig(chaindb, &trie.Config{
|
triedb := trie.NewDatabaseWithConfig(chaindb, &trie.Config{
|
||||||
Preimages: ctx.Bool(utils.CachePreimagesFlag.Name),
|
Preimages: ctx.Bool(utils.CachePreimagesFlag.Name),
|
||||||
})
|
})
|
||||||
|
|
@ -215,32 +216,41 @@ func dumpGenesis(ctx *cli.Context) error {
|
||||||
if err := json.NewEncoder(os.Stdout).Encode(genesis); err != nil {
|
if err := json.NewEncoder(os.Stdout).Encode(genesis); err != nil {
|
||||||
utils.Fatalf("could not encode genesis: %s", err)
|
utils.Fatalf("could not encode genesis: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// dump whatever already exists in the datadir
|
// dump whatever already exists in the datadir
|
||||||
stack, _ := makeConfigNode(ctx)
|
stack, _ := makeConfigNode(ctx)
|
||||||
for _, name := range []string{"chaindata", "lightchaindata"} {
|
for _, name := range []string{"chaindata", "lightchaindata"} {
|
||||||
db, err := stack.OpenDatabase(name, 0, 0, "", true)
|
db, err := stack.OpenDatabase(name, 0, 0, "", true)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
genesis, err := core.ReadGenesis(db)
|
genesis, err := core.ReadGenesis(db)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("failed to read genesis: %s", err)
|
utils.Fatalf("failed to read genesis: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
db.Close()
|
db.Close()
|
||||||
|
|
||||||
if err := json.NewEncoder(os.Stdout).Encode(*genesis); err != nil {
|
if err := json.NewEncoder(os.Stdout).Encode(*genesis); err != nil {
|
||||||
utils.Fatalf("could not encode stored genesis: %s", err)
|
utils.Fatalf("could not encode stored genesis: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(utils.DataDirFlag.Name) {
|
if ctx.IsSet(utils.DataDirFlag.Name) {
|
||||||
utils.Fatalf("no existing datadir at %s", stack.Config().DataDir)
|
utils.Fatalf("no existing datadir at %s", stack.Config().DataDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.Fatalf("no network preset provided. no exisiting genesis in the default datadir")
|
utils.Fatalf("no network preset provided. no exisiting genesis in the default datadir")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -337,6 +347,7 @@ func exportChain(ctx *cli.Context) error {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
fp := ctx.Args().First()
|
fp := ctx.Args().First()
|
||||||
|
|
||||||
if ctx.Args().Len() < 3 {
|
if ctx.Args().Len() < 3 {
|
||||||
err = utils.ExportChain(chain, fp)
|
err = utils.ExportChain(chain, fp)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -465,6 +476,7 @@ func dump(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &trie.Config{
|
config := &trie.Config{
|
||||||
Preimages: true, // always enable preimage lookup
|
Preimages: true, // always enable preimage lookup
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,7 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.SetEthConfig(ctx, stack, &cfg.Eth)
|
utils.SetEthConfig(ctx, stack, &cfg.Eth)
|
||||||
|
|
||||||
if ctx.IsSet(utils.EthStatsURLFlag.Name) {
|
if ctx.IsSet(utils.EthStatsURLFlag.Name) {
|
||||||
cfg.Ethstats.URL = ctx.String(utils.EthStatsURLFlag.Name)
|
cfg.Ethstats.URL = ctx.String(utils.EthStatsURLFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
@ -188,45 +189,59 @@ func dumpConfig(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) {
|
func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) {
|
||||||
|
|
||||||
if ctx.IsSet(utils.MetricsEnabledFlag.Name) {
|
if ctx.IsSet(utils.MetricsEnabledFlag.Name) {
|
||||||
cfg.Metrics.Enabled = ctx.Bool(utils.MetricsEnabledFlag.Name)
|
cfg.Metrics.Enabled = ctx.Bool(utils.MetricsEnabledFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(utils.MetricsEnabledExpensiveFlag.Name) {
|
if ctx.IsSet(utils.MetricsEnabledExpensiveFlag.Name) {
|
||||||
cfg.Metrics.EnabledExpensive = ctx.Bool(utils.MetricsEnabledExpensiveFlag.Name)
|
cfg.Metrics.EnabledExpensive = ctx.Bool(utils.MetricsEnabledExpensiveFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(utils.MetricsHTTPFlag.Name) {
|
if ctx.IsSet(utils.MetricsHTTPFlag.Name) {
|
||||||
cfg.Metrics.HTTP = ctx.String(utils.MetricsHTTPFlag.Name)
|
cfg.Metrics.HTTP = ctx.String(utils.MetricsHTTPFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(utils.MetricsPortFlag.Name) {
|
if ctx.IsSet(utils.MetricsPortFlag.Name) {
|
||||||
cfg.Metrics.Port = ctx.Int(utils.MetricsPortFlag.Name)
|
cfg.Metrics.Port = ctx.Int(utils.MetricsPortFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(utils.MetricsEnableInfluxDBFlag.Name) {
|
if ctx.IsSet(utils.MetricsEnableInfluxDBFlag.Name) {
|
||||||
cfg.Metrics.EnableInfluxDB = ctx.Bool(utils.MetricsEnableInfluxDBFlag.Name)
|
cfg.Metrics.EnableInfluxDB = ctx.Bool(utils.MetricsEnableInfluxDBFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(utils.MetricsInfluxDBEndpointFlag.Name) {
|
if ctx.IsSet(utils.MetricsInfluxDBEndpointFlag.Name) {
|
||||||
cfg.Metrics.InfluxDBEndpoint = ctx.String(utils.MetricsInfluxDBEndpointFlag.Name)
|
cfg.Metrics.InfluxDBEndpoint = ctx.String(utils.MetricsInfluxDBEndpointFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(utils.MetricsInfluxDBDatabaseFlag.Name) {
|
if ctx.IsSet(utils.MetricsInfluxDBDatabaseFlag.Name) {
|
||||||
cfg.Metrics.InfluxDBDatabase = ctx.String(utils.MetricsInfluxDBDatabaseFlag.Name)
|
cfg.Metrics.InfluxDBDatabase = ctx.String(utils.MetricsInfluxDBDatabaseFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(utils.MetricsInfluxDBUsernameFlag.Name) {
|
if ctx.IsSet(utils.MetricsInfluxDBUsernameFlag.Name) {
|
||||||
cfg.Metrics.InfluxDBUsername = ctx.String(utils.MetricsInfluxDBUsernameFlag.Name)
|
cfg.Metrics.InfluxDBUsername = ctx.String(utils.MetricsInfluxDBUsernameFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(utils.MetricsInfluxDBPasswordFlag.Name) {
|
if ctx.IsSet(utils.MetricsInfluxDBPasswordFlag.Name) {
|
||||||
cfg.Metrics.InfluxDBPassword = ctx.String(utils.MetricsInfluxDBPasswordFlag.Name)
|
cfg.Metrics.InfluxDBPassword = ctx.String(utils.MetricsInfluxDBPasswordFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(utils.MetricsInfluxDBTagsFlag.Name) {
|
if ctx.IsSet(utils.MetricsInfluxDBTagsFlag.Name) {
|
||||||
cfg.Metrics.InfluxDBTags = ctx.String(utils.MetricsInfluxDBTagsFlag.Name)
|
cfg.Metrics.InfluxDBTags = ctx.String(utils.MetricsInfluxDBTagsFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(utils.MetricsEnableInfluxDBV2Flag.Name) {
|
if ctx.IsSet(utils.MetricsEnableInfluxDBV2Flag.Name) {
|
||||||
cfg.Metrics.EnableInfluxDBV2 = ctx.Bool(utils.MetricsEnableInfluxDBV2Flag.Name)
|
cfg.Metrics.EnableInfluxDBV2 = ctx.Bool(utils.MetricsEnableInfluxDBV2Flag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(utils.MetricsInfluxDBTokenFlag.Name) {
|
if ctx.IsSet(utils.MetricsInfluxDBTokenFlag.Name) {
|
||||||
cfg.Metrics.InfluxDBToken = ctx.String(utils.MetricsInfluxDBTokenFlag.Name)
|
cfg.Metrics.InfluxDBToken = ctx.String(utils.MetricsInfluxDBTokenFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(utils.MetricsInfluxDBBucketFlag.Name) {
|
if ctx.IsSet(utils.MetricsInfluxDBBucketFlag.Name) {
|
||||||
cfg.Metrics.InfluxDBBucket = ctx.String(utils.MetricsInfluxDBBucketFlag.Name)
|
cfg.Metrics.InfluxDBBucket = ctx.String(utils.MetricsInfluxDBBucketFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(utils.MetricsInfluxDBOrganizationFlag.Name) {
|
if ctx.IsSet(utils.MetricsInfluxDBOrganizationFlag.Name) {
|
||||||
cfg.Metrics.InfluxDBOrganization = ctx.String(utils.MetricsInfluxDBOrganizationFlag.Name)
|
cfg.Metrics.InfluxDBOrganization = ctx.String(utils.MetricsInfluxDBOrganizationFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,7 @@ func remoteConsole(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
endpoint = fmt.Sprintf("%s/bor.ipc", path)
|
endpoint = fmt.Sprintf("%s/bor.ipc", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := utils.DialRPCWithHeaders(endpoint, ctx.StringSlice(utils.HttpHeaderFlag.Name))
|
client, err := utils.DialRPCWithHeaders(endpoint, ctx.StringSlice(utils.HttpHeaderFlag.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Unable to attach to remote geth: %v", err)
|
utils.Fatalf("Unable to attach to remote geth: %v", err)
|
||||||
|
|
@ -173,6 +174,7 @@ func ephemeralConsole(ctx *cli.Context) error {
|
||||||
for _, file := range ctx.Args().Slice() {
|
for _, file := range ctx.Args().Slice() {
|
||||||
b.Write([]byte(fmt.Sprintf("loadScript('%s');", file)))
|
b.Write([]byte(fmt.Sprintf("loadScript('%s');", file)))
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.Fatalf(`The "js" command is deprecated. Please use the following instead:
|
utils.Fatalf(`The "js" command is deprecated. Please use the following instead:
|
||||||
geth --exec "%s" console`, b.String())
|
geth --exec "%s" console`, b.String())
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -291,9 +291,11 @@ func checkStateContent(ctx *cli.Context) error {
|
||||||
prefix []byte
|
prefix []byte
|
||||||
start []byte
|
start []byte
|
||||||
)
|
)
|
||||||
|
|
||||||
if ctx.NArg() > 1 {
|
if ctx.NArg() > 1 {
|
||||||
return fmt.Errorf("max 1 argument: %v", ctx.Command.ArgsUsage)
|
return fmt.Errorf("max 1 argument: %v", ctx.Command.ArgsUsage)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.NArg() > 0 {
|
if ctx.NArg() > 0 {
|
||||||
if d, err := hexutil.Decode(ctx.Args().First()); err != nil {
|
if d, err := hexutil.Decode(ctx.Args().First()); err != nil {
|
||||||
return fmt.Errorf("failed to hex-decode 'start': %v", err)
|
return fmt.Errorf("failed to hex-decode 'start': %v", err)
|
||||||
|
|
@ -301,11 +303,13 @@ func checkStateContent(ctx *cli.Context) error {
|
||||||
start = d
|
start = d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stack, _ := makeConfigNode(ctx)
|
stack, _ := makeConfigNode(ctx)
|
||||||
defer stack.Close()
|
defer stack.Close()
|
||||||
|
|
||||||
db := utils.MakeChainDatabase(ctx, stack, true)
|
db := utils.MakeChainDatabase(ctx, stack, true)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
it = rawdb.NewKeyLengthIterator(db.NewIterator(prefix, start), 32)
|
it = rawdb.NewKeyLengthIterator(db.NewIterator(prefix, start), 32)
|
||||||
hasher = crypto.NewKeccakState()
|
hasher = crypto.NewKeccakState()
|
||||||
|
|
@ -315,28 +319,37 @@ func checkStateContent(ctx *cli.Context) error {
|
||||||
startTime = time.Now()
|
startTime = time.Now()
|
||||||
lastLog = time.Now()
|
lastLog = time.Now()
|
||||||
)
|
)
|
||||||
|
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
count++
|
count++
|
||||||
|
|
||||||
k := it.Key()
|
k := it.Key()
|
||||||
v := it.Value()
|
v := it.Value()
|
||||||
|
|
||||||
hasher.Reset()
|
hasher.Reset()
|
||||||
hasher.Write(v)
|
hasher.Write(v)
|
||||||
hasher.Read(got)
|
hasher.Read(got)
|
||||||
|
|
||||||
if !bytes.Equal(k, got) {
|
if !bytes.Equal(k, got) {
|
||||||
errs++
|
errs++
|
||||||
|
|
||||||
fmt.Printf("Error at %#x\n", k)
|
fmt.Printf("Error at %#x\n", k)
|
||||||
fmt.Printf(" Hash: %#x\n", got)
|
fmt.Printf(" Hash: %#x\n", got)
|
||||||
fmt.Printf(" Data: %#x\n", v)
|
fmt.Printf(" Data: %#x\n", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if time.Since(lastLog) > 8*time.Second {
|
if time.Since(lastLog) > 8*time.Second {
|
||||||
log.Info("Iterating the database", "at", fmt.Sprintf("%#x", k), "elapsed", common.PrettyDuration(time.Since(startTime)))
|
log.Info("Iterating the database", "at", fmt.Sprintf("%#x", k), "elapsed", common.PrettyDuration(time.Since(startTime)))
|
||||||
lastLog = time.Now()
|
lastLog = time.Now()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := it.Error(); err != nil {
|
if err := it.Error(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Iterated the state content", "errors", errs, "items", count)
|
log.Info("Iterated the state content", "errors", errs, "items", count)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -454,6 +467,7 @@ func dbPut(ctx *cli.Context) error {
|
||||||
data []byte
|
data []byte
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
key, err = common.ParseHexOrString(ctx.Args().Get(0))
|
key, err = common.ParseHexOrString(ctx.Args().Get(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Could not decode the key", "error", err)
|
log.Info("Could not decode the key", "error", err)
|
||||||
|
|
@ -490,30 +504,36 @@ func dbDumpTrie(ctx *cli.Context) error {
|
||||||
max = int64(-1)
|
max = int64(-1)
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
if state, err = hexutil.Decode(ctx.Args().Get(0)); err != nil {
|
if state, err = hexutil.Decode(ctx.Args().Get(0)); err != nil {
|
||||||
log.Info("Could not decode the state root", "error", err)
|
log.Info("Could not decode the state root", "error", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if account, err = hexutil.Decode(ctx.Args().Get(1)); err != nil {
|
if account, err = hexutil.Decode(ctx.Args().Get(1)); err != nil {
|
||||||
log.Info("Could not decode the account hash", "error", err)
|
log.Info("Could not decode the account hash", "error", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if storage, err = hexutil.Decode(ctx.Args().Get(2)); err != nil {
|
if storage, err = hexutil.Decode(ctx.Args().Get(2)); err != nil {
|
||||||
log.Info("Could not decode the storage trie root", "error", err)
|
log.Info("Could not decode the storage trie root", "error", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.NArg() > 3 {
|
if ctx.NArg() > 3 {
|
||||||
if start, err = hexutil.Decode(ctx.Args().Get(3)); err != nil {
|
if start, err = hexutil.Decode(ctx.Args().Get(3)); err != nil {
|
||||||
log.Info("Could not decode the seek position", "error", err)
|
log.Info("Could not decode the seek position", "error", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.NArg() > 4 {
|
if ctx.NArg() > 4 {
|
||||||
if max, err = strconv.ParseInt(ctx.Args().Get(4), 10, 64); err != nil {
|
if max, err = strconv.ParseInt(ctx.Args().Get(4), 10, 64); err != nil {
|
||||||
log.Info("Could not decode the max count", "error", err)
|
log.Info("Could not decode the max count", "error", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
id := trie.StorageTrieID(common.BytesToHash(state), common.BytesToHash(account), common.BytesToHash(storage))
|
id := trie.StorageTrieID(common.BytesToHash(state), common.BytesToHash(account), common.BytesToHash(storage))
|
||||||
theTrie, err := trie.New(id, trie.NewDatabase(db))
|
theTrie, err := trie.New(id, trie.NewDatabase(db))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -536,16 +556,21 @@ func freezerInspect(ctx *cli.Context) error {
|
||||||
if ctx.NArg() < 4 {
|
if ctx.NArg() < 4 {
|
||||||
return fmt.Errorf("required arguments: %v", ctx.Command.ArgsUsage)
|
return fmt.Errorf("required arguments: %v", ctx.Command.ArgsUsage)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
freezer = ctx.Args().Get(0)
|
freezer = ctx.Args().Get(0)
|
||||||
table = ctx.Args().Get(1)
|
table = ctx.Args().Get(1)
|
||||||
)
|
)
|
||||||
|
|
||||||
start, err := strconv.ParseInt(ctx.Args().Get(2), 10, 64)
|
start, err := strconv.ParseInt(ctx.Args().Get(2), 10, 64)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Could not read start-param", "err", err)
|
log.Info("Could not read start-param", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
end, err := strconv.ParseInt(ctx.Args().Get(3), 10, 64)
|
end, err := strconv.ParseInt(ctx.Args().Get(3), 10, 64)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Could not read count param", "err", err)
|
log.Info("Could not read count param", "err", err)
|
||||||
return err
|
return err
|
||||||
|
|
@ -553,6 +578,7 @@ func freezerInspect(ctx *cli.Context) error {
|
||||||
stack, _ := makeConfigNode(ctx)
|
stack, _ := makeConfigNode(ctx)
|
||||||
ancient := stack.ResolveAncient("chaindata", ctx.String(utils.AncientFlag.Name))
|
ancient := stack.ResolveAncient("chaindata", ctx.String(utils.AncientFlag.Name))
|
||||||
stack.Close()
|
stack.Close()
|
||||||
|
|
||||||
return rawdb.InspectFreezerTable(ancient, freezer, table, start, end)
|
return rawdb.InspectFreezerTable(ancient, freezer, table, start, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -694,6 +720,7 @@ func showMetaData(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error accessing ancients: %v", err)
|
fmt.Fprintf(os.Stderr, "Error accessing ancients: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data := rawdb.ReadChainMetadata(db)
|
data := rawdb.ReadChainMetadata(db)
|
||||||
data = append(data, []string{"frozen", fmt.Sprintf("%d items", ancients)})
|
data = append(data, []string{"frozen", fmt.Sprintf("%d items", ancients)})
|
||||||
data = append(data, []string{"snapshotGenerator", snapshot.ParseGeneratorStatus(rawdb.ReadSnapshotGenerator(db))})
|
data = append(data, []string{"snapshotGenerator", snapshot.ParseGeneratorStatus(rawdb.ReadSnapshotGenerator(db))})
|
||||||
|
|
|
||||||
|
|
@ -33,13 +33,17 @@ func TestExport(t *testing.T) {
|
||||||
defer os.Remove(outfile)
|
defer os.Remove(outfile)
|
||||||
geth := runGeth(t, "--datadir", initGeth(t), "export", outfile)
|
geth := runGeth(t, "--datadir", initGeth(t), "export", outfile)
|
||||||
geth.WaitExit()
|
geth.WaitExit()
|
||||||
|
|
||||||
if have, want := geth.ExitStatus(), 0; have != want {
|
if have, want := geth.ExitStatus(), 0; have != want {
|
||||||
t.Errorf("exit error, have %d want %d", have, want)
|
t.Errorf("exit error, have %d want %d", have, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
have, err := os.ReadFile(outfile)
|
have, err := os.ReadFile(outfile)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
want := common.FromHex("0xf9026bf90266a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a08758259b018f7bce3d2be2ddb62f325eaeea0a0c188cf96623eab468a4413e03a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000180837a12008080b875000000000000000000000000000000000000000000000000000000000000000002f0d131f1f97aef08aec6e3291b957d9efe71050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0")
|
want := common.FromHex("0xf9026bf90266a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a08758259b018f7bce3d2be2ddb62f325eaeea0a0c188cf96623eab468a4413e03a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000180837a12008080b875000000000000000000000000000000000000000000000000000000000000000002f0d131f1f97aef08aec6e3291b957d9efe71050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0")
|
||||||
if !bytes.Equal(have, want) {
|
if !bytes.Equal(have, want) {
|
||||||
t.Fatalf("wrong content exported")
|
t.Fatalf("wrong content exported")
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@ func TestCustomBackend(t *testing.T) {
|
||||||
if strconv.IntSize != 64 {
|
if strconv.IntSize != 64 {
|
||||||
t.Skip("Custom backends are only available on 64-bit platform")
|
t.Skip("Custom backends are only available on 64-bit platform")
|
||||||
}
|
}
|
||||||
|
|
||||||
genesis := `{
|
genesis := `{
|
||||||
"alloc" : {},
|
"alloc" : {},
|
||||||
"coinbase" : "0x0000000000000000000000000000000000000000",
|
"coinbase" : "0x0000000000000000000000000000000000000000",
|
||||||
|
|
@ -113,13 +114,16 @@ func TestCustomBackend(t *testing.T) {
|
||||||
"timestamp" : "0x00",
|
"timestamp" : "0x00",
|
||||||
"config" : {}
|
"config" : {}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
type backendTest struct {
|
type backendTest struct {
|
||||||
initArgs []string
|
initArgs []string
|
||||||
initExpect string
|
initExpect string
|
||||||
execArgs []string
|
execArgs []string
|
||||||
execExpect string
|
execExpect string
|
||||||
}
|
}
|
||||||
|
|
||||||
testfunc := func(t *testing.T, tt backendTest) error {
|
testfunc := func(t *testing.T, tt backendTest) error {
|
||||||
|
t.Helper()
|
||||||
// Create a temporary data directory to use and inspect later
|
// Create a temporary data directory to use and inspect later
|
||||||
datadir := t.TempDir()
|
datadir := t.TempDir()
|
||||||
|
|
||||||
|
|
@ -143,8 +147,10 @@ func TestCustomBackend(t *testing.T) {
|
||||||
geth.ExpectRegexp(tt.execExpect)
|
geth.ExpectRegexp(tt.execExpect)
|
||||||
geth.ExpectExit()
|
geth.ExpectExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tt := range []backendTest{
|
for i, tt := range []backendTest{
|
||||||
{ // When not specified, it should default to leveldb
|
{ // When not specified, it should default to leveldb
|
||||||
execArgs: []string{"--db.engine", "leveldb"},
|
execArgs: []string{"--db.engine", "leveldb"},
|
||||||
|
|
|
||||||
|
|
@ -473,6 +473,7 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend, isCon
|
||||||
// unlockAccounts unlocks any account specifically requested.
|
// unlockAccounts unlocks any account specifically requested.
|
||||||
func unlockAccounts(ctx *cli.Context, stack *node.Node) {
|
func unlockAccounts(ctx *cli.Context, stack *node.Node) {
|
||||||
var unlocks []string
|
var unlocks []string
|
||||||
|
|
||||||
inputs := strings.Split(ctx.String(utils.UnlockedAccountFlag.Name), ",")
|
inputs := strings.Split(ctx.String(utils.UnlockedAccountFlag.Name), ",")
|
||||||
for _, input := range inputs {
|
for _, input := range inputs {
|
||||||
if trimmed := strings.TrimSpace(input); trimmed != "" {
|
if trimmed := strings.TrimSpace(input); trimmed != "" {
|
||||||
|
|
@ -488,11 +489,14 @@ func unlockAccounts(ctx *cli.Context, stack *node.Node) {
|
||||||
if !stack.Config().InsecureUnlockAllowed && stack.Config().ExtRPCEnabled() {
|
if !stack.Config().InsecureUnlockAllowed && stack.Config().ExtRPCEnabled() {
|
||||||
utils.Fatalf("Account unlock with HTTP access is forbidden!")
|
utils.Fatalf("Account unlock with HTTP access is forbidden!")
|
||||||
}
|
}
|
||||||
|
|
||||||
backends := stack.AccountManager().Backends(keystore.KeyStoreType)
|
backends := stack.AccountManager().Backends(keystore.KeyStoreType)
|
||||||
|
|
||||||
if len(backends) == 0 {
|
if len(backends) == 0 {
|
||||||
log.Warn("Failed to unlock accounts, keystore is not available")
|
log.Warn("Failed to unlock accounts, keystore is not available")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ks := backends[0].(*keystore.KeyStore)
|
ks := backends[0].(*keystore.KeyStore)
|
||||||
passwords := utils.MakePasswordList(ctx)
|
passwords := utils.MakePasswordList(ctx)
|
||||||
for i, account := range unlocks {
|
for i, account := range unlocks {
|
||||||
|
|
|
||||||
|
|
@ -131,9 +131,11 @@ func printVersion(ctx *cli.Context) error {
|
||||||
|
|
||||||
fmt.Println(strings.Title(clientIdentifier))
|
fmt.Println(strings.Title(clientIdentifier))
|
||||||
fmt.Println("Version:", params.VersionWithMeta)
|
fmt.Println("Version:", params.VersionWithMeta)
|
||||||
|
|
||||||
if git.Commit != "" {
|
if git.Commit != "" {
|
||||||
fmt.Println("Git Commit:", git.Commit)
|
fmt.Println("Git Commit:", git.Commit)
|
||||||
}
|
}
|
||||||
|
|
||||||
if git.Date != "" {
|
if git.Date != "" {
|
||||||
fmt.Println("Git Commit Date:", git.Date)
|
fmt.Println("Git Commit Date:", git.Date)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -207,6 +207,7 @@ func verifyState(ctx *cli.Context) error {
|
||||||
log.Error("Failed to load head block")
|
log.Error("Failed to load head block")
|
||||||
return errors.New("no head block")
|
return errors.New("no head block")
|
||||||
}
|
}
|
||||||
|
|
||||||
snapconfig := snapshot.Config{
|
snapconfig := snapshot.Config{
|
||||||
CacheSize: 256,
|
CacheSize: 256,
|
||||||
Recovery: false,
|
Recovery: false,
|
||||||
|
|
@ -235,6 +236,7 @@ func verifyState(ctx *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Info("Verified the state", "root", root)
|
log.Info("Verified the state", "root", root)
|
||||||
|
|
||||||
return snapshot.CheckDanglingStorage(chaindb)
|
return snapshot.CheckDanglingStorage(chaindb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -300,6 +302,7 @@ func traverseState(ctx *cli.Context) error {
|
||||||
log.Error("Invalid account encountered during traversal", "err", err)
|
log.Error("Invalid account encountered during traversal", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if acc.Root != types.EmptyRootHash {
|
if acc.Root != types.EmptyRootHash {
|
||||||
id := trie.StorageTrieID(root, common.BytesToHash(accIter.Key), acc.Root)
|
id := trie.StorageTrieID(root, common.BytesToHash(accIter.Key), acc.Root)
|
||||||
storageTrie, err := trie.NewStateTrie(id, triedb)
|
storageTrie, err := trie.NewStateTrie(id, triedb)
|
||||||
|
|
@ -316,6 +319,7 @@ func traverseState(ctx *cli.Context) error {
|
||||||
return storageIter.Err
|
return storageIter.Err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
|
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||||
if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) {
|
if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) {
|
||||||
log.Error("Code is missing", "hash", common.BytesToHash(acc.CodeHash))
|
log.Error("Code is missing", "hash", common.BytesToHash(acc.CodeHash))
|
||||||
|
|
@ -398,9 +402,11 @@ func traverseRawState(ctx *cli.Context) error {
|
||||||
log.Error("Missing trie node(account)", "hash", node)
|
log.Error("Missing trie node(account)", "hash", node)
|
||||||
return errors.New("missing account")
|
return errors.New("missing account")
|
||||||
}
|
}
|
||||||
|
|
||||||
hasher.Reset()
|
hasher.Reset()
|
||||||
hasher.Write(blob)
|
hasher.Write(blob)
|
||||||
hasher.Read(got)
|
hasher.Read(got)
|
||||||
|
|
||||||
if !bytes.Equal(got, node.Bytes()) {
|
if !bytes.Equal(got, node.Bytes()) {
|
||||||
log.Error("Invalid trie node(account)", "hash", node.Hex(), "value", blob)
|
log.Error("Invalid trie node(account)", "hash", node.Hex(), "value", blob)
|
||||||
return errors.New("invalid account node")
|
return errors.New("invalid account node")
|
||||||
|
|
@ -415,6 +421,7 @@ func traverseRawState(ctx *cli.Context) error {
|
||||||
log.Error("Invalid account encountered during traversal", "err", err)
|
log.Error("Invalid account encountered during traversal", "err", err)
|
||||||
return errors.New("invalid account")
|
return errors.New("invalid account")
|
||||||
}
|
}
|
||||||
|
|
||||||
if acc.Root != types.EmptyRootHash {
|
if acc.Root != types.EmptyRootHash {
|
||||||
id := trie.StorageTrieID(root, common.BytesToHash(accIter.LeafKey()), acc.Root)
|
id := trie.StorageTrieID(root, common.BytesToHash(accIter.LeafKey()), acc.Root)
|
||||||
storageTrie, err := trie.NewStateTrie(id, triedb)
|
storageTrie, err := trie.NewStateTrie(id, triedb)
|
||||||
|
|
@ -435,9 +442,11 @@ func traverseRawState(ctx *cli.Context) error {
|
||||||
log.Error("Missing trie node(storage)", "hash", node)
|
log.Error("Missing trie node(storage)", "hash", node)
|
||||||
return errors.New("missing storage")
|
return errors.New("missing storage")
|
||||||
}
|
}
|
||||||
|
|
||||||
hasher.Reset()
|
hasher.Reset()
|
||||||
hasher.Write(blob)
|
hasher.Write(blob)
|
||||||
hasher.Read(got)
|
hasher.Read(got)
|
||||||
|
|
||||||
if !bytes.Equal(got, node.Bytes()) {
|
if !bytes.Equal(got, node.Bytes()) {
|
||||||
log.Error("Invalid trie node(storage)", "hash", node.Hex(), "value", blob)
|
log.Error("Invalid trie node(storage)", "hash", node.Hex(), "value", blob)
|
||||||
return errors.New("invalid storage node")
|
return errors.New("invalid storage node")
|
||||||
|
|
@ -453,6 +462,7 @@ func traverseRawState(ctx *cli.Context) error {
|
||||||
return storageIter.Error()
|
return storageIter.Error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
|
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||||
if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) {
|
if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) {
|
||||||
log.Error("Code is missing", "account", common.BytesToHash(accIter.LeafKey()))
|
log.Error("Code is missing", "account", common.BytesToHash(accIter.LeafKey()))
|
||||||
|
|
@ -490,6 +500,7 @@ func dumpState(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
snapConfig := snapshot.Config{
|
snapConfig := snapshot.Config{
|
||||||
CacheSize: 256,
|
CacheSize: 256,
|
||||||
Recovery: false,
|
Recovery: false,
|
||||||
|
|
@ -528,6 +539,7 @@ func dumpState(ctx *cli.Context) error {
|
||||||
CodeHash: account.CodeHash,
|
CodeHash: account.CodeHash,
|
||||||
SecureKey: accIt.Hash().Bytes(),
|
SecureKey: accIt.Hash().Bytes(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if !conf.SkipCode && !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) {
|
if !conf.SkipCode && !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||||
da.Code = rawdb.ReadCode(db, common.BytesToHash(account.CodeHash))
|
da.Code = rawdb.ReadCode(db, common.BytesToHash(account.CodeHash))
|
||||||
}
|
}
|
||||||
|
|
@ -564,10 +576,12 @@ func checkAccount(ctx *cli.Context) error {
|
||||||
if ctx.NArg() != 1 {
|
if ctx.NArg() != 1 {
|
||||||
return errors.New("need <address|hash> arg")
|
return errors.New("need <address|hash> arg")
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
hash common.Hash
|
hash common.Hash
|
||||||
addr common.Address
|
addr common.Address
|
||||||
)
|
)
|
||||||
|
|
||||||
switch arg := ctx.Args().First(); len(arg) {
|
switch arg := ctx.Args().First(); len(arg) {
|
||||||
case 40, 42:
|
case 40, 42:
|
||||||
addr = common.HexToAddress(arg)
|
addr = common.HexToAddress(arg)
|
||||||
|
|
@ -577,15 +591,22 @@ func checkAccount(ctx *cli.Context) error {
|
||||||
default:
|
default:
|
||||||
return errors.New("malformed address or hash")
|
return errors.New("malformed address or hash")
|
||||||
}
|
}
|
||||||
|
|
||||||
stack, _ := makeConfigNode(ctx)
|
stack, _ := makeConfigNode(ctx)
|
||||||
defer stack.Close()
|
defer stack.Close()
|
||||||
|
|
||||||
chaindb := utils.MakeChainDatabase(ctx, stack, true)
|
chaindb := utils.MakeChainDatabase(ctx, stack, true)
|
||||||
defer chaindb.Close()
|
defer chaindb.Close()
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
log.Info("Checking difflayer journal", "address", addr, "hash", hash)
|
log.Info("Checking difflayer journal", "address", addr, "hash", hash)
|
||||||
|
|
||||||
if err := snapshot.CheckJournalAccount(chaindb, hash); err != nil {
|
if err := snapshot.CheckJournalAccount(chaindb, hash); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Checked the snapshot journalled storage", "time", common.PrettyDuration(time.Since(start)))
|
log.Info("Checked the snapshot journalled storage", "time", common.PrettyDuration(time.Since(start)))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,9 +77,11 @@ func checkChildren(root verkle.VerkleNode, resolver verkle.NodeResolverFn) error
|
||||||
childC := child.ComputeCommitment().Bytes()
|
childC := child.ComputeCommitment().Bytes()
|
||||||
|
|
||||||
childS, err := resolver(childC[:])
|
childS, err := resolver(childC[:])
|
||||||
|
|
||||||
if bytes.Equal(childC[:], zero[:]) {
|
if bytes.Equal(childC[:], zero[:]) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not find child %x in db: %w", childC, err)
|
return fmt.Errorf("could not find child %x in db: %w", childC, err)
|
||||||
}
|
}
|
||||||
|
|
@ -88,18 +90,19 @@ func checkChildren(root verkle.VerkleNode, resolver verkle.NodeResolverFn) error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("decode error child %x in db: %w", child.ComputeCommitment().Bytes(), err)
|
return fmt.Errorf("decode error child %x in db: %w", child.ComputeCommitment().Bytes(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := checkChildren(childN, resolver); err != nil {
|
if err := checkChildren(childN, resolver); err != nil {
|
||||||
return fmt.Errorf("%x%w", i, err) // write the path to the erroring node
|
return fmt.Errorf("%x%w", i, err) // write the path to the erroring node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *verkle.LeafNode:
|
case *verkle.LeafNode:
|
||||||
// sanity check: ensure at least one value is non-zero
|
// sanity check: ensure at least one value is non-zero
|
||||||
|
|
||||||
for i := 0; i < verkle.NodeWidth; i++ {
|
for i := 0; i < verkle.NodeWidth; i++ {
|
||||||
if len(node.Value(i)) != 0 {
|
if len(node.Value(i)) != 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("Both balance and nonce are 0")
|
return fmt.Errorf("Both balance and nonce are 0")
|
||||||
case verkle.Empty:
|
case verkle.Empty:
|
||||||
// nothing to do
|
// nothing to do
|
||||||
|
|
@ -116,24 +119,29 @@ func verifyVerkle(ctx *cli.Context) error {
|
||||||
|
|
||||||
chaindb := utils.MakeChainDatabase(ctx, stack, true)
|
chaindb := utils.MakeChainDatabase(ctx, stack, true)
|
||||||
headBlock := rawdb.ReadHeadBlock(chaindb)
|
headBlock := rawdb.ReadHeadBlock(chaindb)
|
||||||
|
|
||||||
if headBlock == nil {
|
if headBlock == nil {
|
||||||
log.Error("Failed to load head block")
|
log.Error("Failed to load head block")
|
||||||
return errors.New("no head block")
|
return errors.New("no head block")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.NArg() > 1 {
|
if ctx.NArg() > 1 {
|
||||||
log.Error("Too many arguments given")
|
log.Error("Too many arguments given")
|
||||||
return errors.New("too many arguments")
|
return errors.New("too many arguments")
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
rootC common.Hash
|
rootC common.Hash
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
if ctx.NArg() == 1 {
|
if ctx.NArg() == 1 {
|
||||||
rootC, err = parseRoot(ctx.Args().First())
|
rootC, err = parseRoot(ctx.Args().First())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to resolve state root", "error", err)
|
log.Error("Failed to resolve state root", "error", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Rebuilding the tree", "root", rootC)
|
log.Info("Rebuilding the tree", "root", rootC)
|
||||||
} else {
|
} else {
|
||||||
rootC = headBlock.Root()
|
rootC = headBlock.Root()
|
||||||
|
|
@ -144,7 +152,9 @@ func verifyVerkle(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
root, err := verkle.ParseNode(serializedRoot, 0, rootC[:])
|
root, err := verkle.ParseNode(serializedRoot, 0, rootC[:])
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -155,6 +165,7 @@ func verifyVerkle(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Tree was rebuilt from the database")
|
log.Info("Tree was rebuilt from the database")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,27 +174,34 @@ func expandVerkle(ctx *cli.Context) error {
|
||||||
defer stack.Close()
|
defer stack.Close()
|
||||||
|
|
||||||
chaindb := utils.MakeChainDatabase(ctx, stack, true)
|
chaindb := utils.MakeChainDatabase(ctx, stack, true)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
rootC common.Hash
|
rootC common.Hash
|
||||||
keylist [][]byte
|
keylist [][]byte
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
if ctx.NArg() >= 2 {
|
if ctx.NArg() >= 2 {
|
||||||
rootC, err = parseRoot(ctx.Args().First())
|
rootC, err = parseRoot(ctx.Args().First())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to resolve state root", "error", err)
|
log.Error("Failed to resolve state root", "error", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
keylist = make([][]byte, 0, ctx.Args().Len()-1)
|
keylist = make([][]byte, 0, ctx.Args().Len()-1)
|
||||||
|
|
||||||
args := ctx.Args().Slice()
|
args := ctx.Args().Slice()
|
||||||
for i := range args[1:] {
|
for i := range args[1:] {
|
||||||
key, err := hex.DecodeString(args[i+1])
|
key, err := hex.DecodeString(args[i+1])
|
||||||
log.Info("decoded key", "arg", args[i+1], "key", key)
|
log.Info("decoded key", "arg", args[i+1], "key", key)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error decoding key #%d: %w", i+1, err)
|
return fmt.Errorf("error decoding key #%d: %w", i+1, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
keylist = append(keylist, key)
|
keylist = append(keylist, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Rebuilding the tree", "root", rootC)
|
log.Info("Rebuilding the tree", "root", rootC)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("usage: %s root key1 [key 2...]", ctx.App.Name)
|
return fmt.Errorf("usage: %s root key1 [key 2...]", ctx.App.Name)
|
||||||
|
|
@ -193,7 +211,9 @@ func expandVerkle(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
root, err := verkle.ParseNode(serializedRoot, 0, rootC[:])
|
root, err := verkle.ParseNode(serializedRoot, 0, rootC[:])
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -208,5 +228,6 @@ func expandVerkle(ctx *cli.Context) error {
|
||||||
} else {
|
} else {
|
||||||
log.Info("Tree was dumped to file", "file", "dump.dot")
|
log.Info("Tree was dumped to file", "file", "dump.dot")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,7 @@ func monitorFreeDiskSpace(sigc chan os.Signal, path string, freeDiskSpaceCritica
|
||||||
} else if freeSpace < 2*freeDiskSpaceCritical {
|
} else if freeSpace < 2*freeDiskSpaceCritical {
|
||||||
log.Warn("Disk space is running low. Geth will shutdown if disk space runs below critical level.", "available", common.StorageSize(freeSpace), "critical_level", common.StorageSize(freeDiskSpaceCritical), "path", path)
|
log.Warn("Disk space is running low. Geth will shutdown if disk space runs below critical level.", "available", common.StorageSize(freeSpace), "critical_level", common.StorageSize(freeDiskSpaceCritical), "path", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(30 * time.Second)
|
time.Sleep(30 * time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1037,6 +1037,7 @@ func MakeDataDir(ctx *cli.Context) string {
|
||||||
if ctx.Bool(GoerliFlag.Name) {
|
if ctx.Bool(GoerliFlag.Name) {
|
||||||
return filepath.Join(path, "goerli")
|
return filepath.Join(path, "goerli")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Bool(SepoliaFlag.Name) {
|
if ctx.Bool(SepoliaFlag.Name) {
|
||||||
return filepath.Join(path, "sepolia")
|
return filepath.Join(path, "sepolia")
|
||||||
}
|
}
|
||||||
|
|
@ -1140,6 +1141,7 @@ func setListenAddress(ctx *cli.Context, cfg *p2p.Config) {
|
||||||
if ctx.IsSet(ListenPortFlag.Name) {
|
if ctx.IsSet(ListenPortFlag.Name) {
|
||||||
cfg.ListenAddr = fmt.Sprintf(":%d", ctx.Int(ListenPortFlag.Name))
|
cfg.ListenAddr = fmt.Sprintf(":%d", ctx.Int(ListenPortFlag.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(DiscoveryPortFlag.Name) {
|
if ctx.IsSet(DiscoveryPortFlag.Name) {
|
||||||
cfg.DiscAddr = fmt.Sprintf(":%d", ctx.Int(DiscoveryPortFlag.Name))
|
cfg.DiscAddr = fmt.Sprintf(":%d", ctx.Int(DiscoveryPortFlag.Name))
|
||||||
}
|
}
|
||||||
|
|
@ -1209,6 +1211,7 @@ func setHTTP(ctx *cli.Context, cfg *node.Config) {
|
||||||
if ctx.IsSet(HTTPPathPrefixFlag.Name) {
|
if ctx.IsSet(HTTPPathPrefixFlag.Name) {
|
||||||
cfg.HTTPPathPrefix = ctx.String(HTTPPathPrefixFlag.Name)
|
cfg.HTTPPathPrefix = ctx.String(HTTPPathPrefixFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(AllowUnprotectedTxs.Name) {
|
if ctx.IsSet(AllowUnprotectedTxs.Name) {
|
||||||
cfg.AllowUnprotectedTxs = ctx.Bool(AllowUnprotectedTxs.Name)
|
cfg.AllowUnprotectedTxs = ctx.Bool(AllowUnprotectedTxs.Name)
|
||||||
}
|
}
|
||||||
|
|
@ -1220,6 +1223,7 @@ func setGraphQL(ctx *cli.Context, cfg *node.Config) {
|
||||||
if ctx.IsSet(GraphQLCORSDomainFlag.Name) {
|
if ctx.IsSet(GraphQLCORSDomainFlag.Name) {
|
||||||
cfg.GraphQLCors = SplitAndTrim(ctx.String(GraphQLCORSDomainFlag.Name))
|
cfg.GraphQLCors = SplitAndTrim(ctx.String(GraphQLCORSDomainFlag.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(GraphQLVirtualHostsFlag.Name) {
|
if ctx.IsSet(GraphQLVirtualHostsFlag.Name) {
|
||||||
cfg.GraphQLVirtualHosts = SplitAndTrim(ctx.String(GraphQLVirtualHostsFlag.Name))
|
cfg.GraphQLVirtualHosts = SplitAndTrim(ctx.String(GraphQLVirtualHostsFlag.Name))
|
||||||
}
|
}
|
||||||
|
|
@ -1234,6 +1238,7 @@ func setWS(ctx *cli.Context, cfg *node.Config) {
|
||||||
cfg.WSHost = ctx.String(WSListenAddrFlag.Name)
|
cfg.WSHost = ctx.String(WSListenAddrFlag.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(WSPortFlag.Name) {
|
if ctx.IsSet(WSPortFlag.Name) {
|
||||||
cfg.WSPort = ctx.Int(WSPortFlag.Name)
|
cfg.WSPort = ctx.Int(WSPortFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
@ -1268,31 +1273,40 @@ func setLes(ctx *cli.Context, cfg *ethconfig.Config) {
|
||||||
if ctx.IsSet(LightServeFlag.Name) {
|
if ctx.IsSet(LightServeFlag.Name) {
|
||||||
cfg.LightServ = ctx.Int(LightServeFlag.Name)
|
cfg.LightServ = ctx.Int(LightServeFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(LightIngressFlag.Name) {
|
if ctx.IsSet(LightIngressFlag.Name) {
|
||||||
cfg.LightIngress = ctx.Int(LightIngressFlag.Name)
|
cfg.LightIngress = ctx.Int(LightIngressFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(LightEgressFlag.Name) {
|
if ctx.IsSet(LightEgressFlag.Name) {
|
||||||
cfg.LightEgress = ctx.Int(LightEgressFlag.Name)
|
cfg.LightEgress = ctx.Int(LightEgressFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(LightMaxPeersFlag.Name) {
|
if ctx.IsSet(LightMaxPeersFlag.Name) {
|
||||||
cfg.LightPeers = ctx.Int(LightMaxPeersFlag.Name)
|
cfg.LightPeers = ctx.Int(LightMaxPeersFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(UltraLightServersFlag.Name) {
|
if ctx.IsSet(UltraLightServersFlag.Name) {
|
||||||
cfg.UltraLightServers = strings.Split(ctx.String(UltraLightServersFlag.Name), ",")
|
cfg.UltraLightServers = strings.Split(ctx.String(UltraLightServersFlag.Name), ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(UltraLightFractionFlag.Name) {
|
if ctx.IsSet(UltraLightFractionFlag.Name) {
|
||||||
cfg.UltraLightFraction = ctx.Int(UltraLightFractionFlag.Name)
|
cfg.UltraLightFraction = ctx.Int(UltraLightFractionFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.UltraLightFraction <= 0 && cfg.UltraLightFraction > 100 {
|
if cfg.UltraLightFraction <= 0 && cfg.UltraLightFraction > 100 {
|
||||||
log.Error("Ultra light fraction is invalid", "had", cfg.UltraLightFraction, "updated", ethconfig.Defaults.UltraLightFraction)
|
log.Error("Ultra light fraction is invalid", "had", cfg.UltraLightFraction, "updated", ethconfig.Defaults.UltraLightFraction)
|
||||||
cfg.UltraLightFraction = ethconfig.Defaults.UltraLightFraction
|
cfg.UltraLightFraction = ethconfig.Defaults.UltraLightFraction
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(UltraLightOnlyAnnounceFlag.Name) {
|
if ctx.IsSet(UltraLightOnlyAnnounceFlag.Name) {
|
||||||
cfg.UltraLightOnlyAnnounce = ctx.Bool(UltraLightOnlyAnnounceFlag.Name)
|
cfg.UltraLightOnlyAnnounce = ctx.Bool(UltraLightOnlyAnnounceFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(LightNoPruneFlag.Name) {
|
if ctx.IsSet(LightNoPruneFlag.Name) {
|
||||||
cfg.LightNoPrune = ctx.Bool(LightNoPruneFlag.Name)
|
cfg.LightNoPrune = ctx.Bool(LightNoPruneFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(LightNoSyncServeFlag.Name) {
|
if ctx.IsSet(LightNoSyncServeFlag.Name) {
|
||||||
cfg.LightNoSyncServe = ctx.Bool(LightNoSyncServeFlag.Name)
|
cfg.LightNoSyncServe = ctx.Bool(LightNoSyncServeFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
@ -1355,15 +1369,20 @@ func setEtherbase(ctx *cli.Context, cfg *ethconfig.Config) {
|
||||||
if !ctx.IsSet(MinerEtherbaseFlag.Name) {
|
if !ctx.IsSet(MinerEtherbaseFlag.Name) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := ctx.String(MinerEtherbaseFlag.Name)
|
addr := ctx.String(MinerEtherbaseFlag.Name)
|
||||||
|
|
||||||
if strings.HasPrefix(addr, "0x") || strings.HasPrefix(addr, "0X") {
|
if strings.HasPrefix(addr, "0x") || strings.HasPrefix(addr, "0X") {
|
||||||
addr = addr[2:]
|
addr = addr[2:]
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := hex.DecodeString(addr)
|
b, err := hex.DecodeString(addr)
|
||||||
|
|
||||||
if err != nil || len(b) != common.AddressLength {
|
if err != nil || len(b) != common.AddressLength {
|
||||||
Fatalf("-%s: invalid etherbase address %q", MinerEtherbaseFlag.Name, addr)
|
Fatalf("-%s: invalid etherbase address %q", MinerEtherbaseFlag.Name, addr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.Miner.Etherbase = common.BytesToAddress(b)
|
cfg.Miner.Etherbase = common.BytesToAddress(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1373,6 +1392,7 @@ func MakePasswordList(ctx *cli.Context) []string {
|
||||||
if path == "" {
|
if path == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
text, err := os.ReadFile(path)
|
text, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("Failed to read password file: %v", err)
|
Fatalf("Failed to read password file: %v", err)
|
||||||
|
|
@ -1426,6 +1446,7 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
|
||||||
if ctx.IsSet(MaxPendingPeersFlag.Name) {
|
if ctx.IsSet(MaxPendingPeersFlag.Name) {
|
||||||
cfg.MaxPendingPeers = ctx.Int(MaxPendingPeersFlag.Name)
|
cfg.MaxPendingPeers = ctx.Int(MaxPendingPeersFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(NoDiscoverFlag.Name) || lightClient {
|
if ctx.IsSet(NoDiscoverFlag.Name) || lightClient {
|
||||||
cfg.NoDiscovery = true
|
cfg.NoDiscovery = true
|
||||||
}
|
}
|
||||||
|
|
@ -1434,6 +1455,7 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
|
||||||
// unless it is explicitly disabled with --nodiscover note that explicitly specifying
|
// unless it is explicitly disabled with --nodiscover note that explicitly specifying
|
||||||
// --v5disc overrides --nodiscover, in which case the later only disables v4 discovery
|
// --v5disc overrides --nodiscover, in which case the later only disables v4 discovery
|
||||||
forceV5Discovery := (lightClient || lightServer) && !ctx.Bool(NoDiscoverFlag.Name)
|
forceV5Discovery := (lightClient || lightServer) && !ctx.Bool(NoDiscoverFlag.Name)
|
||||||
|
|
||||||
if ctx.IsSet(DiscoveryV5Flag.Name) {
|
if ctx.IsSet(DiscoveryV5Flag.Name) {
|
||||||
cfg.DiscoveryV5 = ctx.Bool(DiscoveryV5Flag.Name)
|
cfg.DiscoveryV5 = ctx.Bool(DiscoveryV5Flag.Name)
|
||||||
} else if forceV5Discovery {
|
} else if forceV5Discovery {
|
||||||
|
|
@ -1484,26 +1506,33 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
|
||||||
if ctx.IsSet(KeyStoreDirFlag.Name) {
|
if ctx.IsSet(KeyStoreDirFlag.Name) {
|
||||||
cfg.KeyStoreDir = ctx.String(KeyStoreDirFlag.Name)
|
cfg.KeyStoreDir = ctx.String(KeyStoreDirFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(DeveloperFlag.Name) {
|
if ctx.IsSet(DeveloperFlag.Name) {
|
||||||
cfg.UseLightweightKDF = true
|
cfg.UseLightweightKDF = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(LightKDFFlag.Name) {
|
if ctx.IsSet(LightKDFFlag.Name) {
|
||||||
cfg.UseLightweightKDF = ctx.Bool(LightKDFFlag.Name)
|
cfg.UseLightweightKDF = ctx.Bool(LightKDFFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(NoUSBFlag.Name) || cfg.NoUSB {
|
if ctx.IsSet(NoUSBFlag.Name) || cfg.NoUSB {
|
||||||
log.Warn("Option nousb is deprecated and USB is deactivated by default. Use --usb to enable")
|
log.Warn("Option nousb is deprecated and USB is deactivated by default. Use --usb to enable")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(USBFlag.Name) {
|
if ctx.IsSet(USBFlag.Name) {
|
||||||
cfg.USB = ctx.Bool(USBFlag.Name)
|
cfg.USB = ctx.Bool(USBFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(InsecureUnlockAllowedFlag.Name) {
|
if ctx.IsSet(InsecureUnlockAllowedFlag.Name) {
|
||||||
cfg.InsecureUnlockAllowed = ctx.Bool(InsecureUnlockAllowedFlag.Name)
|
cfg.InsecureUnlockAllowed = ctx.Bool(InsecureUnlockAllowedFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(DBEngineFlag.Name) {
|
if ctx.IsSet(DBEngineFlag.Name) {
|
||||||
dbEngine := ctx.String(DBEngineFlag.Name)
|
dbEngine := ctx.String(DBEngineFlag.Name)
|
||||||
if dbEngine != "leveldb" && dbEngine != "pebble" {
|
if dbEngine != "leveldb" && dbEngine != "pebble" {
|
||||||
Fatalf("Invalid choice for db.engine '%s', allowed 'leveldb' or 'pebble'", dbEngine)
|
Fatalf("Invalid choice for db.engine '%s', allowed 'leveldb' or 'pebble'", dbEngine)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info(fmt.Sprintf("Using %s as db engine", dbEngine))
|
log.Info(fmt.Sprintf("Using %s as db engine", dbEngine))
|
||||||
cfg.DBEngine = dbEngine
|
cfg.DBEngine = dbEngine
|
||||||
}
|
}
|
||||||
|
|
@ -1517,10 +1546,12 @@ func setSmartCard(ctx *cli.Context, cfg *node.Config) {
|
||||||
}
|
}
|
||||||
// Sanity check that the smartcard path is valid
|
// Sanity check that the smartcard path is valid
|
||||||
fi, err := os.Stat(path)
|
fi, err := os.Stat(path)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Smartcard socket not found, disabling", "err", err)
|
log.Info("Smartcard socket not found, disabling", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if fi.Mode()&os.ModeType != os.ModeSocket {
|
if fi.Mode()&os.ModeType != os.ModeSocket {
|
||||||
log.Error("Invalid smartcard daemon path", "path", path, "type", fi.Mode().String())
|
log.Error("Invalid smartcard daemon path", "path", path, "type", fi.Mode().String())
|
||||||
return
|
return
|
||||||
|
|
@ -1548,15 +1579,19 @@ func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) {
|
||||||
if light {
|
if light {
|
||||||
*cfg = ethconfig.LightClientGPO
|
*cfg = ethconfig.LightClientGPO
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(GpoBlocksFlag.Name) {
|
if ctx.IsSet(GpoBlocksFlag.Name) {
|
||||||
cfg.Blocks = ctx.Int(GpoBlocksFlag.Name)
|
cfg.Blocks = ctx.Int(GpoBlocksFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(GpoPercentileFlag.Name) {
|
if ctx.IsSet(GpoPercentileFlag.Name) {
|
||||||
cfg.Percentile = ctx.Int(GpoPercentileFlag.Name)
|
cfg.Percentile = ctx.Int(GpoPercentileFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(GpoMaxGasPriceFlag.Name) {
|
if ctx.IsSet(GpoMaxGasPriceFlag.Name) {
|
||||||
cfg.MaxPrice = big.NewInt(ctx.Int64(GpoMaxGasPriceFlag.Name))
|
cfg.MaxPrice = big.NewInt(ctx.Int64(GpoMaxGasPriceFlag.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(GpoIgnoreGasPriceFlag.Name) {
|
if ctx.IsSet(GpoIgnoreGasPriceFlag.Name) {
|
||||||
cfg.IgnorePrice = big.NewInt(ctx.Int64(GpoIgnoreGasPriceFlag.Name))
|
cfg.IgnorePrice = big.NewInt(ctx.Int64(GpoIgnoreGasPriceFlag.Name))
|
||||||
}
|
}
|
||||||
|
|
@ -1573,33 +1608,43 @@ func setTxPool(ctx *cli.Context, cfg *txpool.Config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(TxPoolNoLocalsFlag.Name) {
|
if ctx.IsSet(TxPoolNoLocalsFlag.Name) {
|
||||||
cfg.NoLocals = ctx.Bool(TxPoolNoLocalsFlag.Name)
|
cfg.NoLocals = ctx.Bool(TxPoolNoLocalsFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(TxPoolJournalFlag.Name) {
|
if ctx.IsSet(TxPoolJournalFlag.Name) {
|
||||||
cfg.Journal = ctx.String(TxPoolJournalFlag.Name)
|
cfg.Journal = ctx.String(TxPoolJournalFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(TxPoolRejournalFlag.Name) {
|
if ctx.IsSet(TxPoolRejournalFlag.Name) {
|
||||||
cfg.Rejournal = ctx.Duration(TxPoolRejournalFlag.Name)
|
cfg.Rejournal = ctx.Duration(TxPoolRejournalFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(TxPoolPriceLimitFlag.Name) {
|
if ctx.IsSet(TxPoolPriceLimitFlag.Name) {
|
||||||
cfg.PriceLimit = ctx.Uint64(TxPoolPriceLimitFlag.Name)
|
cfg.PriceLimit = ctx.Uint64(TxPoolPriceLimitFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(TxPoolPriceBumpFlag.Name) {
|
if ctx.IsSet(TxPoolPriceBumpFlag.Name) {
|
||||||
cfg.PriceBump = ctx.Uint64(TxPoolPriceBumpFlag.Name)
|
cfg.PriceBump = ctx.Uint64(TxPoolPriceBumpFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(TxPoolAccountSlotsFlag.Name) {
|
if ctx.IsSet(TxPoolAccountSlotsFlag.Name) {
|
||||||
cfg.AccountSlots = ctx.Uint64(TxPoolAccountSlotsFlag.Name)
|
cfg.AccountSlots = ctx.Uint64(TxPoolAccountSlotsFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(TxPoolGlobalSlotsFlag.Name) {
|
if ctx.IsSet(TxPoolGlobalSlotsFlag.Name) {
|
||||||
cfg.GlobalSlots = ctx.Uint64(TxPoolGlobalSlotsFlag.Name)
|
cfg.GlobalSlots = ctx.Uint64(TxPoolGlobalSlotsFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(TxPoolAccountQueueFlag.Name) {
|
if ctx.IsSet(TxPoolAccountQueueFlag.Name) {
|
||||||
cfg.AccountQueue = ctx.Uint64(TxPoolAccountQueueFlag.Name)
|
cfg.AccountQueue = ctx.Uint64(TxPoolAccountQueueFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(TxPoolGlobalQueueFlag.Name) {
|
if ctx.IsSet(TxPoolGlobalQueueFlag.Name) {
|
||||||
cfg.GlobalQueue = ctx.Uint64(TxPoolGlobalQueueFlag.Name)
|
cfg.GlobalQueue = ctx.Uint64(TxPoolGlobalQueueFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(TxPoolLifetimeFlag.Name) {
|
if ctx.IsSet(TxPoolLifetimeFlag.Name) {
|
||||||
cfg.Lifetime = ctx.Duration(TxPoolLifetimeFlag.Name)
|
cfg.Lifetime = ctx.Duration(TxPoolLifetimeFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
@ -1609,24 +1654,31 @@ func setEthash(ctx *cli.Context, cfg *ethconfig.Config) {
|
||||||
if ctx.IsSet(EthashCacheDirFlag.Name) {
|
if ctx.IsSet(EthashCacheDirFlag.Name) {
|
||||||
cfg.Ethash.CacheDir = ctx.String(EthashCacheDirFlag.Name)
|
cfg.Ethash.CacheDir = ctx.String(EthashCacheDirFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(EthashDatasetDirFlag.Name) {
|
if ctx.IsSet(EthashDatasetDirFlag.Name) {
|
||||||
cfg.Ethash.DatasetDir = ctx.String(EthashDatasetDirFlag.Name)
|
cfg.Ethash.DatasetDir = ctx.String(EthashDatasetDirFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(EthashCachesInMemoryFlag.Name) {
|
if ctx.IsSet(EthashCachesInMemoryFlag.Name) {
|
||||||
cfg.Ethash.CachesInMem = ctx.Int(EthashCachesInMemoryFlag.Name)
|
cfg.Ethash.CachesInMem = ctx.Int(EthashCachesInMemoryFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(EthashCachesOnDiskFlag.Name) {
|
if ctx.IsSet(EthashCachesOnDiskFlag.Name) {
|
||||||
cfg.Ethash.CachesOnDisk = ctx.Int(EthashCachesOnDiskFlag.Name)
|
cfg.Ethash.CachesOnDisk = ctx.Int(EthashCachesOnDiskFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(EthashCachesLockMmapFlag.Name) {
|
if ctx.IsSet(EthashCachesLockMmapFlag.Name) {
|
||||||
cfg.Ethash.CachesLockMmap = ctx.Bool(EthashCachesLockMmapFlag.Name)
|
cfg.Ethash.CachesLockMmap = ctx.Bool(EthashCachesLockMmapFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(EthashDatasetsInMemoryFlag.Name) {
|
if ctx.IsSet(EthashDatasetsInMemoryFlag.Name) {
|
||||||
cfg.Ethash.DatasetsInMem = ctx.Int(EthashDatasetsInMemoryFlag.Name)
|
cfg.Ethash.DatasetsInMem = ctx.Int(EthashDatasetsInMemoryFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(EthashDatasetsOnDiskFlag.Name) {
|
if ctx.IsSet(EthashDatasetsOnDiskFlag.Name) {
|
||||||
cfg.Ethash.DatasetsOnDisk = ctx.Int(EthashDatasetsOnDiskFlag.Name)
|
cfg.Ethash.DatasetsOnDisk = ctx.Int(EthashDatasetsOnDiskFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(EthashDatasetsLockMmapFlag.Name) {
|
if ctx.IsSet(EthashDatasetsLockMmapFlag.Name) {
|
||||||
cfg.Ethash.DatasetsLockMmap = ctx.Bool(EthashDatasetsLockMmapFlag.Name)
|
cfg.Ethash.DatasetsLockMmap = ctx.Bool(EthashDatasetsLockMmapFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
@ -1636,22 +1688,29 @@ func setMiner(ctx *cli.Context, cfg *miner.Config) {
|
||||||
if ctx.IsSet(MinerNotifyFlag.Name) {
|
if ctx.IsSet(MinerNotifyFlag.Name) {
|
||||||
cfg.Notify = strings.Split(ctx.String(MinerNotifyFlag.Name), ",")
|
cfg.Notify = strings.Split(ctx.String(MinerNotifyFlag.Name), ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.NotifyFull = ctx.Bool(MinerNotifyFullFlag.Name)
|
cfg.NotifyFull = ctx.Bool(MinerNotifyFullFlag.Name)
|
||||||
|
|
||||||
if ctx.IsSet(MinerExtraDataFlag.Name) {
|
if ctx.IsSet(MinerExtraDataFlag.Name) {
|
||||||
cfg.ExtraData = []byte(ctx.String(MinerExtraDataFlag.Name))
|
cfg.ExtraData = []byte(ctx.String(MinerExtraDataFlag.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(MinerGasLimitFlag.Name) {
|
if ctx.IsSet(MinerGasLimitFlag.Name) {
|
||||||
cfg.GasCeil = ctx.Uint64(MinerGasLimitFlag.Name)
|
cfg.GasCeil = ctx.Uint64(MinerGasLimitFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(MinerGasPriceFlag.Name) {
|
if ctx.IsSet(MinerGasPriceFlag.Name) {
|
||||||
cfg.GasPrice = flags.GlobalBig(ctx, MinerGasPriceFlag.Name)
|
cfg.GasPrice = flags.GlobalBig(ctx, MinerGasPriceFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(MinerRecommitIntervalFlag.Name) {
|
if ctx.IsSet(MinerRecommitIntervalFlag.Name) {
|
||||||
cfg.Recommit = ctx.Duration(MinerRecommitIntervalFlag.Name)
|
cfg.Recommit = ctx.Duration(MinerRecommitIntervalFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(MinerNoVerifyFlag.Name) {
|
if ctx.IsSet(MinerNoVerifyFlag.Name) {
|
||||||
cfg.Noverify = ctx.Bool(MinerNoVerifyFlag.Name)
|
cfg.Noverify = ctx.Bool(MinerNoVerifyFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(MinerNewPayloadTimeout.Name) {
|
if ctx.IsSet(MinerNewPayloadTimeout.Name) {
|
||||||
cfg.NewPayloadTimeout = ctx.Duration(MinerNewPayloadTimeout.Name)
|
cfg.NewPayloadTimeout = ctx.Duration(MinerNewPayloadTimeout.Name)
|
||||||
}
|
}
|
||||||
|
|
@ -1662,12 +1721,15 @@ func setRequiredBlocks(ctx *cli.Context, cfg *ethconfig.Config) {
|
||||||
if requiredBlocks == "" {
|
if requiredBlocks == "" {
|
||||||
if ctx.IsSet(LegacyWhitelistFlag.Name) {
|
if ctx.IsSet(LegacyWhitelistFlag.Name) {
|
||||||
log.Warn("The flag --whitelist is deprecated and will be removed, please use --eth.requiredblocks")
|
log.Warn("The flag --whitelist is deprecated and will be removed, please use --eth.requiredblocks")
|
||||||
|
|
||||||
requiredBlocks = ctx.String(LegacyWhitelistFlag.Name)
|
requiredBlocks = ctx.String(LegacyWhitelistFlag.Name)
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.RequiredBlocks = make(map[uint64]common.Hash)
|
cfg.RequiredBlocks = make(map[uint64]common.Hash)
|
||||||
|
|
||||||
for _, entry := range strings.Split(requiredBlocks, ",") {
|
for _, entry := range strings.Split(requiredBlocks, ",") {
|
||||||
parts := strings.Split(entry, "=")
|
parts := strings.Split(entry, "=")
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
|
|
@ -1681,6 +1743,7 @@ func setRequiredBlocks(ctx *cli.Context, cfg *ethconfig.Config) {
|
||||||
if err = hash.UnmarshalText([]byte(parts[1])); err != nil {
|
if err = hash.UnmarshalText([]byte(parts[1])); err != nil {
|
||||||
Fatalf("Invalid required block hash %s: %v", parts[1], err)
|
Fatalf("Invalid required block hash %s: %v", parts[1], err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.RequiredBlocks[number] = hash
|
cfg.RequiredBlocks[number] = hash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1736,9 +1799,11 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
ctx.Set(TxLookupLimitFlag.Name, "0")
|
ctx.Set(TxLookupLimitFlag.Name, "0")
|
||||||
log.Warn("Disable transaction unindexing for archive node")
|
log.Warn("Disable transaction unindexing for archive node")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(LightServeFlag.Name) && ctx.Uint64(TxLookupLimitFlag.Name) != 0 {
|
if ctx.IsSet(LightServeFlag.Name) && ctx.Uint64(TxLookupLimitFlag.Name) != 0 {
|
||||||
log.Warn("LES server cannot serve old transaction status and cannot connect below les/4 protocol version if transaction lookup index is limited")
|
log.Warn("LES server cannot serve old transaction status and cannot connect below les/4 protocol version if transaction lookup index is limited")
|
||||||
}
|
}
|
||||||
|
|
||||||
setEtherbase(ctx, cfg)
|
setEtherbase(ctx, cfg)
|
||||||
setGPO(ctx, &cfg.GPO, ctx.String(SyncModeFlag.Name) == "light")
|
setGPO(ctx, &cfg.GPO, ctx.String(SyncModeFlag.Name) == "light")
|
||||||
setTxPool(ctx, &cfg.TxPool)
|
setTxPool(ctx, &cfg.TxPool)
|
||||||
|
|
@ -1755,6 +1820,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
mem.Total = 2 * 1024 * 1024 * 1024
|
mem.Total = 2 * 1024 * 1024 * 1024
|
||||||
}
|
}
|
||||||
allowance := int(mem.Total / 1024 / 1024 / 3)
|
allowance := int(mem.Total / 1024 / 1024 / 3)
|
||||||
|
|
||||||
if cache := ctx.Int(CacheFlag.Name); cache > allowance {
|
if cache := ctx.Int(CacheFlag.Name); cache > allowance {
|
||||||
log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance)
|
log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance)
|
||||||
ctx.Set(CacheFlag.Name, strconv.Itoa(allowance))
|
ctx.Set(CacheFlag.Name, strconv.Itoa(allowance))
|
||||||
|
|
@ -1770,13 +1836,17 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
if ctx.IsSet(SyncModeFlag.Name) {
|
if ctx.IsSet(SyncModeFlag.Name) {
|
||||||
cfg.SyncMode = *flags.GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode)
|
cfg.SyncMode = *flags.GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(NetworkIdFlag.Name) {
|
if ctx.IsSet(NetworkIdFlag.Name) {
|
||||||
cfg.NetworkId = ctx.Uint64(NetworkIdFlag.Name)
|
cfg.NetworkId = ctx.Uint64(NetworkIdFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheDatabaseFlag.Name) {
|
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheDatabaseFlag.Name) {
|
||||||
cfg.DatabaseCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheDatabaseFlag.Name) / 100
|
cfg.DatabaseCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheDatabaseFlag.Name) / 100
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.DatabaseHandles = MakeDatabaseHandles(ctx.Int(FDLimitFlag.Name))
|
cfg.DatabaseHandles = MakeDatabaseHandles(ctx.Int(FDLimitFlag.Name))
|
||||||
|
|
||||||
if ctx.IsSet(AncientFlag.Name) {
|
if ctx.IsSet(AncientFlag.Name) {
|
||||||
cfg.DatabaseFreezer = ctx.String(AncientFlag.Name)
|
cfg.DatabaseFreezer = ctx.String(AncientFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
@ -1784,39 +1854,50 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
if gcmode := ctx.String(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
|
if gcmode := ctx.String(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
|
||||||
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
|
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(GCModeFlag.Name) {
|
if ctx.IsSet(GCModeFlag.Name) {
|
||||||
cfg.NoPruning = ctx.String(GCModeFlag.Name) == "archive"
|
cfg.NoPruning = ctx.String(GCModeFlag.Name) == "archive"
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(CacheNoPrefetchFlag.Name) {
|
if ctx.IsSet(CacheNoPrefetchFlag.Name) {
|
||||||
cfg.NoPrefetch = ctx.Bool(CacheNoPrefetchFlag.Name)
|
cfg.NoPrefetch = ctx.Bool(CacheNoPrefetchFlag.Name)
|
||||||
}
|
}
|
||||||
// Read the value from the flag no matter if it's set or not.
|
// Read the value from the flag no matter if it's set or not.
|
||||||
cfg.Preimages = ctx.Bool(CachePreimagesFlag.Name)
|
cfg.Preimages = ctx.Bool(CachePreimagesFlag.Name)
|
||||||
|
|
||||||
if cfg.NoPruning && !cfg.Preimages {
|
if cfg.NoPruning && !cfg.Preimages {
|
||||||
cfg.Preimages = true
|
cfg.Preimages = true
|
||||||
log.Info("Enabling recording of key preimages since archive mode is used")
|
log.Info("Enabling recording of key preimages since archive mode is used")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(TxLookupLimitFlag.Name) {
|
if ctx.IsSet(TxLookupLimitFlag.Name) {
|
||||||
cfg.TxLookupLimit = ctx.Uint64(TxLookupLimitFlag.Name)
|
cfg.TxLookupLimit = ctx.Uint64(TxLookupLimitFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) {
|
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) {
|
||||||
cfg.TrieCleanCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100
|
cfg.TrieCleanCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(CacheTrieJournalFlag.Name) {
|
if ctx.IsSet(CacheTrieJournalFlag.Name) {
|
||||||
cfg.TrieCleanCacheJournal = ctx.String(CacheTrieJournalFlag.Name)
|
cfg.TrieCleanCacheJournal = ctx.String(CacheTrieJournalFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(CacheTrieRejournalFlag.Name) {
|
if ctx.IsSet(CacheTrieRejournalFlag.Name) {
|
||||||
cfg.TrieCleanCacheRejournal = ctx.Duration(CacheTrieRejournalFlag.Name)
|
cfg.TrieCleanCacheRejournal = ctx.Duration(CacheTrieRejournalFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) {
|
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) {
|
||||||
cfg.TrieDirtyCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100
|
cfg.TrieDirtyCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheSnapshotFlag.Name) {
|
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheSnapshotFlag.Name) {
|
||||||
cfg.SnapshotCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheSnapshotFlag.Name) / 100
|
cfg.SnapshotCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheSnapshotFlag.Name) / 100
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(CacheLogSizeFlag.Name) {
|
if ctx.IsSet(CacheLogSizeFlag.Name) {
|
||||||
cfg.FilterLogCacheSize = ctx.Int(CacheLogSizeFlag.Name)
|
cfg.FilterLogCacheSize = ctx.Int(CacheLogSizeFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.Bool(SnapshotFlag.Name) {
|
if !ctx.Bool(SnapshotFlag.Name) {
|
||||||
// If snap-sync is requested, this flag is also required
|
// If snap-sync is requested, this flag is also required
|
||||||
if cfg.SyncMode == downloader.SnapSync {
|
if cfg.SyncMode == downloader.SnapSync {
|
||||||
|
|
@ -1826,9 +1907,11 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
cfg.SnapshotCache = 0 // Disabled
|
cfg.SnapshotCache = 0 // Disabled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(DocRootFlag.Name) {
|
if ctx.IsSet(DocRootFlag.Name) {
|
||||||
cfg.DocRoot = ctx.String(DocRootFlag.Name)
|
cfg.DocRoot = ctx.String(DocRootFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(VMEnableDebugFlag.Name) {
|
if ctx.IsSet(VMEnableDebugFlag.Name) {
|
||||||
// TODO(fjl): force-enable this in --dev mode
|
// TODO(fjl): force-enable this in --dev mode
|
||||||
cfg.EnablePreimageRecording = ctx.Bool(VMEnableDebugFlag.Name)
|
cfg.EnablePreimageRecording = ctx.Bool(VMEnableDebugFlag.Name)
|
||||||
|
|
@ -1842,12 +1925,15 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
} else {
|
} else {
|
||||||
log.Info("Global gas cap disabled")
|
log.Info("Global gas cap disabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(RPCGlobalEVMTimeoutFlag.Name) {
|
if ctx.IsSet(RPCGlobalEVMTimeoutFlag.Name) {
|
||||||
cfg.RPCEVMTimeout = ctx.Duration(RPCGlobalEVMTimeoutFlag.Name)
|
cfg.RPCEVMTimeout = ctx.Duration(RPCGlobalEVMTimeoutFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(RPCGlobalTxFeeCapFlag.Name) {
|
if ctx.IsSet(RPCGlobalTxFeeCapFlag.Name) {
|
||||||
cfg.RPCTxFeeCap = ctx.Float64(RPCGlobalTxFeeCapFlag.Name)
|
cfg.RPCTxFeeCap = ctx.Float64(RPCGlobalTxFeeCapFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(NoDiscoverFlag.Name) {
|
if ctx.IsSet(NoDiscoverFlag.Name) {
|
||||||
cfg.EthDiscoveryURLs, cfg.SnapDiscoveryURLs = []string{}, []string{}
|
cfg.EthDiscoveryURLs, cfg.SnapDiscoveryURLs = []string{}, []string{}
|
||||||
} else if ctx.IsSet(DNSDiscoveryFlag.Name) {
|
} else if ctx.IsSet(DNSDiscoveryFlag.Name) {
|
||||||
|
|
@ -1902,6 +1988,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
if keystores := stack.AccountManager().Backends(keystore.KeyStoreType); len(keystores) > 0 {
|
if keystores := stack.AccountManager().Backends(keystore.KeyStoreType); len(keystores) > 0 {
|
||||||
ks = keystores[0].(*keystore.KeyStore)
|
ks = keystores[0].(*keystore.KeyStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ks == nil {
|
if ks == nil {
|
||||||
Fatalf("Keystore is not available")
|
Fatalf("Keystore is not available")
|
||||||
}
|
}
|
||||||
|
|
@ -1929,6 +2016,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
|
|
||||||
// Create a new developer genesis block or reuse existing one
|
// Create a new developer genesis block or reuse existing one
|
||||||
cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.Int(DeveloperPeriodFlag.Name)), ctx.Uint64(DeveloperGasLimitFlag.Name), developer.Address)
|
cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.Int(DeveloperPeriodFlag.Name)), ctx.Uint64(DeveloperGasLimitFlag.Name), developer.Address)
|
||||||
|
|
||||||
if ctx.IsSet(DataDirFlag.Name) {
|
if ctx.IsSet(DataDirFlag.Name) {
|
||||||
// If datadir doesn't exist we need to open db in write-mode
|
// If datadir doesn't exist we need to open db in write-mode
|
||||||
// so leveldb can create files.
|
// so leveldb can create files.
|
||||||
|
|
@ -1944,6 +2032,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
}
|
}
|
||||||
chaindb.Close()
|
chaindb.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.IsSet(MinerGasPriceFlag.Name) {
|
if !ctx.IsSet(MinerGasPriceFlag.Name) {
|
||||||
cfg.Miner.GasPrice = big.NewInt(1)
|
cfg.Miner.GasPrice = big.NewInt(1)
|
||||||
}
|
}
|
||||||
|
|
@ -1980,6 +2069,7 @@ func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (ethapi.Backend
|
||||||
Fatalf("Failed to register the Ethereum service: %v", err)
|
Fatalf("Failed to register the Ethereum service: %v", err)
|
||||||
}
|
}
|
||||||
stack.RegisterAPIs(tracers.APIs(backend.ApiBackend))
|
stack.RegisterAPIs(tracers.APIs(backend.ApiBackend))
|
||||||
|
|
||||||
if err := lescatalyst.Register(stack, backend); err != nil {
|
if err := lescatalyst.Register(stack, backend); err != nil {
|
||||||
Fatalf("Failed to register the Engine API service: %v", err)
|
Fatalf("Failed to register the Engine API service: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1995,6 +2085,7 @@ func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (ethapi.Backend
|
||||||
Fatalf("Failed to create the LES server: %v", err)
|
Fatalf("Failed to create the LES server: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ethcatalyst.Register(stack, backend); err != nil {
|
if err := ethcatalyst.Register(stack, backend); err != nil {
|
||||||
Fatalf("Failed to register the Engine API service: %v", err)
|
Fatalf("Failed to register the Engine API service: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -2023,10 +2114,12 @@ func RegisterFilterAPI(stack *node.Node, backend ethapi.Backend, ethcfg *ethconf
|
||||||
filterSystem := filters.NewFilterSystem(backend, filters.Config{
|
filterSystem := filters.NewFilterSystem(backend, filters.Config{
|
||||||
LogCacheSize: ethcfg.FilterLogCacheSize,
|
LogCacheSize: ethcfg.FilterLogCacheSize,
|
||||||
})
|
})
|
||||||
|
|
||||||
stack.RegisterAPIs([]rpc.API{{
|
stack.RegisterAPIs([]rpc.API{{
|
||||||
Namespace: "eth",
|
Namespace: "eth",
|
||||||
Service: filters.NewFilterAPI(filterSystem, isLightClient, ethconfig.Defaults.BorLogs),
|
Service: filters.NewFilterAPI(filterSystem, isLightClient, ethconfig.Defaults.BorLogs),
|
||||||
}})
|
}})
|
||||||
|
|
||||||
return filterSystem
|
return filterSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2036,11 +2129,15 @@ func RegisterFullSyncTester(stack *node.Node, eth *eth.Ethereum, path string) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("Failed to read block file: %v", err)
|
Fatalf("Failed to read block file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rlpBlob, err := hexutil.Decode(string(bytes.TrimRight(blob, "\r\n")))
|
rlpBlob, err := hexutil.Decode(string(bytes.TrimRight(blob, "\r\n")))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("Failed to decode block blob: %v", err)
|
Fatalf("Failed to decode block blob: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var block types.Block
|
var block types.Block
|
||||||
|
|
||||||
if err := rlp.DecodeBytes(rlpBlob, &block); err != nil {
|
if err := rlp.DecodeBytes(rlpBlob, &block); err != nil {
|
||||||
Fatalf("Failed to decode block: %v", err)
|
Fatalf("Failed to decode block: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -2135,13 +2232,16 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb.
|
||||||
err error
|
err error
|
||||||
chainDb ethdb.Database
|
chainDb ethdb.Database
|
||||||
)
|
)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case ctx.IsSet(RemoteDBFlag.Name):
|
case ctx.IsSet(RemoteDBFlag.Name):
|
||||||
log.Info("Using remote db", "url", ctx.String(RemoteDBFlag.Name), "headers", len(ctx.StringSlice(HttpHeaderFlag.Name)))
|
log.Info("Using remote db", "url", ctx.String(RemoteDBFlag.Name), "headers", len(ctx.StringSlice(HttpHeaderFlag.Name)))
|
||||||
client, err := DialRPCWithHeaders(ctx.String(RemoteDBFlag.Name), ctx.StringSlice(HttpHeaderFlag.Name))
|
client, err := DialRPCWithHeaders(ctx.String(RemoteDBFlag.Name), ctx.StringSlice(HttpHeaderFlag.Name))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
chainDb = remotedb.New(client)
|
chainDb = remotedb.New(client)
|
||||||
case ctx.String(SyncModeFlag.Name) == "light":
|
case ctx.String(SyncModeFlag.Name) == "light":
|
||||||
chainDb, err = stack.OpenDatabase("lightchaindata", cache, handles, "", readonly)
|
chainDb, err = stack.OpenDatabase("lightchaindata", cache, handles, "", readonly)
|
||||||
|
|
@ -2161,6 +2261,7 @@ func IsNetworkPreset(ctx *cli.Context) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2168,23 +2269,30 @@ func DialRPCWithHeaders(endpoint string, headers []string) (*rpc.Client, error)
|
||||||
if endpoint == "" {
|
if endpoint == "" {
|
||||||
return nil, errors.New("endpoint must be specified")
|
return nil, errors.New("endpoint must be specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") {
|
if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") {
|
||||||
// Backwards compatibility with geth < 1.5 which required
|
// Backwards compatibility with geth < 1.5 which required
|
||||||
// these prefixes.
|
// these prefixes.
|
||||||
endpoint = endpoint[4:]
|
endpoint = endpoint[4:]
|
||||||
}
|
}
|
||||||
|
|
||||||
var opts []rpc.ClientOption
|
var opts []rpc.ClientOption
|
||||||
|
|
||||||
if len(headers) > 0 {
|
if len(headers) > 0 {
|
||||||
var customHeaders = make(http.Header)
|
var customHeaders = make(http.Header)
|
||||||
|
|
||||||
for _, h := range headers {
|
for _, h := range headers {
|
||||||
kv := strings.Split(h, ":")
|
kv := strings.Split(h, ":")
|
||||||
if len(kv) != 2 {
|
if len(kv) != 2 {
|
||||||
return nil, fmt.Errorf("invalid http header directive: %q", h)
|
return nil, fmt.Errorf("invalid http header directive: %q", h)
|
||||||
}
|
}
|
||||||
|
|
||||||
customHeaders.Add(kv[0], kv[1])
|
customHeaders.Add(kv[0], kv[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
opts = append(opts, rpc.WithHeaders(customHeaders))
|
opts = append(opts, rpc.WithHeaders(customHeaders))
|
||||||
}
|
}
|
||||||
|
|
||||||
return rpc.DialOptions(context.Background(), endpoint, opts...)
|
return rpc.DialOptions(context.Background(), endpoint, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2209,18 +2317,23 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
|
||||||
gspec = MakeGenesis(ctx)
|
gspec = MakeGenesis(ctx)
|
||||||
chainDb = MakeChainDatabase(ctx, stack, readonly)
|
chainDb = MakeChainDatabase(ctx, stack, readonly)
|
||||||
)
|
)
|
||||||
|
|
||||||
config, _, err := core.SetupGenesisBlock(chainDb, trie.NewDatabase(chainDb), gspec)
|
config, _, err := core.SetupGenesisBlock(chainDb, trie.NewDatabase(chainDb), gspec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("%v", err)
|
Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cliqueConfig, err := core.LoadCliqueConfig(chainDb, gspec)
|
cliqueConfig, err := core.LoadCliqueConfig(chainDb, gspec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("%v", err)
|
Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ethashConfig := ethconfig.Defaults.Ethash
|
ethashConfig := ethconfig.Defaults.Ethash
|
||||||
|
|
||||||
if ctx.Bool(FakePoWFlag.Name) {
|
if ctx.Bool(FakePoWFlag.Name) {
|
||||||
ethashConfig.PowMode = ethash.ModeFake
|
ethashConfig.PowMode = ethash.ModeFake
|
||||||
}
|
}
|
||||||
|
|
||||||
configs := ðconfig.Config{
|
configs := ðconfig.Config{
|
||||||
Genesis: gspec,
|
Genesis: gspec,
|
||||||
HeimdallURL: ctx.String(HeimdallURLFlag.Name),
|
HeimdallURL: ctx.String(HeimdallURLFlag.Name),
|
||||||
|
|
@ -2232,6 +2345,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
|
||||||
}
|
}
|
||||||
_ = CreateBorEthereum(configs)
|
_ = CreateBorEthereum(configs)
|
||||||
engine := ethconfig.CreateConsensusEngine(stack, config, configs, ðashConfig, cliqueConfig, nil, false, chainDb, nil)
|
engine := ethconfig.CreateConsensusEngine(stack, config, configs, ðashConfig, cliqueConfig, nil, false, chainDb, nil)
|
||||||
|
|
||||||
if gcmode := ctx.String(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
|
if gcmode := ctx.String(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
|
||||||
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
|
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
|
||||||
}
|
}
|
||||||
|
|
@ -2248,6 +2362,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
|
||||||
cache.Preimages = true
|
cache.Preimages = true
|
||||||
log.Info("Enabling recording of key preimages since archive mode is used")
|
log.Info("Enabling recording of key preimages since archive mode is used")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.Bool(SnapshotFlag.Name) {
|
if !ctx.Bool(SnapshotFlag.Name) {
|
||||||
cache.SnapshotLimit = 0 // Disabled
|
cache.SnapshotLimit = 0 // Disabled
|
||||||
}
|
}
|
||||||
|
|
@ -2259,9 +2374,11 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
|
||||||
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) {
|
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) {
|
||||||
cache.TrieCleanLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100
|
cache.TrieCleanLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) {
|
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) {
|
||||||
cache.TrieDirtyLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100
|
cache.TrieDirtyLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100
|
||||||
}
|
}
|
||||||
|
|
||||||
vmcfg := vm.Config{EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name)}
|
vmcfg := vm.Config{EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name)}
|
||||||
|
|
||||||
// Disable transaction indexing/unindexing by default.
|
// Disable transaction indexing/unindexing by default.
|
||||||
|
|
|
||||||
|
|
@ -54,5 +54,6 @@ func showDeprecated(*cli.Context) error {
|
||||||
fmt.Println(flag.String())
|
fmt.Println(flag.String())
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,7 @@ func (c *Console) initWeb3(bridge *bridge) error {
|
||||||
if err := c.jsre.Compile("bignumber.js", deps.BigNumberJS); err != nil {
|
if err := c.jsre.Compile("bignumber.js", deps.BigNumberJS); err != nil {
|
||||||
return fmt.Errorf("bignumber.js: %v", err)
|
return fmt.Errorf("bignumber.js: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.jsre.Compile("web3.js", deps.Web3JS); err != nil {
|
if err := c.jsre.Compile("web3.js", deps.Web3JS); err != nil {
|
||||||
return fmt.Errorf("web3.js: %v", err)
|
return fmt.Errorf("web3.js: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -208,6 +209,7 @@ func (c *Console) initExtensions() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if rpcErr, ok := err.(rpc.Error); ok && rpcErr.ErrorCode() == methodNotFound {
|
if rpcErr, ok := err.(rpc.Error); ok && rpcErr.ErrorCode() == methodNotFound {
|
||||||
log.Warn("Server does not support method rpc_modules, using default API list.")
|
log.Warn("Server does not support method rpc_modules, using default API list.")
|
||||||
|
|
||||||
apis = defaultAPIs
|
apis = defaultAPIs
|
||||||
} else {
|
} else {
|
||||||
return err
|
return err
|
||||||
|
|
@ -260,6 +262,7 @@ func (c *Console) initPersonal(vm *goja.Runtime, bridge *bridge) {
|
||||||
if personal == nil || c.prompter == nil {
|
if personal == nil || c.prompter == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Warn("Enabling deprecated personal namespace")
|
log.Warn("Enabling deprecated personal namespace")
|
||||||
jeth := vm.NewObject()
|
jeth := vm.NewObject()
|
||||||
vm.Set("jeth", jeth)
|
vm.Set("jeth", jeth)
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,7 @@ func genUncles(i int, gen *BlockGen) {
|
||||||
func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
|
func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
|
||||||
// Create the database in memory or in a temporary directory.
|
// Create the database in memory or in a temporary directory.
|
||||||
var db ethdb.Database
|
var db ethdb.Database
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
if !disk {
|
if !disk {
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
|
|
@ -264,6 +265,7 @@ func makeChainForBench(db ethdb.Database, full bool, count uint64) {
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
rawdb.WriteChainConfig(db, hash, params.AllEthashProtocolChanges)
|
rawdb.WriteChainConfig(db, hash, params.AllEthashProtocolChanges)
|
||||||
}
|
}
|
||||||
|
|
||||||
rawdb.WriteHeadHeaderHash(db, hash)
|
rawdb.WriteHeadHeaderHash(db, hash)
|
||||||
|
|
||||||
if full || n == 0 {
|
if full || n == 0 {
|
||||||
|
|
@ -307,6 +309,7 @@ func benchReadChain(b *testing.B, full bool, count uint64) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("error opening database at %v: %v", dir, err)
|
b.Fatalf("error opening database at %v: %v", dir, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
chain, err := NewBlockChain(db, &cacheConfig, nil, nil, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
|
chain, err := NewBlockChain(db, &cacheConfig, nil, nil, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("error creating chain: %v", err)
|
b.Fatalf("error creating chain: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
|
||||||
if block.Withdrawals() == nil {
|
if block.Withdrawals() == nil {
|
||||||
return fmt.Errorf("missing withdrawals in block body")
|
return fmt.Errorf("missing withdrawals in block body")
|
||||||
}
|
}
|
||||||
|
|
||||||
if hash := types.DeriveSha(block.Withdrawals(), trie.NewStackTrie(nil)); hash != *header.WithdrawalsHash {
|
if hash := types.DeriveSha(block.Withdrawals(), trie.NewStackTrie(nil)); hash != *header.WithdrawalsHash {
|
||||||
return fmt.Errorf("withdrawals root hash mismatch (header value %x, calculated %x)", *header.WithdrawalsHash, hash)
|
return fmt.Errorf("withdrawals root hash mismatch (header value %x, calculated %x)", *header.WithdrawalsHash, hash)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,7 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
|
||||||
addr = crypto.PubkeyToAddress(key.PublicKey)
|
addr = crypto.PubkeyToAddress(key.PublicKey)
|
||||||
config = *params.AllCliqueProtocolChanges
|
config = *params.AllCliqueProtocolChanges
|
||||||
)
|
)
|
||||||
|
|
||||||
engine = beacon.New(clique.New(params.AllCliqueProtocolChanges.Clique, rawdb.NewMemoryDatabase()))
|
engine = beacon.New(clique.New(params.AllCliqueProtocolChanges.Clique, rawdb.NewMemoryDatabase()))
|
||||||
gspec = &Genesis{
|
gspec = &Genesis{
|
||||||
Config: &config,
|
Config: &config,
|
||||||
|
|
@ -112,6 +113,7 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
|
||||||
|
|
||||||
td := 0
|
td := 0
|
||||||
genDb, blocks, _ := GenerateChainWithGenesis(gspec, engine, 8, nil)
|
genDb, blocks, _ := GenerateChainWithGenesis(gspec, engine, 8, nil)
|
||||||
|
|
||||||
for i, block := range blocks {
|
for i, block := range blocks {
|
||||||
header := block.Header()
|
header := block.Header()
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
|
|
@ -127,6 +129,7 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
|
||||||
// calculate td
|
// calculate td
|
||||||
td += int(block.Difficulty().Uint64())
|
td += int(block.Difficulty().Uint64())
|
||||||
}
|
}
|
||||||
|
|
||||||
preBlocks = blocks
|
preBlocks = blocks
|
||||||
gspec.Config.TerminalTotalDifficulty = big.NewInt(int64(td))
|
gspec.Config.TerminalTotalDifficulty = big.NewInt(int64(td))
|
||||||
postBlocks, _ = GenerateChain(gspec.Config, preBlocks[len(preBlocks)-1], engine, genDb, 8, nil)
|
postBlocks, _ = GenerateChain(gspec.Config, preBlocks[len(preBlocks)-1], engine, genDb, 8, nil)
|
||||||
|
|
@ -221,6 +224,7 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
|
||||||
headers = append(headers, block.Header())
|
headers = append(headers, block.Header())
|
||||||
seals = append(seals, true)
|
seals = append(seals, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, results := engine.VerifyHeaders(chain, headers, seals)
|
_, results := engine.VerifyHeaders(chain, headers, seals)
|
||||||
for i := 0; i < len(headers); i++ {
|
for i := 0; i < len(headers); i++ {
|
||||||
select {
|
select {
|
||||||
|
|
|
||||||
|
|
@ -274,11 +274,14 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
||||||
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
|
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
|
||||||
return nil, genesisErr
|
return nil, genesisErr
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("")
|
log.Info("")
|
||||||
log.Info(strings.Repeat("-", 153))
|
log.Info(strings.Repeat("-", 153))
|
||||||
|
|
||||||
for _, line := range strings.Split(chainConfig.Description(), "\n") {
|
for _, line := range strings.Split(chainConfig.Description(), "\n") {
|
||||||
log.Info(line)
|
log.Info(line)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info(strings.Repeat("-", 153))
|
log.Info(strings.Repeat("-", 153))
|
||||||
log.Info("")
|
log.Info("")
|
||||||
|
|
||||||
|
|
@ -381,6 +384,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
||||||
snapBlock := bc.CurrentSnapBlock()
|
snapBlock := bc.CurrentSnapBlock()
|
||||||
if snapBlock != nil && snapBlock.Number.Uint64() < frozen-1 {
|
if snapBlock != nil && snapBlock.Number.Uint64() < frozen-1 {
|
||||||
needRewind = true
|
needRewind = true
|
||||||
|
|
||||||
if snapBlock.Number.Uint64() < low || low == 0 {
|
if snapBlock.Number.Uint64() < low || low == 0 {
|
||||||
low = snapBlock.Number.Uint64()
|
low = snapBlock.Number.Uint64()
|
||||||
}
|
}
|
||||||
|
|
@ -426,6 +430,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
||||||
log.Warn("Enabling snapshot recovery", "chainhead", head.Number, "diskbase", *layer)
|
log.Warn("Enabling snapshot recovery", "chainhead", head.Number, "diskbase", *layer)
|
||||||
recover = true
|
recover = true
|
||||||
}
|
}
|
||||||
|
|
||||||
snapconfig := snapshot.Config{
|
snapconfig := snapshot.Config{
|
||||||
CacheSize: bc.cacheConfig.SnapshotLimit,
|
CacheSize: bc.cacheConfig.SnapshotLimit,
|
||||||
Recovery: recover,
|
Recovery: recover,
|
||||||
|
|
@ -454,11 +459,13 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
||||||
// Rewind the chain in case of an incompatible config upgrade.
|
// Rewind the chain in case of an incompatible config upgrade.
|
||||||
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
|
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
|
||||||
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
|
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
|
||||||
|
|
||||||
if compat.RewindToTime > 0 {
|
if compat.RewindToTime > 0 {
|
||||||
bc.SetHeadWithTimestamp(compat.RewindToTime)
|
bc.SetHeadWithTimestamp(compat.RewindToTime)
|
||||||
} else {
|
} else {
|
||||||
bc.SetHead(compat.RewindToBlock)
|
bc.SetHead(compat.RewindToBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
rawdb.WriteChainConfig(db, genesisHash, chainConfig)
|
rawdb.WriteChainConfig(db, genesisHash, chainConfig)
|
||||||
}
|
}
|
||||||
// Start tx indexer/unindexer if required.
|
// Start tx indexer/unindexer if required.
|
||||||
|
|
@ -466,8 +473,10 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
||||||
bc.txLookupLimit = *txLookupLimit
|
bc.txLookupLimit = *txLookupLimit
|
||||||
|
|
||||||
bc.wg.Add(1)
|
bc.wg.Add(1)
|
||||||
|
|
||||||
go bc.maintainTxIndex()
|
go bc.maintainTxIndex()
|
||||||
}
|
}
|
||||||
|
|
||||||
return bc, nil
|
return bc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -486,6 +495,7 @@ func NewParallelBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis
|
||||||
Preimages: cacheConfig.Preimages,
|
Preimages: cacheConfig.Preimages,
|
||||||
})
|
})
|
||||||
chainConfig, _, genesisErr := SetupGenesisBlockWithOverride(db, triedb, genesis, overrides)
|
chainConfig, _, genesisErr := SetupGenesisBlockWithOverride(db, triedb, genesis, overrides)
|
||||||
|
|
||||||
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
|
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
|
||||||
return nil, genesisErr
|
return nil, genesisErr
|
||||||
}
|
}
|
||||||
|
|
@ -611,6 +621,7 @@ func (bc *BlockChain) loadLastState() error {
|
||||||
headHeader = header
|
headHeader = header
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bc.hc.SetCurrentHeader(headHeader)
|
bc.hc.SetCurrentHeader(headHeader)
|
||||||
|
|
||||||
// Restore the last known head fast block
|
// Restore the last known head fast block
|
||||||
|
|
@ -643,14 +654,18 @@ func (bc *BlockChain) loadLastState() error {
|
||||||
headerTd = bc.GetTd(headHeader.Hash(), headHeader.Number.Uint64())
|
headerTd = bc.GetTd(headHeader.Hash(), headHeader.Number.Uint64())
|
||||||
blockTd = bc.GetTd(headBlock.Hash(), headBlock.NumberU64())
|
blockTd = bc.GetTd(headBlock.Hash(), headBlock.NumberU64())
|
||||||
)
|
)
|
||||||
|
|
||||||
if headHeader.Hash() != headBlock.Hash() {
|
if headHeader.Hash() != headBlock.Hash() {
|
||||||
log.Info("Loaded most recent local header", "number", headHeader.Number, "hash", headHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(headHeader.Time), 0)))
|
log.Info("Loaded most recent local header", "number", headHeader.Number, "hash", headHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(headHeader.Time), 0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Loaded most recent local block", "number", headBlock.Number(), "hash", headBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(headBlock.Time()), 0)))
|
log.Info("Loaded most recent local block", "number", headBlock.Number(), "hash", headBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(headBlock.Time()), 0)))
|
||||||
|
|
||||||
if headBlock.Hash() != currentSnapBlock.Hash() {
|
if headBlock.Hash() != currentSnapBlock.Hash() {
|
||||||
fastTd := bc.GetTd(currentSnapBlock.Hash(), currentSnapBlock.Number.Uint64())
|
fastTd := bc.GetTd(currentSnapBlock.Hash(), currentSnapBlock.Number.Uint64())
|
||||||
log.Info("Loaded most recent local snap block", "number", currentSnapBlock.Number, "hash", currentSnapBlock.Hash(), "td", fastTd, "age", common.PrettyAge(time.Unix(int64(currentSnapBlock.Time), 0)))
|
log.Info("Loaded most recent local snap block", "number", currentSnapBlock.Number, "hash", currentSnapBlock.Hash(), "td", fastTd, "age", common.PrettyAge(time.Unix(int64(currentSnapBlock.Time), 0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if currentFinalBlock != nil {
|
if currentFinalBlock != nil {
|
||||||
finalTd := bc.GetTd(currentFinalBlock.Hash(), currentFinalBlock.Number.Uint64())
|
finalTd := bc.GetTd(currentFinalBlock.Hash(), currentFinalBlock.Number.Uint64())
|
||||||
log.Info("Loaded most recent local finalized block", "number", currentFinalBlock.Number, "hash", currentFinalBlock.Hash(), "td", finalTd, "age", common.PrettyAge(time.Unix(int64(currentFinalBlock.Time), 0)))
|
log.Info("Loaded most recent local finalized block", "number", currentFinalBlock.Number, "hash", currentFinalBlock.Hash(), "td", finalTd, "age", common.PrettyAge(time.Unix(int64(currentFinalBlock.Time), 0)))
|
||||||
|
|
@ -671,6 +686,7 @@ func (bc *BlockChain) SetHead(head uint64) error {
|
||||||
// Send chain head event to update the transaction pool
|
// Send chain head event to update the transaction pool
|
||||||
header := bc.CurrentBlock()
|
header := bc.CurrentBlock()
|
||||||
block := bc.GetBlock(header.Hash(), header.Number.Uint64())
|
block := bc.GetBlock(header.Hash(), header.Number.Uint64())
|
||||||
|
|
||||||
if block == nil {
|
if block == nil {
|
||||||
// This should never happen. In practice, previsouly currentBlock
|
// This should never happen. In practice, previsouly currentBlock
|
||||||
// contained the entire block whereas now only a "marker", so there
|
// contained the entire block whereas now only a "marker", so there
|
||||||
|
|
@ -678,7 +694,9 @@ func (bc *BlockChain) SetHead(head uint64) error {
|
||||||
log.Error("Current block not found in database", "block", header.Number, "hash", header.Hash())
|
log.Error("Current block not found in database", "block", header.Number, "hash", header.Hash())
|
||||||
return fmt.Errorf("current block missing: #%d [%x..]", header.Number, header.Hash().Bytes()[:4])
|
return fmt.Errorf("current block missing: #%d [%x..]", header.Number, header.Hash().Bytes()[:4])
|
||||||
}
|
}
|
||||||
|
|
||||||
bc.chainHeadFeed.Send(ChainHeadEvent{Block: block})
|
bc.chainHeadFeed.Send(ChainHeadEvent{Block: block})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -693,6 +711,7 @@ func (bc *BlockChain) SetHeadWithTimestamp(timestamp uint64) error {
|
||||||
// Send chain head event to update the transaction pool
|
// Send chain head event to update the transaction pool
|
||||||
header := bc.CurrentBlock()
|
header := bc.CurrentBlock()
|
||||||
block := bc.GetBlock(header.Hash(), header.Number.Uint64())
|
block := bc.GetBlock(header.Hash(), header.Number.Uint64())
|
||||||
|
|
||||||
if block == nil {
|
if block == nil {
|
||||||
// This should never happen. In practice, previsouly currentBlock
|
// This should never happen. In practice, previsouly currentBlock
|
||||||
// contained the entire block whereas now only a "marker", so there
|
// contained the entire block whereas now only a "marker", so there
|
||||||
|
|
@ -700,13 +719,16 @@ func (bc *BlockChain) SetHeadWithTimestamp(timestamp uint64) error {
|
||||||
log.Error("Current block not found in database", "block", header.Number, "hash", header.Hash())
|
log.Error("Current block not found in database", "block", header.Number, "hash", header.Hash())
|
||||||
return fmt.Errorf("current block missing: #%d [%x..]", header.Number, header.Hash().Bytes()[:4])
|
return fmt.Errorf("current block missing: #%d [%x..]", header.Number, header.Hash().Bytes()[:4])
|
||||||
}
|
}
|
||||||
|
|
||||||
bc.chainHeadFeed.Send(ChainHeadEvent{Block: block})
|
bc.chainHeadFeed.Send(ChainHeadEvent{Block: block})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFinalized sets the finalized block.
|
// SetFinalized sets the finalized block.
|
||||||
func (bc *BlockChain) SetFinalized(header *types.Header) {
|
func (bc *BlockChain) SetFinalized(header *types.Header) {
|
||||||
bc.currentFinalBlock.Store(header)
|
bc.currentFinalBlock.Store(header)
|
||||||
|
|
||||||
if header != nil {
|
if header != nil {
|
||||||
rawdb.WriteFinalizedBlockHash(bc.db, header.Hash())
|
rawdb.WriteFinalizedBlockHash(bc.db, header.Hash())
|
||||||
headFinalizedBlockGauge.Update(int64(header.Number.Uint64()))
|
headFinalizedBlockGauge.Update(int64(header.Number.Uint64()))
|
||||||
|
|
@ -719,6 +741,7 @@ func (bc *BlockChain) SetFinalized(header *types.Header) {
|
||||||
// SetSafe sets the safe block.
|
// SetSafe sets the safe block.
|
||||||
func (bc *BlockChain) SetSafe(header *types.Header) {
|
func (bc *BlockChain) SetSafe(header *types.Header) {
|
||||||
bc.currentSafeBlock.Store(header)
|
bc.currentSafeBlock.Store(header)
|
||||||
|
|
||||||
if header != nil {
|
if header != nil {
|
||||||
headSafeBlockGauge.Update(int64(header.Number.Uint64()))
|
headSafeBlockGauge.Update(int64(header.Number.Uint64()))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -824,15 +847,17 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
|
||||||
if newHeadSnapBlock == nil {
|
if newHeadSnapBlock == nil {
|
||||||
newHeadSnapBlock = bc.genesisBlock
|
newHeadSnapBlock = bc.genesisBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
rawdb.WriteHeadFastBlockHash(db, newHeadSnapBlock.Hash())
|
rawdb.WriteHeadFastBlockHash(db, newHeadSnapBlock.Hash())
|
||||||
|
|
||||||
// Degrade the chain markers if they are explicitly reverted.
|
// Degrade the chain markers if they are explicitly reverted.
|
||||||
// In theory we should update all in-memory markers in the
|
// In theory, we should update all in-memory markers in the
|
||||||
// last step, however the direction of SetHead is from high
|
// last step, however the direction of SetHead is from high
|
||||||
// to low, so it's safe the update in-memory markers directly.
|
// to low, so it's safe the update in-memory markers directly.
|
||||||
bc.currentSnapBlock.Store(newHeadSnapBlock.Header())
|
bc.currentSnapBlock.Store(newHeadSnapBlock.Header())
|
||||||
headFastBlockGauge.Update(int64(newHeadSnapBlock.NumberU64()))
|
headFastBlockGauge.Update(int64(newHeadSnapBlock.NumberU64()))
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
headHeader = bc.CurrentBlock()
|
headHeader = bc.CurrentBlock()
|
||||||
headNumber = headHeader.Number.Uint64()
|
headNumber = headHeader.Number.Uint64()
|
||||||
|
|
@ -844,6 +869,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
|
||||||
if headNumber+1 < frozen {
|
if headNumber+1 < frozen {
|
||||||
wipe = pivot == nil || headNumber >= *pivot
|
wipe = pivot == nil || headNumber >= *pivot
|
||||||
}
|
}
|
||||||
|
|
||||||
return headHeader, wipe // Only force wipe if full synced
|
return headHeader, wipe // Only force wipe if full synced
|
||||||
}
|
}
|
||||||
// Rewind the header chain, deleting all block bodies until then
|
// Rewind the header chain, deleting all block bodies until then
|
||||||
|
|
@ -900,6 +926,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
|
||||||
log.Warn("SetHead invalidated safe block")
|
log.Warn("SetHead invalidated safe block")
|
||||||
bc.SetSafe(nil)
|
bc.SetSafe(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if finalized := bc.CurrentFinalBlock(); finalized != nil && head < finalized.Number.Uint64() {
|
if finalized := bc.CurrentFinalBlock(); finalized != nil && head < finalized.Number.Uint64() {
|
||||||
log.Error("SetHead invalidated finalized block")
|
log.Error("SetHead invalidated finalized block")
|
||||||
bc.SetFinalized(nil)
|
bc.SetFinalized(nil)
|
||||||
|
|
@ -915,7 +942,9 @@ func (bc *BlockChain) SnapSyncCommitHead(hash common.Hash) error {
|
||||||
if block == nil {
|
if block == nil {
|
||||||
return fmt.Errorf("non existent block [%x..]", hash[:4])
|
return fmt.Errorf("non existent block [%x..]", hash[:4])
|
||||||
}
|
}
|
||||||
|
|
||||||
root := block.Root()
|
root := block.Root()
|
||||||
|
|
||||||
if !bc.HasState(root) {
|
if !bc.HasState(root) {
|
||||||
return fmt.Errorf("non existent state [%x..]", root[:4])
|
return fmt.Errorf("non existent state [%x..]", root[:4])
|
||||||
}
|
}
|
||||||
|
|
@ -923,6 +952,7 @@ func (bc *BlockChain) SnapSyncCommitHead(hash common.Hash) error {
|
||||||
if !bc.chainmu.TryLock() {
|
if !bc.chainmu.TryLock() {
|
||||||
return errChainStopped
|
return errChainStopped
|
||||||
}
|
}
|
||||||
|
|
||||||
bc.currentBlock.Store(block.Header())
|
bc.currentBlock.Store(block.Header())
|
||||||
headBlockGauge.Update(int64(block.NumberU64()))
|
headBlockGauge.Update(int64(block.NumberU64()))
|
||||||
bc.chainmu.Unlock()
|
bc.chainmu.Unlock()
|
||||||
|
|
@ -995,9 +1025,11 @@ func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error {
|
||||||
if block == nil {
|
if block == nil {
|
||||||
return fmt.Errorf("export failed on #%d: not found", nr)
|
return fmt.Errorf("export failed on #%d: not found", nr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if nr > first && block.ParentHash() != parentHash {
|
if nr > first && block.ParentHash() != parentHash {
|
||||||
return fmt.Errorf("export failed: chain reorg during export")
|
return fmt.Errorf("export failed: chain reorg during export")
|
||||||
}
|
}
|
||||||
|
|
||||||
parentHash = block.Hash()
|
parentHash = block.Hash()
|
||||||
if err := block.EncodeRLP(w); err != nil {
|
if err := block.EncodeRLP(w); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -1094,6 +1126,7 @@ func (bc *BlockChain) Stop() {
|
||||||
recent := bc.GetBlockByNumber(number - offset)
|
recent := bc.GetBlockByNumber(number - offset)
|
||||||
|
|
||||||
log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root())
|
log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root())
|
||||||
|
|
||||||
if err := triedb.Commit(recent.Root(), true); err != nil {
|
if err := triedb.Commit(recent.Root(), true); err != nil {
|
||||||
log.Error("Failed to commit recent state trie", "err", err)
|
log.Error("Failed to commit recent state trie", "err", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1101,6 +1134,7 @@ func (bc *BlockChain) Stop() {
|
||||||
}
|
}
|
||||||
if snapBase != (common.Hash{}) {
|
if snapBase != (common.Hash{}) {
|
||||||
log.Info("Writing snapshot state to disk", "root", snapBase)
|
log.Info("Writing snapshot state to disk", "root", snapBase)
|
||||||
|
|
||||||
if err := triedb.Commit(snapBase, true); err != nil {
|
if err := triedb.Commit(snapBase, true); err != nil {
|
||||||
log.Error("Failed to commit recent state trie", "err", err)
|
log.Error("Failed to commit recent state trie", "err", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1450,6 +1484,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
|
||||||
if stats.ignored > 0 {
|
if stats.ignored > 0 {
|
||||||
context = append(context, []interface{}{"ignored", stats.ignored}...)
|
context = append(context, []interface{}{"ignored", stats.ignored}...)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("Imported new block receipts", context...)
|
log.Debug("Imported new block receipts", context...)
|
||||||
|
|
||||||
return 0, nil
|
return 0, nil
|
||||||
|
|
@ -1565,6 +1600,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
||||||
nodes, imgs = bc.triedb.Size()
|
nodes, imgs = bc.triedb.Size()
|
||||||
limit = common.StorageSize(bc.cacheConfig.TrieDirtyLimit) * 1024 * 1024
|
limit = common.StorageSize(bc.cacheConfig.TrieDirtyLimit) * 1024 * 1024
|
||||||
)
|
)
|
||||||
|
|
||||||
if nodes > limit || imgs > 4*1024*1024 {
|
if nodes > limit || imgs > 4*1024*1024 {
|
||||||
bc.triedb.Cap(limit - ethdb.IdealBatchSize)
|
bc.triedb.Cap(limit - ethdb.IdealBatchSize)
|
||||||
}
|
}
|
||||||
|
|
@ -1597,6 +1633,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
||||||
bc.triegc.Push(root, number)
|
bc.triegc.Push(root, number)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
bc.triedb.Dereference(root)
|
bc.triedb.Dereference(root)
|
||||||
}
|
}
|
||||||
return stateSyncLogs, nil
|
return stateSyncLogs, nil
|
||||||
|
|
@ -2026,6 +2063,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool)
|
||||||
bc.prefetcher.Prefetch(followup, throwaway, bc.vmConfig, &followupInterrupt)
|
bc.prefetcher.Prefetch(followup, throwaway, bc.vmConfig, &followupInterrupt)
|
||||||
|
|
||||||
blockPrefetchExecuteTimer.Update(time.Since(start))
|
blockPrefetchExecuteTimer.Update(time.Since(start))
|
||||||
|
|
||||||
if followupInterrupt.Load() {
|
if followupInterrupt.Load() {
|
||||||
blockPrefetchInterruptMeter.Mark(1)
|
blockPrefetchInterruptMeter.Mark(1)
|
||||||
}
|
}
|
||||||
|
|
@ -2056,6 +2094,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool)
|
||||||
followupInterrupt.Store(true)
|
followupInterrupt.Store(true)
|
||||||
return it.index, err
|
return it.index, err
|
||||||
}
|
}
|
||||||
|
|
||||||
vtime := time.Since(vstart)
|
vtime := time.Since(vstart)
|
||||||
proctime := time.Since(start) // processing + validation
|
proctime := time.Since(start) // processing + validation
|
||||||
|
|
||||||
|
|
@ -2086,6 +2125,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool)
|
||||||
} else {
|
} else {
|
||||||
status, err = bc.writeBlockAndSetHead(context.Background(), block, receipts, logs, statedb, false)
|
status, err = bc.writeBlockAndSetHead(context.Background(), block, receipts, logs, statedb, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
followupInterrupt.Store(true)
|
followupInterrupt.Store(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return it.index, err
|
return it.index, err
|
||||||
|
|
@ -2353,6 +2393,7 @@ func (bc *BlockChain) recoverAncestors(block *types.Block) (common.Hash, error)
|
||||||
return b.ParentHash(), err
|
return b.ParentHash(), err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return block.Hash(), nil
|
return block.Hash(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2396,10 +2437,13 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
|
||||||
deletedTxs []common.Hash
|
deletedTxs []common.Hash
|
||||||
addedTxs []common.Hash
|
addedTxs []common.Hash
|
||||||
)
|
)
|
||||||
|
|
||||||
oldBlock := bc.GetBlock(oldHead.Hash(), oldHead.Number.Uint64())
|
oldBlock := bc.GetBlock(oldHead.Hash(), oldHead.Number.Uint64())
|
||||||
|
|
||||||
if oldBlock == nil {
|
if oldBlock == nil {
|
||||||
return errors.New("current head block missing")
|
return errors.New("current head block missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
newBlock := newHead
|
newBlock := newHead
|
||||||
|
|
||||||
// Reduce the longer chain to the same number as the shorter one
|
// Reduce the longer chain to the same number as the shorter one
|
||||||
|
|
@ -2407,6 +2451,7 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
|
||||||
// Old chain is longer, gather all transactions and logs as deleted ones
|
// Old chain is longer, gather all transactions and logs as deleted ones
|
||||||
for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) {
|
for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) {
|
||||||
oldChain = append(oldChain, oldBlock)
|
oldChain = append(oldChain, oldBlock)
|
||||||
|
|
||||||
for _, tx := range oldBlock.Transactions() {
|
for _, tx := range oldBlock.Transactions() {
|
||||||
deletedTxs = append(deletedTxs, tx.Hash())
|
deletedTxs = append(deletedTxs, tx.Hash())
|
||||||
}
|
}
|
||||||
|
|
@ -2433,6 +2478,7 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
|
||||||
}
|
}
|
||||||
// Remove an old block as well as stash away a new block
|
// Remove an old block as well as stash away a new block
|
||||||
oldChain = append(oldChain, oldBlock)
|
oldChain = append(oldChain, oldBlock)
|
||||||
|
|
||||||
for _, tx := range oldBlock.Transactions() {
|
for _, tx := range oldBlock.Transactions() {
|
||||||
deletedTxs = append(deletedTxs, tx.Hash())
|
deletedTxs = append(deletedTxs, tx.Hash())
|
||||||
}
|
}
|
||||||
|
|
@ -2551,6 +2597,7 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
|
||||||
|
|
||||||
// Deleted logs + blocks:
|
// Deleted logs + blocks:
|
||||||
var deletedLogs []*types.Log
|
var deletedLogs []*types.Log
|
||||||
|
|
||||||
for i := len(oldChain) - 1; i >= 0; i-- {
|
for i := len(oldChain) - 1; i >= 0; i-- {
|
||||||
// Also send event for blocks removed from the canon chain.
|
// Also send event for blocks removed from the canon chain.
|
||||||
bc.chainSideFeed.Send(ChainSideEvent{Block: oldChain[i]})
|
bc.chainSideFeed.Send(ChainSideEvent{Block: oldChain[i]})
|
||||||
|
|
@ -2559,26 +2606,31 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
|
||||||
if logs := bc.collectLogs(oldChain[i], true); len(logs) > 0 {
|
if logs := bc.collectLogs(oldChain[i], true); len(logs) > 0 {
|
||||||
deletedLogs = append(deletedLogs, logs...)
|
deletedLogs = append(deletedLogs, logs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(deletedLogs) > 512 {
|
if len(deletedLogs) > 512 {
|
||||||
bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs})
|
bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs})
|
||||||
deletedLogs = nil
|
deletedLogs = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(deletedLogs) > 0 {
|
if len(deletedLogs) > 0 {
|
||||||
bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs})
|
bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs})
|
||||||
}
|
}
|
||||||
|
|
||||||
// New logs:
|
// New logs:
|
||||||
var rebirthLogs []*types.Log
|
var rebirthLogs []*types.Log
|
||||||
|
|
||||||
for i := len(newChain) - 1; i >= 1; i-- {
|
for i := len(newChain) - 1; i >= 1; i-- {
|
||||||
if logs := bc.collectLogs(newChain[i], false); len(logs) > 0 {
|
if logs := bc.collectLogs(newChain[i], false); len(logs) > 0 {
|
||||||
rebirthLogs = append(rebirthLogs, logs...)
|
rebirthLogs = append(rebirthLogs, logs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(rebirthLogs) > 512 {
|
if len(rebirthLogs) > 512 {
|
||||||
bc.logsFeed.Send(rebirthLogs)
|
bc.logsFeed.Send(rebirthLogs)
|
||||||
rebirthLogs = nil
|
rebirthLogs = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(rebirthLogs) > 0 {
|
if len(rebirthLogs) > 0 {
|
||||||
bc.logsFeed.Send(rebirthLogs)
|
bc.logsFeed.Send(rebirthLogs)
|
||||||
}
|
}
|
||||||
|
|
@ -2652,6 +2704,7 @@ func (bc *BlockChain) SetCanonical(head *types.Block) (common.Hash, error) {
|
||||||
if latestValidHash, err := bc.recoverAncestors(head); err != nil {
|
if latestValidHash, err := bc.recoverAncestors(head); err != nil {
|
||||||
return latestValidHash, err
|
return latestValidHash, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Recovered head state", "number", head.Number(), "hash", head.Hash())
|
log.Info("Recovered head state", "number", head.Number(), "hash", head.Hash())
|
||||||
}
|
}
|
||||||
// Run the reorg if necessary and set the given block as new head.
|
// Run the reorg if necessary and set the given block as new head.
|
||||||
|
|
@ -2681,6 +2734,7 @@ func (bc *BlockChain) SetCanonical(head *types.Block) (common.Hash, error) {
|
||||||
context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...)
|
context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...)
|
||||||
}
|
}
|
||||||
log.Info("Chain head was updated", context...)
|
log.Info("Chain head was updated", context...)
|
||||||
|
|
||||||
return head.Hash(), nil
|
return head.Hash(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2750,7 +2804,9 @@ func (bc *BlockChain) indexBlocks(tail *uint64, head uint64, done chan struct{})
|
||||||
if bc.txLookupLimit != 0 && head >= bc.txLookupLimit {
|
if bc.txLookupLimit != 0 && head >= bc.txLookupLimit {
|
||||||
from = head - bc.txLookupLimit + 1
|
from = head - bc.txLookupLimit + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
rawdb.IndexTransactions(bc.db, from, head+1, bc.quit)
|
rawdb.IndexTransactions(bc.db, from, head+1, bc.quit)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// The tail flag is existent, but the whole chain is required to be indexed.
|
// The tail flag is existent, but the whole chain is required to be indexed.
|
||||||
|
|
@ -2763,8 +2819,10 @@ func (bc *BlockChain) indexBlocks(tail *uint64, head uint64, done chan struct{})
|
||||||
if end > head+1 {
|
if end > head+1 {
|
||||||
end = head + 1
|
end = head + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
rawdb.IndexTransactions(bc.db, 0, end, bc.quit)
|
rawdb.IndexTransactions(bc.db, 0, end, bc.quit)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Update the transaction index to the new chain state
|
// Update the transaction index to the new chain state
|
||||||
|
|
@ -2835,11 +2893,14 @@ func summarizeBadBlock(block *types.Block, receipts []*types.Receipt, config *pa
|
||||||
i, receipt.CumulativeGasUsed, receipt.GasUsed, receipt.ContractAddress.Hex(),
|
i, receipt.CumulativeGasUsed, receipt.GasUsed, receipt.ContractAddress.Hex(),
|
||||||
receipt.Status, receipt.TxHash.Hex(), receipt.Logs, receipt.Bloom, receipt.PostState)
|
receipt.Status, receipt.TxHash.Hex(), receipt.Logs, receipt.Bloom, receipt.PostState)
|
||||||
}
|
}
|
||||||
|
|
||||||
version, vcs := version.Info()
|
version, vcs := version.Info()
|
||||||
platform := fmt.Sprintf("%s %s %s %s", version, runtime.Version(), runtime.GOARCH, runtime.GOOS)
|
platform := fmt.Sprintf("%s %s %s %s", version, runtime.Version(), runtime.GOARCH, runtime.GOOS)
|
||||||
|
|
||||||
if vcs != "" {
|
if vcs != "" {
|
||||||
vcs = fmt.Sprintf("\nVCS: %s", vcs)
|
vcs = fmt.Sprintf("\nVCS: %s", vcs)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf(`
|
return fmt.Sprintf(`
|
||||||
########## BAD BLOCK #########
|
########## BAD BLOCK #########
|
||||||
Block: %v (%#x)
|
Block: %v (%#x)
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,7 @@ func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool {
|
||||||
if bc.blockCache.Contains(hash) {
|
if bc.blockCache.Contains(hash) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bc.HasHeader(hash, number) {
|
if !bc.HasHeader(hash, number) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,11 +69,13 @@ func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *G
|
||||||
// Full block-chain requested
|
// Full block-chain requested
|
||||||
genDb, blocks := makeBlockChainWithGenesis(genesis, n, engine, canonicalSeed)
|
genDb, blocks := makeBlockChainWithGenesis(genesis, n, engine, canonicalSeed)
|
||||||
_, err := blockchain.InsertChain(blocks)
|
_, err := blockchain.InsertChain(blocks)
|
||||||
|
|
||||||
return genDb, genesis, blockchain, err
|
return genDb, genesis, blockchain, err
|
||||||
}
|
}
|
||||||
// Header-only chain requested
|
// Header-only chain requested
|
||||||
genDb, headers := makeHeaderChainWithGenesis(genesis, n, engine, canonicalSeed)
|
genDb, headers := makeHeaderChainWithGenesis(genesis, n, engine, canonicalSeed)
|
||||||
_, err := blockchain.InsertHeaderChain(headers, 1)
|
_, err := blockchain.InsertHeaderChain(headers, 1)
|
||||||
|
|
||||||
return genDb, genesis, blockchain, err
|
return genDb, genesis, blockchain, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -261,6 +263,7 @@ func testInsertAfterMerge(t *testing.T, blockchain *BlockChain, i, n int, full b
|
||||||
if _, err := blockchain2.InsertChain(blockChainB); err != nil {
|
if _, err := blockchain2.InsertChain(blockChainB); err != nil {
|
||||||
t.Fatalf("failed to insert forking chain: %v", err)
|
t.Fatalf("failed to insert forking chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if blockchain2.CurrentBlock().Number.Uint64() != blockChainB[len(blockChainB)-1].NumberU64() {
|
if blockchain2.CurrentBlock().Number.Uint64() != blockChainB[len(blockChainB)-1].NumberU64() {
|
||||||
t.Fatalf("failed to reorg to the given chain")
|
t.Fatalf("failed to reorg to the given chain")
|
||||||
}
|
}
|
||||||
|
|
@ -767,6 +770,7 @@ func TestFastVsFullChains(t *testing.T) {
|
||||||
}
|
}
|
||||||
signer = types.LatestSigner(gspec.Config)
|
signer = types.LatestSigner(gspec.Config)
|
||||||
)
|
)
|
||||||
|
|
||||||
_, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 1024, func(i int, block *BlockGen) {
|
_, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 1024, func(i int, block *BlockGen) {
|
||||||
block.SetCoinbase(common.Address{0x00})
|
block.SetCoinbase(common.Address{0x00})
|
||||||
|
|
||||||
|
|
@ -902,6 +906,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create temp freezer db: %v", err)
|
t.Fatalf("failed to create temp freezer db: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return db
|
return db
|
||||||
}
|
}
|
||||||
// Configure a subchain to roll back
|
// Configure a subchain to roll back
|
||||||
|
|
@ -914,6 +919,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
|
||||||
if num := chain.CurrentBlock().Number.Uint64(); num != block {
|
if num := chain.CurrentBlock().Number.Uint64(); num != block {
|
||||||
t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
|
t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
|
||||||
}
|
}
|
||||||
|
|
||||||
if num := chain.CurrentSnapBlock().Number.Uint64(); num != fast {
|
if num := chain.CurrentSnapBlock().Number.Uint64(); num != fast {
|
||||||
t.Errorf("%s head snap-block mismatch: have #%v, want #%v", kind, num, fast)
|
t.Errorf("%s head snap-block mismatch: have #%v, want #%v", kind, num, fast)
|
||||||
}
|
}
|
||||||
|
|
@ -1122,6 +1128,7 @@ func TestLogReorgs(t *testing.T) {
|
||||||
|
|
||||||
rmLogsCh := make(chan RemovedLogsEvent)
|
rmLogsCh := make(chan RemovedLogsEvent)
|
||||||
blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
|
blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
|
||||||
|
|
||||||
_, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 2, func(i int, gen *BlockGen) {
|
_, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 2, func(i int, gen *BlockGen) {
|
||||||
if i == 1 {
|
if i == 1 {
|
||||||
tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, code), signer, key1)
|
tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, code), signer, key1)
|
||||||
|
|
@ -1198,6 +1205,7 @@ func TestLogRebirth(t *testing.T) {
|
||||||
if _, err := blockchain.InsertChain(chain); err != nil {
|
if _, err := blockchain.InsertChain(chain); err != nil {
|
||||||
t.Fatalf("failed to insert chain: %v", err)
|
t.Fatalf("failed to insert chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
checkLogEvents(t, newLogCh, rmLogsCh, 10, 0)
|
checkLogEvents(t, newLogCh, rmLogsCh, 10, 0)
|
||||||
|
|
||||||
// Generate long reorg chain containing more logs. Inserting the
|
// Generate long reorg chain containing more logs. Inserting the
|
||||||
|
|
@ -1224,6 +1232,7 @@ func TestLogRebirth(t *testing.T) {
|
||||||
if _, err := blockchain.InsertChain(forkChain); err != nil {
|
if _, err := blockchain.InsertChain(forkChain); err != nil {
|
||||||
t.Fatalf("failed to insert forked chain: %v", err)
|
t.Fatalf("failed to insert forked chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
checkLogEvents(t, newLogCh, rmLogsCh, 10, 10)
|
checkLogEvents(t, newLogCh, rmLogsCh, 10, 10)
|
||||||
|
|
||||||
// This chain segment is rooted in the original chain, but doesn't contain any logs.
|
// This chain segment is rooted in the original chain, but doesn't contain any logs.
|
||||||
|
|
@ -1233,6 +1242,7 @@ func TestLogRebirth(t *testing.T) {
|
||||||
if _, err := blockchain.InsertChain(newBlocks); err != nil {
|
if _, err := blockchain.InsertChain(newBlocks); err != nil {
|
||||||
t.Fatalf("failed to insert forked chain: %v", err)
|
t.Fatalf("failed to insert forked chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
checkLogEvents(t, newLogCh, rmLogsCh, 10, 10)
|
checkLogEvents(t, newLogCh, rmLogsCh, 10, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1288,6 +1298,7 @@ func TestSideLogRebirth(t *testing.T) {
|
||||||
|
|
||||||
func checkLogEvents(t *testing.T, logsCh <-chan []*types.Log, rmLogsCh <-chan RemovedLogsEvent, wantNew, wantRemoved int) {
|
func checkLogEvents(t *testing.T, logsCh <-chan []*types.Log, rmLogsCh <-chan RemovedLogsEvent, wantNew, wantRemoved int) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
countNew int
|
countNew int
|
||||||
countRm int
|
countRm int
|
||||||
|
|
@ -1297,25 +1308,31 @@ func checkLogEvents(t *testing.T, logsCh <-chan []*types.Log, rmLogsCh <-chan Re
|
||||||
for len(logsCh) > 0 {
|
for len(logsCh) > 0 {
|
||||||
x := <-logsCh
|
x := <-logsCh
|
||||||
countNew += len(x)
|
countNew += len(x)
|
||||||
|
|
||||||
for _, log := range x {
|
for _, log := range x {
|
||||||
// We expect added logs to be in ascending order: 0:0, 0:1, 1:0 ...
|
// We expect added logs to be in ascending order: 0:0, 0:1, 1:0 ...
|
||||||
have := 100*int(log.BlockNumber) + int(log.TxIndex)
|
have := 100*int(log.BlockNumber) + int(log.TxIndex)
|
||||||
if have < prev {
|
if have < prev {
|
||||||
t.Fatalf("Expected new logs to arrive in ascending order (%d < %d)", have, prev)
|
t.Fatalf("Expected new logs to arrive in ascending order (%d < %d)", have, prev)
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = have
|
prev = have
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = 0
|
prev = 0
|
||||||
|
|
||||||
for len(rmLogsCh) > 0 {
|
for len(rmLogsCh) > 0 {
|
||||||
x := <-rmLogsCh
|
x := <-rmLogsCh
|
||||||
countRm += len(x.Logs)
|
countRm += len(x.Logs)
|
||||||
|
|
||||||
for _, log := range x.Logs {
|
for _, log := range x.Logs {
|
||||||
// We expect removed logs to be in ascending order: 0:0, 0:1, 1:0 ...
|
// We expect removed logs to be in ascending order: 0:0, 0:1, 1:0 ...
|
||||||
have := 100*int(log.BlockNumber) + int(log.TxIndex)
|
have := 100*int(log.BlockNumber) + int(log.TxIndex)
|
||||||
if have < prev {
|
if have < prev {
|
||||||
t.Fatalf("Expected removed logs to arrive in ascending order (%d < %d)", have, prev)
|
t.Fatalf("Expected removed logs to arrive in ascending order (%d < %d)", have, prev)
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = have
|
prev = have
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1323,6 +1340,7 @@ func checkLogEvents(t *testing.T, logsCh <-chan []*types.Log, rmLogsCh <-chan Re
|
||||||
if countNew != wantNew {
|
if countNew != wantNew {
|
||||||
t.Fatalf("wrong number of log events: got %d, want %d", countNew, wantNew)
|
t.Fatalf("wrong number of log events: got %d, want %d", countNew, wantNew)
|
||||||
}
|
}
|
||||||
|
|
||||||
if countRm != wantRemoved {
|
if countRm != wantRemoved {
|
||||||
t.Fatalf("wrong number of removed log events: got %d, want %d", countRm, wantRemoved)
|
t.Fatalf("wrong number of removed log events: got %d, want %d", countRm, wantRemoved)
|
||||||
}
|
}
|
||||||
|
|
@ -1338,6 +1356,7 @@ func TestReorgSideEvent(t *testing.T) {
|
||||||
}
|
}
|
||||||
signer = types.LatestSigner(gspec.Config)
|
signer = types.LatestSigner(gspec.Config)
|
||||||
)
|
)
|
||||||
|
|
||||||
blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
|
blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
|
||||||
defer blockchain.Stop()
|
defer blockchain.Stop()
|
||||||
|
|
||||||
|
|
@ -1471,6 +1490,7 @@ func TestEIP155Transition(t *testing.T) {
|
||||||
Alloc: GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
|
Alloc: GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
genDb, blocks, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 4, func(i int, block *BlockGen) {
|
genDb, blocks, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 4, func(i int, block *BlockGen) {
|
||||||
var (
|
var (
|
||||||
tx *types.Transaction
|
tx *types.Transaction
|
||||||
|
|
@ -1582,6 +1602,7 @@ func TestEIP161AccountRemoval(t *testing.T) {
|
||||||
Alloc: GenesisAlloc{address: {Balance: funds}},
|
Alloc: GenesisAlloc{address: {Balance: funds}},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
_, blocks, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 3, func(i int, block *BlockGen) {
|
_, blocks, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 3, func(i int, block *BlockGen) {
|
||||||
var (
|
var (
|
||||||
tx *types.Transaction
|
tx *types.Transaction
|
||||||
|
|
@ -1650,6 +1671,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
parent = blocks[i-1]
|
parent = blocks[i-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
|
fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
|
||||||
forks[i] = fork[0]
|
forks[i] = fork[0]
|
||||||
}
|
}
|
||||||
|
|
@ -1659,6 +1681,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
for i := 0; i < len(blocks); i++ {
|
for i := 0; i < len(blocks); i++ {
|
||||||
|
|
@ -1695,6 +1718,7 @@ func TestTrieForkGC(t *testing.T) {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
parent = blocks[i-1]
|
parent = blocks[i-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
|
fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
|
||||||
forks[i] = fork[0]
|
forks[i] = fork[0]
|
||||||
}
|
}
|
||||||
|
|
@ -1703,6 +1727,7 @@ func TestTrieForkGC(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
for i := 0; i < len(blocks); i++ {
|
for i := 0; i < len(blocks); i++ {
|
||||||
|
|
@ -1741,6 +1766,7 @@ func TestLargeReorgTrieGC(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
if _, err := chain.InsertChain(shared); err != nil {
|
if _, err := chain.InsertChain(shared); err != nil {
|
||||||
|
|
@ -1814,9 +1840,11 @@ func TestBlockchainRecovery(t *testing.T) {
|
||||||
// Reopen broken blockchain again
|
// Reopen broken blockchain again
|
||||||
ancient, _ = NewBlockChain(ancientDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
|
ancient, _ = NewBlockChain(ancientDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
|
||||||
defer ancient.Stop()
|
defer ancient.Stop()
|
||||||
|
|
||||||
if num := ancient.CurrentBlock().Number.Uint64(); num != 0 {
|
if num := ancient.CurrentBlock().Number.Uint64(); num != 0 {
|
||||||
t.Errorf("head block mismatch: have #%v, want #%v", num, 0)
|
t.Errorf("head block mismatch: have #%v, want #%v", num, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if num := ancient.CurrentSnapBlock().Number.Uint64(); num != midBlock.NumberU64() {
|
if num := ancient.CurrentSnapBlock().Number.Uint64(); num != midBlock.NumberU64() {
|
||||||
t.Errorf("head snap-block mismatch: have #%v, want #%v", num, midBlock.NumberU64())
|
t.Errorf("head snap-block mismatch: have #%v, want #%v", num, midBlock.NumberU64())
|
||||||
}
|
}
|
||||||
|
|
@ -1837,6 +1865,7 @@ func TestInsertReceiptChainRollback(t *testing.T) {
|
||||||
if _, err := tmpChain.InsertChain(sideblocks); err != nil {
|
if _, err := tmpChain.InsertChain(sideblocks); err != nil {
|
||||||
t.Fatal("processing side chain failed:", err)
|
t.Fatal("processing side chain failed:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Log("sidechain head:", tmpChain.CurrentBlock().Number, tmpChain.CurrentBlock().Hash())
|
t.Log("sidechain head:", tmpChain.CurrentBlock().Number, tmpChain.CurrentBlock().Hash())
|
||||||
sidechainReceipts := make([]types.Receipts, len(sideblocks))
|
sidechainReceipts := make([]types.Receipts, len(sideblocks))
|
||||||
for i, block := range sideblocks {
|
for i, block := range sideblocks {
|
||||||
|
|
@ -1846,6 +1875,7 @@ func TestInsertReceiptChainRollback(t *testing.T) {
|
||||||
if _, err := tmpChain.InsertChain(canonblocks); err != nil {
|
if _, err := tmpChain.InsertChain(canonblocks); err != nil {
|
||||||
t.Fatal("processing canon chain failed:", err)
|
t.Fatal("processing canon chain failed:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Log("canon head:", tmpChain.CurrentBlock().Number, tmpChain.CurrentBlock().Hash())
|
t.Log("canon head:", tmpChain.CurrentBlock().Number, tmpChain.CurrentBlock().Hash())
|
||||||
canonReceipts := make([]types.Receipts, len(canonblocks))
|
canonReceipts := make([]types.Receipts, len(canonblocks))
|
||||||
for i, block := range canonblocks {
|
for i, block := range canonblocks {
|
||||||
|
|
@ -1876,6 +1906,7 @@ func TestInsertReceiptChainRollback(t *testing.T) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error from InsertReceiptChain.")
|
t.Fatal("expected error from InsertReceiptChain.")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ancientChain.CurrentSnapBlock().Number.Uint64() != 0 {
|
if ancientChain.CurrentSnapBlock().Number.Uint64() != 0 {
|
||||||
t.Fatalf("failed to rollback ancient data, want %d, have %d", 0, ancientChain.CurrentSnapBlock().Number)
|
t.Fatalf("failed to rollback ancient data, want %d, have %d", 0, ancientChain.CurrentSnapBlock().Number)
|
||||||
}
|
}
|
||||||
|
|
@ -1888,6 +1919,7 @@ func TestInsertReceiptChainRollback(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't import canon chain receipts: %v", err)
|
t.Fatalf("can't import canon chain receipts: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ancientChain.CurrentSnapBlock().Number.Uint64() != canonblocks[len(canonblocks)-1].NumberU64() {
|
if ancientChain.CurrentSnapBlock().Number.Uint64() != canonblocks[len(canonblocks)-1].NumberU64() {
|
||||||
t.Fatalf("failed to insert ancient recept chain after rollback")
|
t.Fatalf("failed to insert ancient recept chain after rollback")
|
||||||
}
|
}
|
||||||
|
|
@ -1922,6 +1954,7 @@ func TestLowDiffLongChain(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.stopWithoutSaving()
|
defer chain.stopWithoutSaving()
|
||||||
|
|
||||||
if n, err := chain.InsertChain(blocks); err != nil {
|
if n, err := chain.InsertChain(blocks); err != nil {
|
||||||
|
|
@ -1984,6 +2017,7 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
// Activate the transition since genesis if required
|
// Activate the transition since genesis if required
|
||||||
|
|
@ -1995,6 +2029,7 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon
|
||||||
// Set the terminal total difficulty in the config
|
// Set the terminal total difficulty in the config
|
||||||
gspec.Config.TerminalTotalDifficulty = big.NewInt(0)
|
gspec.Config.TerminalTotalDifficulty = big.NewInt(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
genDb, blocks, _ := GenerateChainWithGenesis(gspec, engine, 2*int(DefaultCacheConfig.TriesInMemory), func(i int, gen *BlockGen) {
|
genDb, blocks, _ := GenerateChainWithGenesis(gspec, engine, 2*int(DefaultCacheConfig.TriesInMemory), func(i int, gen *BlockGen) {
|
||||||
tx, err := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("deadbeef"), big.NewInt(100), 21000, big.NewInt(int64(i+1)*params.GWei), nil), signer, key)
|
tx, err := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("deadbeef"), big.NewInt(100), 21000, big.NewInt(int64(i+1)*params.GWei), nil), signer, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -2133,6 +2168,7 @@ func testInsertKnownChainData(t *testing.T, typ string) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -2304,6 +2340,7 @@ func testInsertKnownChainDataWithMerging(t *testing.T, typ string, mergeHeight i
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -2316,7 +2353,9 @@ func testInsertKnownChainDataWithMerging(t *testing.T, typ string, mergeHeight i
|
||||||
for _, block := range blocks {
|
for _, block := range blocks {
|
||||||
headers = append(headers, block.Header())
|
headers = append(headers, block.Header())
|
||||||
}
|
}
|
||||||
|
|
||||||
i, err := chain.InsertHeaderChain(headers, 1)
|
i, err := chain.InsertHeaderChain(headers, 1)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("index %d, number %d: %w", i, headers[i].Number, err)
|
return fmt.Errorf("index %d, number %d: %w", i, headers[i].Number, err)
|
||||||
}
|
}
|
||||||
|
|
@ -2425,6 +2464,7 @@ func getLongAndShortChains() (*BlockChain, []*types.Block, []*types.Block, *Gene
|
||||||
b.SetCoinbase(common.Address{2})
|
b.SetCoinbase(common.Address{2})
|
||||||
b.OffsetTime(-9)
|
b.OffsetTime(-9)
|
||||||
})
|
})
|
||||||
|
|
||||||
var heavyChain []*types.Block
|
var heavyChain []*types.Block
|
||||||
heavyChain = append(heavyChain, longChain[:parentIndex+1]...)
|
heavyChain = append(heavyChain, longChain[:parentIndex+1]...)
|
||||||
heavyChain = append(heavyChain, heavyChainExt...)
|
heavyChain = append(heavyChain, heavyChainExt...)
|
||||||
|
|
@ -2451,6 +2491,7 @@ func getLongAndShortChains() (*BlockChain, []*types.Block, []*types.Block, *Gene
|
||||||
if shorterNum >= longerNum {
|
if shorterNum >= longerNum {
|
||||||
return nil, nil, nil, nil, fmt.Errorf("test is moot, heavyChain num (%v) must be lower than canon num (%v)", shorterNum, longerNum)
|
return nil, nil, nil, nil, fmt.Errorf("test is moot, heavyChain num (%v) must be lower than canon num (%v)", shorterNum, longerNum)
|
||||||
}
|
}
|
||||||
|
|
||||||
return chain, longChain, heavyChain, genesis, nil
|
return chain, longChain, heavyChain, genesis, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2464,11 +2505,13 @@ func TestReorgToShorterRemovesCanonMapping(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
if n, err := chain.InsertChain(canonblocks); err != nil {
|
if n, err := chain.InsertChain(canonblocks); err != nil {
|
||||||
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
canonNum := chain.CurrentBlock().Number.Uint64()
|
canonNum := chain.CurrentBlock().Number.Uint64()
|
||||||
canonHash := chain.CurrentBlock().Hash()
|
canonHash := chain.CurrentBlock().Hash()
|
||||||
_, err = chain.InsertChain(sideblocks)
|
_, err = chain.InsertChain(sideblocks)
|
||||||
|
|
@ -2502,6 +2545,7 @@ func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
// Convert into headers
|
// Convert into headers
|
||||||
|
|
@ -2553,6 +2597,7 @@ func TestTransactionIndices(t *testing.T) {
|
||||||
}
|
}
|
||||||
signer = types.LatestSigner(gspec.Config)
|
signer = types.LatestSigner(gspec.Config)
|
||||||
)
|
)
|
||||||
|
|
||||||
_, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 128, func(i int, block *BlockGen) {
|
_, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 128, func(i int, block *BlockGen) {
|
||||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
|
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -2606,6 +2651,7 @@ func TestTransactionIndices(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
chain.indexBlocks(rawdb.ReadTxIndexTail(ancientDb), 128, make(chan struct{}))
|
chain.indexBlocks(rawdb.ReadTxIndexTail(ancientDb), 128, make(chan struct{}))
|
||||||
|
|
||||||
var tail uint64
|
var tail uint64
|
||||||
|
|
@ -2624,16 +2670,20 @@ func TestTransactionIndices(t *testing.T) {
|
||||||
|
|
||||||
rawdb.WriteAncientBlocks(ancientDb, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...), []types.Receipts{nil}, big.NewInt(0))
|
rawdb.WriteAncientBlocks(ancientDb, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...), []types.Receipts{nil}, big.NewInt(0))
|
||||||
limit = []uint64{0, 64 /* drop stale */, 32 /* shorten history */, 64 /* extend history */, 0 /* restore all */}
|
limit = []uint64{0, 64 /* drop stale */, 32 /* shorten history */, 64 /* extend history */, 0 /* restore all */}
|
||||||
|
|
||||||
for _, l := range limit {
|
for _, l := range limit {
|
||||||
l := l
|
l := l
|
||||||
chain, err := NewBlockChain(ancientDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, &l, nil)
|
chain, err := NewBlockChain(ancientDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, &l, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var tail uint64
|
var tail uint64
|
||||||
|
|
||||||
if l != 0 {
|
if l != 0 {
|
||||||
tail = uint64(128) - l + 1
|
tail = uint64(128) - l + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
chain.indexBlocks(rawdb.ReadTxIndexTail(ancientDb), 128, make(chan struct{}))
|
chain.indexBlocks(rawdb.ReadTxIndexTail(ancientDb), 128, make(chan struct{}))
|
||||||
check(&tail, chain)
|
check(&tail, chain)
|
||||||
chain.Stop()
|
chain.Stop()
|
||||||
|
|
@ -2649,6 +2699,7 @@ func TestSkipStaleTxIndicesInSnapSync(t *testing.T) {
|
||||||
gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
|
gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
|
||||||
signer = types.LatestSigner(gspec.Config)
|
signer = types.LatestSigner(gspec.Config)
|
||||||
)
|
)
|
||||||
|
|
||||||
_, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 128, func(i int, block *BlockGen) {
|
_, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 128, func(i int, block *BlockGen) {
|
||||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
|
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -2703,6 +2754,7 @@ func TestSkipStaleTxIndicesInSnapSync(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
headers := make([]*types.Header, len(blocks))
|
headers := make([]*types.Header, len(blocks))
|
||||||
|
|
@ -2769,7 +2821,9 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in
|
||||||
b.Fatalf("failed to insert shared chain: %v", err)
|
b.Fatalf("failed to insert shared chain: %v", err)
|
||||||
}
|
}
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
|
|
||||||
block := chain.GetBlockByHash(chain.CurrentBlock().Hash())
|
block := chain.GetBlockByHash(chain.CurrentBlock().Hash())
|
||||||
|
|
||||||
if got := block.Transactions().Len(); got != numTxs*numBlocks {
|
if got := block.Transactions().Len(); got != numTxs*numBlocks {
|
||||||
b.Fatalf("Transactions were not included, expected %d, got %d", numTxs*numBlocks, got)
|
b.Fatalf("Transactions were not included, expected %d, got %d", numTxs*numBlocks, got)
|
||||||
}
|
}
|
||||||
|
|
@ -2846,6 +2900,7 @@ func TestSideImportPrunedBlocks(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
if n, err := chain.InsertChain(blocks); err != nil {
|
if n, err := chain.InsertChain(blocks); err != nil {
|
||||||
|
|
@ -2937,6 +2992,7 @@ func TestDeleteCreateRevert(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
if n, err := chain.InsertChain(blocks); err != nil {
|
if n, err := chain.InsertChain(blocks); err != nil {
|
||||||
|
|
@ -3047,6 +3103,7 @@ func TestDeleteRecreateSlots(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
if n, err := chain.InsertChain(blocks); err != nil {
|
if n, err := chain.InsertChain(blocks); err != nil {
|
||||||
|
|
@ -3124,6 +3181,7 @@ func TestDeleteRecreateAccount(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
if n, err := chain.InsertChain(blocks); err != nil {
|
if n, err := chain.InsertChain(blocks); err != nil {
|
||||||
|
|
@ -3295,6 +3353,7 @@ func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
var asHash = func(num int) common.Hash {
|
var asHash = func(num int) common.Hash {
|
||||||
|
|
@ -3426,6 +3485,7 @@ func TestInitThenFailCreateContract(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
statedb, _ := chain.State()
|
statedb, _ := chain.State()
|
||||||
|
|
@ -3508,6 +3568,7 @@ func TestEIP2718Transition(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
if n, err := chain.InsertChain(blocks); err != nil {
|
if n, err := chain.InsertChain(blocks); err != nil {
|
||||||
|
|
@ -3596,6 +3657,7 @@ func TestEIP1559Transition(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
if n, err := chain.InsertChain(blocks); err != nil {
|
if n, err := chain.InsertChain(blocks); err != nil {
|
||||||
|
|
@ -3674,8 +3736,7 @@ func TestEIP1559Transition(t *testing.T) {
|
||||||
// Tests the scenario the chain is requested to another point with the missing state.
|
// Tests the scenario the chain is requested to another point with the missing state.
|
||||||
// It expects the state is recovered and all relevant chain markers are set correctly.
|
// It expects the state is recovered and all relevant chain markers are set correctly.
|
||||||
func TestSetCanonical(t *testing.T) {
|
func TestSetCanonical(t *testing.T) {
|
||||||
//log.Root().SetHandler(log.LvlFilterHandler(log.LvlDebug, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
|
t.Parallel()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
address = crypto.PubkeyToAddress(key.PublicKey)
|
address = crypto.PubkeyToAddress(key.PublicKey)
|
||||||
|
|
@ -3688,6 +3749,9 @@ func TestSetCanonical(t *testing.T) {
|
||||||
signer = types.LatestSigner(gspec.Config)
|
signer = types.LatestSigner(gspec.Config)
|
||||||
engine = ethash.NewFaker()
|
engine = ethash.NewFaker()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//log.Root().SetHandler(log.LvlFilterHandler(log.LvlDebug, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
|
||||||
|
|
||||||
// Generate and import the canonical chain
|
// Generate and import the canonical chain
|
||||||
_, canon, _ := GenerateChainWithGenesis(gspec, engine, 2*int(DefaultCacheConfig.TriesInMemory), func(i int, gen *BlockGen) {
|
_, canon, _ := GenerateChainWithGenesis(gspec, engine, 2*int(DefaultCacheConfig.TriesInMemory), func(i int, gen *BlockGen) {
|
||||||
tx, err := types.SignTx(types.NewTransaction(gen.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key)
|
tx, err := types.SignTx(types.NewTransaction(gen.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key)
|
||||||
|
|
@ -3696,10 +3760,12 @@ func TestSetCanonical(t *testing.T) {
|
||||||
}
|
}
|
||||||
gen.AddTx(tx)
|
gen.AddTx(tx)
|
||||||
})
|
})
|
||||||
|
|
||||||
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil, nil)
|
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
if n, err := chain.InsertChain(canon); err != nil {
|
if n, err := chain.InsertChain(canon); err != nil {
|
||||||
|
|
@ -3714,12 +3780,14 @@ func TestSetCanonical(t *testing.T) {
|
||||||
}
|
}
|
||||||
gen.AddTx(tx)
|
gen.AddTx(tx)
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, block := range side {
|
for _, block := range side {
|
||||||
err := chain.InsertBlockWithoutSetHead(block)
|
err := chain.InsertBlockWithoutSetHead(block)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to insert into chain: %v", err)
|
t.Fatalf("Failed to insert into chain: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, block := range side {
|
for _, block := range side {
|
||||||
got := chain.GetBlockByHash(block.Hash())
|
got := chain.GetBlockByHash(block.Hash())
|
||||||
if got == nil {
|
if got == nil {
|
||||||
|
|
@ -3732,12 +3800,15 @@ func TestSetCanonical(t *testing.T) {
|
||||||
if chain.CurrentBlock().Hash() != head.Hash() {
|
if chain.CurrentBlock().Hash() != head.Hash() {
|
||||||
t.Fatalf("Unexpected block hash, want %x, got %x", head.Hash(), chain.CurrentBlock().Hash())
|
t.Fatalf("Unexpected block hash, want %x, got %x", head.Hash(), chain.CurrentBlock().Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
if chain.CurrentSnapBlock().Hash() != head.Hash() {
|
if chain.CurrentSnapBlock().Hash() != head.Hash() {
|
||||||
t.Fatalf("Unexpected fast block hash, want %x, got %x", head.Hash(), chain.CurrentSnapBlock().Hash())
|
t.Fatalf("Unexpected fast block hash, want %x, got %x", head.Hash(), chain.CurrentSnapBlock().Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
if chain.CurrentHeader().Hash() != head.Hash() {
|
if chain.CurrentHeader().Hash() != head.Hash() {
|
||||||
t.Fatalf("Unexpected head header, want %x, got %x", head.Hash(), chain.CurrentHeader().Hash())
|
t.Fatalf("Unexpected head header, want %x, got %x", head.Hash(), chain.CurrentHeader().Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
if !chain.HasState(head.Root()) {
|
if !chain.HasState(head.Root()) {
|
||||||
t.Fatalf("Lost block state %v %x", head.Number(), head.Hash())
|
t.Fatalf("Lost block state %v %x", head.Number(), head.Hash())
|
||||||
}
|
}
|
||||||
|
|
@ -3787,6 +3858,7 @@ func TestCanonicalHashMarker(t *testing.T) {
|
||||||
// markers [1, 11] should be updated
|
// markers [1, 11] should be updated
|
||||||
{10, 11},
|
{10, 11},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
var (
|
var (
|
||||||
gspec = &Genesis{
|
gspec = &Genesis{
|
||||||
|
|
@ -3796,6 +3868,7 @@ func TestCanonicalHashMarker(t *testing.T) {
|
||||||
}
|
}
|
||||||
engine = ethash.NewFaker()
|
engine = ethash.NewFaker()
|
||||||
)
|
)
|
||||||
|
|
||||||
_, forkA, _ := GenerateChainWithGenesis(gspec, engine, c.forkA, func(i int, gen *BlockGen) {})
|
_, forkA, _ := GenerateChainWithGenesis(gspec, engine, c.forkA, func(i int, gen *BlockGen) {})
|
||||||
_, forkB, _ := GenerateChainWithGenesis(gspec, engine, c.forkB, func(i int, gen *BlockGen) {})
|
_, forkB, _ := GenerateChainWithGenesis(gspec, engine, c.forkB, func(i int, gen *BlockGen) {})
|
||||||
|
|
||||||
|
|
@ -3804,10 +3877,12 @@ func TestCanonicalHashMarker(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert forkA and forkB, the canonical should on forkA still
|
// Insert forkA and forkB, the canonical should on forkA still
|
||||||
if n, err := chain.InsertChain(forkA); err != nil {
|
if n, err := chain.InsertChain(forkA); err != nil {
|
||||||
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n, err := chain.InsertChain(forkB); err != nil {
|
if n, err := chain.InsertChain(forkB); err != nil {
|
||||||
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
||||||
}
|
}
|
||||||
|
|
@ -3816,12 +3891,15 @@ func TestCanonicalHashMarker(t *testing.T) {
|
||||||
if chain.CurrentBlock().Hash() != head.Hash() {
|
if chain.CurrentBlock().Hash() != head.Hash() {
|
||||||
t.Fatalf("Unexpected block hash, want %x, got %x", head.Hash(), chain.CurrentBlock().Hash())
|
t.Fatalf("Unexpected block hash, want %x, got %x", head.Hash(), chain.CurrentBlock().Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
if chain.CurrentSnapBlock().Hash() != head.Hash() {
|
if chain.CurrentSnapBlock().Hash() != head.Hash() {
|
||||||
t.Fatalf("Unexpected fast block hash, want %x, got %x", head.Hash(), chain.CurrentSnapBlock().Hash())
|
t.Fatalf("Unexpected fast block hash, want %x, got %x", head.Hash(), chain.CurrentSnapBlock().Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
if chain.CurrentHeader().Hash() != head.Hash() {
|
if chain.CurrentHeader().Hash() != head.Hash() {
|
||||||
t.Fatalf("Unexpected head header, want %x, got %x", head.Hash(), chain.CurrentHeader().Hash())
|
t.Fatalf("Unexpected head header, want %x, got %x", head.Hash(), chain.CurrentHeader().Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
if !chain.HasState(head.Root()) {
|
if !chain.HasState(head.Root()) {
|
||||||
t.Fatalf("Lost block state %v %x", head.Number(), head.Hash())
|
t.Fatalf("Lost block state %v %x", head.Number(), head.Hash())
|
||||||
}
|
}
|
||||||
|
|
@ -3840,10 +3918,12 @@ func TestCanonicalHashMarker(t *testing.T) {
|
||||||
for i := 0; i < len(forkB); i++ {
|
for i := 0; i < len(forkB); i++ {
|
||||||
block := forkB[i]
|
block := forkB[i]
|
||||||
hash := chain.GetCanonicalHash(block.NumberU64())
|
hash := chain.GetCanonicalHash(block.NumberU64())
|
||||||
|
|
||||||
if hash != block.Hash() {
|
if hash != block.Hash() {
|
||||||
t.Fatalf("Unexpected canonical hash %d", block.NumberU64())
|
t.Fatalf("Unexpected canonical hash %d", block.NumberU64())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.forkA > c.forkB {
|
if c.forkA > c.forkB {
|
||||||
for i := uint64(c.forkB) + 1; i <= uint64(c.forkA); i++ {
|
for i := uint64(c.forkB) + 1; i <= uint64(c.forkA); i++ {
|
||||||
hash := chain.GetCanonicalHash(i)
|
hash := chain.GetCanonicalHash(i)
|
||||||
|
|
@ -3852,6 +3932,7 @@ func TestCanonicalHashMarker(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chain.Stop()
|
chain.Stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3873,6 +3954,7 @@ func TestTxIndexer(t *testing.T) {
|
||||||
engine = ethash.NewFaker()
|
engine = ethash.NewFaker()
|
||||||
nonce = uint64(0)
|
nonce = uint64(0)
|
||||||
)
|
)
|
||||||
|
|
||||||
_, blocks, receipts := GenerateChainWithGenesis(gspec, engine, 128, func(i int, gen *BlockGen) {
|
_, blocks, receipts := GenerateChainWithGenesis(gspec, engine, 128, func(i int, gen *BlockGen) {
|
||||||
tx, _ := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("0xdeadbeef"), big.NewInt(1000), params.TxGas, big.NewInt(10*params.InitialBaseFee), nil), types.HomesteadSigner{}, testBankKey)
|
tx, _ := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("0xdeadbeef"), big.NewInt(1000), params.TxGas, big.NewInt(10*params.InitialBaseFee), nil), types.HomesteadSigner{}, testBankKey)
|
||||||
gen.AddTx(tx)
|
gen.AddTx(tx)
|
||||||
|
|
@ -3885,12 +3967,15 @@ func TestTxIndexer(t *testing.T) {
|
||||||
if number == 0 {
|
if number == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
block := blocks[number-1]
|
block := blocks[number-1]
|
||||||
|
|
||||||
for _, tx := range block.Transactions() {
|
for _, tx := range block.Transactions() {
|
||||||
lookup := rawdb.ReadTxLookupEntry(db, tx.Hash())
|
lookup := rawdb.ReadTxLookupEntry(db, tx.Hash())
|
||||||
if exist && lookup == nil {
|
if exist && lookup == nil {
|
||||||
t.Fatalf("missing %d %x", number, tx.Hash().Hex())
|
t.Fatalf("missing %d %x", number, tx.Hash().Hex())
|
||||||
}
|
}
|
||||||
|
|
||||||
if !exist && lookup != nil {
|
if !exist && lookup != nil {
|
||||||
t.Fatalf("unexpected %d %x", number, tx.Hash().Hex())
|
t.Fatalf("unexpected %d %x", number, tx.Hash().Hex())
|
||||||
}
|
}
|
||||||
|
|
@ -3907,12 +3992,15 @@ func TestTxIndexer(t *testing.T) {
|
||||||
if tail == nil {
|
if tail == nil {
|
||||||
t.Fatal("Failed to write tx index tail")
|
t.Fatal("Failed to write tx index tail")
|
||||||
}
|
}
|
||||||
|
|
||||||
if *tail != expTail {
|
if *tail != expTail {
|
||||||
t.Fatalf("Unexpected tx index tail, want %v, got %d", expTail, *tail)
|
t.Fatalf("Unexpected tx index tail, want %v, got %d", expTail, *tail)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *tail != 0 {
|
if *tail != 0 {
|
||||||
verifyRange(db, 0, *tail-1, false)
|
verifyRange(db, 0, *tail-1, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyRange(db, *tail, 128, true)
|
verifyRange(db, *tail, 128, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4035,6 +4123,7 @@ func TestTxIndexer(t *testing.T) {
|
||||||
tailC: 65,
|
tailC: 65,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
frdir := t.TempDir()
|
frdir := t.TempDir()
|
||||||
db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false)
|
db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false)
|
||||||
|
|
@ -4177,6 +4266,7 @@ func TestTransientStorageReset(t *testing.T) {
|
||||||
ExtraEips: []int{1153}, // Enable transient storage EIP
|
ExtraEips: []int{1153}, // Enable transient storage EIP
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
code := append([]byte{
|
code := append([]byte{
|
||||||
// TLoad value with location 1
|
// TLoad value with location 1
|
||||||
byte(vm.PUSH1), 0x1,
|
byte(vm.PUSH1), 0x1,
|
||||||
|
|
@ -4251,8 +4341,10 @@ func TestTransientStorageReset(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to load state %v", err)
|
t.Fatalf("Failed to load state %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
loc := common.BytesToHash([]byte{1})
|
loc := common.BytesToHash([]byte{1})
|
||||||
slot := state.GetState(destAddress, loc)
|
slot := state.GetState(destAddress, loc)
|
||||||
|
|
||||||
if slot != (common.Hash{}) {
|
if slot != (common.Hash{}) {
|
||||||
t.Fatalf("Unexpected dirty storage slot")
|
t.Fatalf("Unexpected dirty storage slot")
|
||||||
}
|
}
|
||||||
|
|
@ -4335,9 +4427,11 @@ func TestEIP3651(t *testing.T) {
|
||||||
b.AddTx(tx)
|
b.AddTx(tx)
|
||||||
})
|
})
|
||||||
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{Tracer: logger.NewMarkdownLogger(&logger.Config{}, os.Stderr)}, nil, nil, nil)
|
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{Tracer: logger.NewMarkdownLogger(&logger.Config{}, os.Stderr)}, nil, nil, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create tester chain: %v", err)
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n, err := chain.InsertChain(blocks); err != nil {
|
if n, err := chain.InsertChain(blocks); err != nil {
|
||||||
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
||||||
}
|
}
|
||||||
|
|
@ -4347,6 +4441,7 @@ func TestEIP3651(t *testing.T) {
|
||||||
// 1+2: Ensure EIP-1559 access lists are accounted for via gas usage.
|
// 1+2: Ensure EIP-1559 access lists are accounted for via gas usage.
|
||||||
innerGas := vm.GasQuickStep*2 + params.ColdSloadCostEIP2929*2
|
innerGas := vm.GasQuickStep*2 + params.ColdSloadCostEIP2929*2
|
||||||
expectedGas := params.TxGas + 5*vm.GasFastestStep + vm.GasQuickStep + 100 + innerGas // 100 because 0xaaaa is in access list
|
expectedGas := params.TxGas + 5*vm.GasFastestStep + vm.GasQuickStep + 100 + innerGas // 100 because 0xaaaa is in access list
|
||||||
|
|
||||||
if block.GasUsed() != expectedGas {
|
if block.GasUsed() != expectedGas {
|
||||||
t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed())
|
t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed())
|
||||||
}
|
}
|
||||||
|
|
@ -4356,6 +4451,7 @@ func TestEIP3651(t *testing.T) {
|
||||||
// 3: Ensure that miner received only the tx's tip.
|
// 3: Ensure that miner received only the tx's tip.
|
||||||
actual := state.GetBalance(block.Coinbase())
|
actual := state.GetBalance(block.Coinbase())
|
||||||
expected := new(big.Int).SetUint64(block.GasUsed() * block.Transactions()[0].GasTipCap().Uint64())
|
expected := new(big.Int).SetUint64(block.GasUsed() * block.Transactions()[0].GasTipCap().Uint64())
|
||||||
|
|
||||||
if actual.Cmp(expected) != 0 {
|
if actual.Cmp(expected) != 0 {
|
||||||
t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
|
t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
|
||||||
}
|
}
|
||||||
|
|
@ -4363,6 +4459,7 @@ func TestEIP3651(t *testing.T) {
|
||||||
// 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee).
|
// 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee).
|
||||||
actual = new(big.Int).Sub(funds, state.GetBalance(addr1))
|
actual = new(big.Int).Sub(funds, state.GetBalance(addr1))
|
||||||
expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64()))
|
expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64()))
|
||||||
|
|
||||||
if actual.Cmp(expected) != 0 {
|
if actual.Cmp(expected) != 0 {
|
||||||
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
|
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,11 +99,14 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti
|
||||||
if b.gasPool == nil {
|
if b.gasPool == nil {
|
||||||
b.SetCoinbase(common.Address{})
|
b.SetCoinbase(common.Address{})
|
||||||
}
|
}
|
||||||
|
|
||||||
b.statedb.SetTxContext(tx.Hash(), len(b.txs))
|
b.statedb.SetTxContext(tx.Hash(), len(b.txs))
|
||||||
receipt, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vmConfig, nil)
|
receipt, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vmConfig, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.txs = append(b.txs, tx)
|
b.txs = append(b.txs, tx)
|
||||||
b.receipts = append(b.receipts, receipt)
|
b.receipts = append(b.receipts, receipt)
|
||||||
}
|
}
|
||||||
|
|
@ -226,6 +229,7 @@ func (b *BlockGen) AddWithdrawal(w *types.Withdrawal) uint64 {
|
||||||
cpy := *w
|
cpy := *w
|
||||||
cpy.Index = b.nextWithdrawalIndex()
|
cpy.Index = b.nextWithdrawalIndex()
|
||||||
b.withdrawals = append(b.withdrawals, &cpy)
|
b.withdrawals = append(b.withdrawals, &cpy)
|
||||||
|
|
||||||
return cpy.Index
|
return cpy.Index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,10 +238,12 @@ func (b *BlockGen) nextWithdrawalIndex() uint64 {
|
||||||
if len(b.withdrawals) != 0 {
|
if len(b.withdrawals) != 0 {
|
||||||
return b.withdrawals[len(b.withdrawals)-1].Index + 1
|
return b.withdrawals[len(b.withdrawals)-1].Index + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := b.i - 1; i >= 0; i-- {
|
for i := b.i - 1; i >= 0; i-- {
|
||||||
if wd := b.chain[i].Withdrawals(); len(wd) != 0 {
|
if wd := b.chain[i].Withdrawals(); len(wd) != 0 {
|
||||||
return wd[len(wd)-1].Index + 1
|
return wd[len(wd)-1].Index + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
// Correctly set the index if no parent had withdrawals.
|
// Correctly set the index if no parent had withdrawals.
|
||||||
if wd := b.parent.Withdrawals(); len(wd) != 0 {
|
if wd := b.parent.Withdrawals(); len(wd) != 0 {
|
||||||
|
|
@ -245,6 +251,7 @@ func (b *BlockGen) nextWithdrawalIndex() uint64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -334,6 +341,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("state write error: %v", err))
|
panic(fmt.Sprintf("state write error: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := statedb.Database().TrieDB().Commit(root, false); err != nil {
|
if err := statedb.Database().TrieDB().Commit(root, false); err != nil {
|
||||||
panic(fmt.Sprintf("trie write error: %v", err))
|
panic(fmt.Sprintf("trie write error: %v", err))
|
||||||
}
|
}
|
||||||
|
|
@ -360,10 +368,13 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
||||||
func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, gen func(int, *BlockGen)) (ethdb.Database, []*types.Block, []types.Receipts) {
|
func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, gen func(int, *BlockGen)) (ethdb.Database, []*types.Block, []types.Receipts) {
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
_, err := genesis.Commit(db, trie.NewDatabase(db))
|
_, err := genesis.Commit(db, trie.NewDatabase(db))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
blocks, receipts := GenerateChain(genesis.Config, genesis.ToBlock(), engine, db, n, gen)
|
blocks, receipts := GenerateChain(genesis.Config, genesis.ToBlock(), engine, db, n, gen)
|
||||||
|
|
||||||
return db, blocks, receipts
|
return db, blocks, receipts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -412,9 +423,11 @@ func makeHeaderChain(chainConfig *params.ChainConfig, parent *types.Header, n in
|
||||||
func makeHeaderChainWithGenesis(genesis *Genesis, n int, engine consensus.Engine, seed int) (ethdb.Database, []*types.Header) {
|
func makeHeaderChainWithGenesis(genesis *Genesis, n int, engine consensus.Engine, seed int) (ethdb.Database, []*types.Header) {
|
||||||
db, blocks := makeBlockChainWithGenesis(genesis, n, engine, seed)
|
db, blocks := makeBlockChainWithGenesis(genesis, n, engine, seed)
|
||||||
headers := make([]*types.Header, len(blocks))
|
headers := make([]*types.Header, len(blocks))
|
||||||
|
|
||||||
for i, block := range blocks {
|
for i, block := range blocks {
|
||||||
headers[i] = block.Header()
|
headers[i] = block.Header()
|
||||||
}
|
}
|
||||||
|
|
||||||
return db, headers
|
return db, headers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -423,6 +436,7 @@ func makeBlockChain(chainConfig *params.ChainConfig, parent *types.Block, n int,
|
||||||
blocks, _ := GenerateChain(chainConfig, parent, engine, db, n, func(i int, b *BlockGen) {
|
blocks, _ := GenerateChain(chainConfig, parent, engine, db, n, func(i int, b *BlockGen) {
|
||||||
b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)})
|
b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)})
|
||||||
})
|
})
|
||||||
|
|
||||||
return blocks
|
return blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -431,6 +445,7 @@ func makeBlockChainWithGenesis(genesis *Genesis, n int, engine consensus.Engine,
|
||||||
db, blocks, _ := GenerateChainWithGenesis(genesis, engine, n, func(i int, b *BlockGen) {
|
db, blocks, _ := GenerateChainWithGenesis(genesis, engine, n, func(i int, b *BlockGen) {
|
||||||
b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)})
|
b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)})
|
||||||
})
|
})
|
||||||
|
|
||||||
return db, blocks
|
return db, blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,18 +122,22 @@ func TestGenerateWithdrawalChain(t *testing.T) {
|
||||||
withdrawalIndex uint64
|
withdrawalIndex uint64
|
||||||
head = blockchain.CurrentBlock().Number.Uint64()
|
head = blockchain.CurrentBlock().Number.Uint64()
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < int(head); i++ {
|
for i := 0; i < int(head); i++ {
|
||||||
block := blockchain.GetBlockByNumber(uint64(i))
|
block := blockchain.GetBlockByNumber(uint64(i))
|
||||||
if block == nil {
|
if block == nil {
|
||||||
t.Fatalf("block %d not found", i)
|
t.Fatalf("block %d not found", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(block.Withdrawals()) == 0 {
|
if len(block.Withdrawals()) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for j := 0; j < len(block.Withdrawals()); j++ {
|
for j := 0; j < len(block.Withdrawals()); j++ {
|
||||||
if block.Withdrawals()[j].Index != withdrawalIndex {
|
if block.Withdrawals()[j].Index != withdrawalIndex {
|
||||||
t.Fatalf("withdrawal index %d does not equal expected index %d", block.Withdrawals()[j].Index, withdrawalIndex)
|
t.Fatalf("withdrawal index %d does not equal expected index %d", block.Withdrawals()[j].Index, withdrawalIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
withdrawalIndex += 1
|
withdrawalIndex += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,10 +83,13 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
||||||
if _, err := bc.InsertChain(blocks); err != nil {
|
if _, err := bc.InsertChain(blocks); err != nil {
|
||||||
t.Fatalf("failed to import contra-fork chain for expansion: %v", err)
|
t.Fatalf("failed to import contra-fork chain for expansion: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
|
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
|
||||||
t.Fatalf("failed to commit contra-fork head for expansion: %v", err)
|
t.Fatalf("failed to commit contra-fork head for expansion: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
bc.Stop()
|
bc.Stop()
|
||||||
|
|
||||||
blocks, _ = GenerateChain(&proConf, conBc.GetBlockByHash(conBc.CurrentBlock().Hash()), ethash.NewFaker(), genDb, 1, func(i int, gen *BlockGen) {})
|
blocks, _ = GenerateChain(&proConf, conBc.GetBlockByHash(conBc.CurrentBlock().Hash()), ethash.NewFaker(), genDb, 1, func(i int, gen *BlockGen) {})
|
||||||
if _, err := conBc.InsertChain(blocks); err == nil {
|
if _, err := conBc.InsertChain(blocks); err == nil {
|
||||||
t.Fatalf("contra-fork chain accepted pro-fork block: %v", blocks[0])
|
t.Fatalf("contra-fork chain accepted pro-fork block: %v", blocks[0])
|
||||||
|
|
@ -106,10 +109,13 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
||||||
if _, err := bc.InsertChain(blocks); err != nil {
|
if _, err := bc.InsertChain(blocks); err != nil {
|
||||||
t.Fatalf("failed to import pro-fork chain for expansion: %v", err)
|
t.Fatalf("failed to import pro-fork chain for expansion: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
|
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
|
||||||
t.Fatalf("failed to commit pro-fork head for expansion: %v", err)
|
t.Fatalf("failed to commit pro-fork head for expansion: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
bc.Stop()
|
bc.Stop()
|
||||||
|
|
||||||
blocks, _ = GenerateChain(&conConf, proBc.GetBlockByHash(proBc.CurrentBlock().Hash()), ethash.NewFaker(), genDb, 1, func(i int, gen *BlockGen) {})
|
blocks, _ = GenerateChain(&conConf, proBc.GetBlockByHash(proBc.CurrentBlock().Hash()), ethash.NewFaker(), genDb, 1, func(i int, gen *BlockGen) {})
|
||||||
if _, err := proBc.InsertChain(blocks); err == nil {
|
if _, err := proBc.InsertChain(blocks); err == nil {
|
||||||
t.Fatalf("pro-fork chain accepted contra-fork block: %v", blocks[0])
|
t.Fatalf("pro-fork chain accepted contra-fork block: %v", blocks[0])
|
||||||
|
|
@ -131,9 +137,11 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
||||||
if _, err := bc.InsertChain(blocks); err != nil {
|
if _, err := bc.InsertChain(blocks); err != nil {
|
||||||
t.Fatalf("failed to import contra-fork chain for expansion: %v", err)
|
t.Fatalf("failed to import contra-fork chain for expansion: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
|
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
|
||||||
t.Fatalf("failed to commit contra-fork head for expansion: %v", err)
|
t.Fatalf("failed to commit contra-fork head for expansion: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
blocks, _ = GenerateChain(&proConf, conBc.GetBlockByHash(conBc.CurrentBlock().Hash()), ethash.NewFaker(), genDb, 1, func(i int, gen *BlockGen) {})
|
blocks, _ = GenerateChain(&proConf, conBc.GetBlockByHash(conBc.CurrentBlock().Hash()), ethash.NewFaker(), genDb, 1, func(i int, gen *BlockGen) {})
|
||||||
if _, err := conBc.InsertChain(blocks); err != nil {
|
if _, err := conBc.InsertChain(blocks); err != nil {
|
||||||
t.Fatalf("contra-fork chain didn't accept pro-fork block post-fork: %v", err)
|
t.Fatalf("contra-fork chain didn't accept pro-fork block post-fork: %v", err)
|
||||||
|
|
@ -143,15 +151,19 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
||||||
defer bc.Stop()
|
defer bc.Stop()
|
||||||
|
|
||||||
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().Number.Uint64()))
|
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().Number.Uint64()))
|
||||||
|
|
||||||
for j := 0; j < len(blocks)/2; j++ {
|
for j := 0; j < len(blocks)/2; j++ {
|
||||||
blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[j]
|
blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[j]
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := bc.InsertChain(blocks); err != nil {
|
if _, err := bc.InsertChain(blocks); err != nil {
|
||||||
t.Fatalf("failed to import pro-fork chain for expansion: %v", err)
|
t.Fatalf("failed to import pro-fork chain for expansion: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
|
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
|
||||||
t.Fatalf("failed to commit pro-fork head for expansion: %v", err)
|
t.Fatalf("failed to commit pro-fork head for expansion: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
blocks, _ = GenerateChain(&conConf, proBc.GetBlockByHash(proBc.CurrentBlock().Hash()), ethash.NewFaker(), genDb, 1, func(i int, gen *BlockGen) {})
|
blocks, _ = GenerateChain(&conConf, proBc.GetBlockByHash(proBc.CurrentBlock().Hash()), ethash.NewFaker(), genDb, 1, func(i int, gen *BlockGen) {})
|
||||||
if _, err := proBc.InsertChain(blocks); err != nil {
|
if _, err := proBc.InsertChain(blocks); err != nil {
|
||||||
t.Fatalf("pro-fork chain didn't accept contra-fork block post-fork: %v", err)
|
t.Fatalf("pro-fork chain didn't accept contra-fork block post-fork: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ func (f *ForkChoice) ReorgNeeded(current *types.Header, extern *types.Header) (b
|
||||||
// Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf
|
// Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf
|
||||||
reorg := false
|
reorg := false
|
||||||
externNum, localNum := extern.Number.Uint64(), current.Number.Uint64()
|
externNum, localNum := extern.Number.Uint64(), current.Number.Uint64()
|
||||||
|
|
||||||
if externNum < localNum {
|
if externNum < localNum {
|
||||||
reorg = true
|
reorg = true
|
||||||
} else if externNum == localNum {
|
} else if externNum == localNum {
|
||||||
|
|
|
||||||
|
|
@ -71,27 +71,37 @@ type Genesis struct {
|
||||||
|
|
||||||
func ReadGenesis(db ethdb.Database) (*Genesis, error) {
|
func ReadGenesis(db ethdb.Database) (*Genesis, error) {
|
||||||
var genesis Genesis
|
var genesis Genesis
|
||||||
|
|
||||||
stored := rawdb.ReadCanonicalHash(db, 0)
|
stored := rawdb.ReadCanonicalHash(db, 0)
|
||||||
|
|
||||||
if (stored == common.Hash{}) {
|
if (stored == common.Hash{}) {
|
||||||
return nil, fmt.Errorf("invalid genesis hash in database: %x", stored)
|
return nil, fmt.Errorf("invalid genesis hash in database: %x", stored)
|
||||||
}
|
}
|
||||||
|
|
||||||
blob := rawdb.ReadGenesisStateSpec(db, stored)
|
blob := rawdb.ReadGenesisStateSpec(db, stored)
|
||||||
|
|
||||||
if blob == nil {
|
if blob == nil {
|
||||||
return nil, fmt.Errorf("genesis state missing from db")
|
return nil, fmt.Errorf("genesis state missing from db")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(blob) != 0 {
|
if len(blob) != 0 {
|
||||||
if err := genesis.Alloc.UnmarshalJSON(blob); err != nil {
|
if err := genesis.Alloc.UnmarshalJSON(blob); err != nil {
|
||||||
return nil, fmt.Errorf("could not unmarshal genesis state json: %s", err)
|
return nil, fmt.Errorf("could not unmarshal genesis state json: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
genesis.Config = rawdb.ReadChainConfig(db, stored)
|
genesis.Config = rawdb.ReadChainConfig(db, stored)
|
||||||
|
|
||||||
if genesis.Config == nil {
|
if genesis.Config == nil {
|
||||||
return nil, fmt.Errorf("genesis config missing from db")
|
return nil, fmt.Errorf("genesis config missing from db")
|
||||||
}
|
}
|
||||||
|
|
||||||
genesisBlock := rawdb.ReadBlock(db, stored, 0)
|
genesisBlock := rawdb.ReadBlock(db, stored, 0)
|
||||||
|
|
||||||
if genesisBlock == nil {
|
if genesisBlock == nil {
|
||||||
return nil, fmt.Errorf("genesis block missing from db")
|
return nil, fmt.Errorf("genesis block missing from db")
|
||||||
}
|
}
|
||||||
|
|
||||||
genesisHeader := genesisBlock.Header()
|
genesisHeader := genesisBlock.Header()
|
||||||
genesis.Nonce = genesisHeader.Nonce.Uint64()
|
genesis.Nonce = genesisHeader.Nonce.Uint64()
|
||||||
genesis.Timestamp = genesisHeader.Time
|
genesis.Timestamp = genesisHeader.Time
|
||||||
|
|
@ -136,6 +146,7 @@ func (ga *GenesisAlloc) deriveHash() (common.Hash, error) {
|
||||||
statedb.SetState(addr, key, value)
|
statedb.SetState(addr, key, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return statedb.Commit(false)
|
return statedb.Commit(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,14 +158,17 @@ func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database, blockhas
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for addr, account := range *ga {
|
for addr, account := range *ga {
|
||||||
statedb.AddBalance(addr, account.Balance)
|
statedb.AddBalance(addr, account.Balance)
|
||||||
statedb.SetCode(addr, account.Code)
|
statedb.SetCode(addr, account.Code)
|
||||||
statedb.SetNonce(addr, account.Nonce)
|
statedb.SetNonce(addr, account.Nonce)
|
||||||
|
|
||||||
for key, value := range account.Storage {
|
for key, value := range account.Storage {
|
||||||
statedb.SetState(addr, key, value)
|
statedb.SetState(addr, key, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
root, err := statedb.Commit(false)
|
root, err := statedb.Commit(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -170,6 +184,7 @@ func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database, blockhas
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
rawdb.WriteGenesisStateSpec(db, blockhash, blob)
|
rawdb.WriteGenesisStateSpec(db, blockhash, blob)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -178,6 +193,7 @@ func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database, blockhas
|
||||||
// hash and commits it into the provided trie database.
|
// hash and commits it into the provided trie database.
|
||||||
func CommitGenesisState(db ethdb.Database, triedb *trie.Database, blockhash common.Hash) error {
|
func CommitGenesisState(db ethdb.Database, triedb *trie.Database, blockhash common.Hash) error {
|
||||||
var alloc GenesisAlloc
|
var alloc GenesisAlloc
|
||||||
|
|
||||||
blob := rawdb.ReadGenesisStateSpec(db, blockhash)
|
blob := rawdb.ReadGenesisStateSpec(db, blockhash)
|
||||||
if len(blob) != 0 {
|
if len(blob) != 0 {
|
||||||
if err := alloc.UnmarshalJSON(blob); err != nil {
|
if err := alloc.UnmarshalJSON(blob); err != nil {
|
||||||
|
|
@ -206,6 +222,7 @@ func CommitGenesisState(db ethdb.Database, triedb *trie.Database, blockhash comm
|
||||||
return errors.New("not found")
|
return errors.New("not found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return alloc.flush(db, triedb, blockhash)
|
return alloc.flush(db, triedb, blockhash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -295,6 +312,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen
|
||||||
if genesis != nil && genesis.Config == nil {
|
if genesis != nil && genesis.Config == nil {
|
||||||
return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig
|
return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
applyOverrides := func(config *params.ChainConfig) {
|
applyOverrides := func(config *params.ChainConfig) {
|
||||||
if config != nil {
|
if config != nil {
|
||||||
// TODO marcello double check
|
// TODO marcello double check
|
||||||
|
|
@ -312,10 +330,12 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen
|
||||||
} else {
|
} else {
|
||||||
log.Info("Writing custom genesis block")
|
log.Info("Writing custom genesis block")
|
||||||
}
|
}
|
||||||
|
|
||||||
block, err := genesis.Commit(db, triedb)
|
block, err := genesis.Commit(db, triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return genesis.Config, common.Hash{}, err
|
return genesis.Config, common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
applyOverrides(genesis.Config)
|
applyOverrides(genesis.Config)
|
||||||
return genesis.Config, block.Hash(), nil
|
return genesis.Config, block.Hash(), nil
|
||||||
}
|
}
|
||||||
|
|
@ -331,10 +351,12 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen
|
||||||
if hash != stored {
|
if hash != stored {
|
||||||
return genesis.Config, hash, &GenesisMismatchError{stored, hash}
|
return genesis.Config, hash, &GenesisMismatchError{stored, hash}
|
||||||
}
|
}
|
||||||
|
|
||||||
block, err := genesis.Commit(db, triedb)
|
block, err := genesis.Commit(db, triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return genesis.Config, hash, err
|
return genesis.Config, hash, err
|
||||||
}
|
}
|
||||||
|
|
||||||
applyOverrides(genesis.Config)
|
applyOverrides(genesis.Config)
|
||||||
return genesis.Config, block.Hash(), nil
|
return genesis.Config, block.Hash(), nil
|
||||||
}
|
}
|
||||||
|
|
@ -357,6 +379,8 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen
|
||||||
rawdb.WriteChainConfig(db, stored, newcfg)
|
rawdb.WriteChainConfig(db, stored, newcfg)
|
||||||
return newcfg, stored, nil
|
return newcfg, stored, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nolint:errchkjson
|
||||||
storedData, _ := json.Marshal(storedcfg)
|
storedData, _ := json.Marshal(storedcfg)
|
||||||
// Special case: if a private network is being used (no genesis and also no
|
// Special case: if a private network is being used (no genesis and also no
|
||||||
// mainnet hash in the database), we must not apply the `configOrDefault`
|
// mainnet hash in the database), we must not apply the `configOrDefault`
|
||||||
|
|
@ -373,7 +397,9 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen
|
||||||
if head == nil {
|
if head == nil {
|
||||||
return newcfg, stored, fmt.Errorf("missing head header")
|
return newcfg, stored, fmt.Errorf("missing head header")
|
||||||
}
|
}
|
||||||
|
|
||||||
compatErr := storedcfg.CheckCompatible(newcfg, head.Number.Uint64(), head.Time)
|
compatErr := storedcfg.CheckCompatible(newcfg, head.Number.Uint64(), head.Time)
|
||||||
|
|
||||||
if compatErr != nil && ((head.Number.Uint64() != 0 && compatErr.RewindToBlock != 0) || (head.Time != 0 && compatErr.RewindToTime != 0)) {
|
if compatErr != nil && ((head.Number.Uint64() != 0 && compatErr.RewindToBlock != 0) || (head.Time != 0 && compatErr.RewindToTime != 0)) {
|
||||||
return newcfg, stored, compatErr
|
return newcfg, stored, compatErr
|
||||||
}
|
}
|
||||||
|
|
@ -413,6 +439,7 @@ func LoadCliqueConfig(db ethdb.Database, genesis *Genesis) (*params.CliqueConfig
|
||||||
if stored != (common.Hash{}) && genesis.ToBlock().Hash() != stored {
|
if stored != (common.Hash{}) && genesis.ToBlock().Hash() != stored {
|
||||||
return nil, &GenesisMismatchError{stored, genesis.ToBlock().Hash()}
|
return nil, &GenesisMismatchError{stored, genesis.ToBlock().Hash()}
|
||||||
}
|
}
|
||||||
|
|
||||||
return genesis.Config.Clique, nil
|
return genesis.Config.Clique, nil
|
||||||
}
|
}
|
||||||
// There is no stored chain config and no new config provided,
|
// There is no stored chain config and no new config provided,
|
||||||
|
|
@ -478,11 +505,14 @@ func (g *Genesis) ToBlock() *types.Block {
|
||||||
head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee)
|
head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var withdrawals []*types.Withdrawal
|
var withdrawals []*types.Withdrawal
|
||||||
|
|
||||||
if g.Config != nil && g.Config.IsShanghai(g.Timestamp) {
|
if g.Config != nil && g.Config.IsShanghai(g.Timestamp) {
|
||||||
head.WithdrawalsHash = &types.EmptyWithdrawalsHash
|
head.WithdrawalsHash = &types.EmptyWithdrawalsHash
|
||||||
withdrawals = make([]*types.Withdrawal, 0)
|
withdrawals = make([]*types.Withdrawal, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.NewBlock(head, nil, nil, nil, trie.NewStackTrie(nil)).WithWithdrawals(withdrawals)
|
return types.NewBlock(head, nil, nil, nil, trie.NewStackTrie(nil)).WithWithdrawals(withdrawals)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -500,6 +530,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *trie.Database) (*types.Block
|
||||||
if err := config.CheckConfigForkOrder(); err != nil {
|
if err := config.CheckConfigForkOrder(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Clique != nil && len(block.Extra()) < 32+crypto.SignatureLength {
|
if config.Clique != nil && len(block.Extra()) < 32+crypto.SignatureLength {
|
||||||
return nil, errors.New("can't start clique chain without signers")
|
return nil, errors.New("can't start clique chain without signers")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ func TestInvalidCliqueConfig(t *testing.T) {
|
||||||
block := DefaultGoerliGenesisBlock()
|
block := DefaultGoerliGenesisBlock()
|
||||||
block.ExtraData = []byte{}
|
block.ExtraData = []byte{}
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
|
|
||||||
if _, err := block.Commit(db, trie.NewDatabase(db)); err == nil {
|
if _, err := block.Commit(db, trie.NewDatabase(db)); err == nil {
|
||||||
t.Fatal("Expected error on invalid clique config")
|
t.Fatal("Expected error on invalid clique config")
|
||||||
}
|
}
|
||||||
|
|
@ -222,6 +223,8 @@ func TestReadWriteGenesisAlloc(t *testing.T) {
|
||||||
}
|
}
|
||||||
hash, _ = alloc.deriveHash()
|
hash, _ = alloc.deriveHash()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// nolint : errchkjson
|
||||||
blob, _ := json.Marshal(alloc)
|
blob, _ := json.Marshal(alloc)
|
||||||
rawdb.WriteGenesisStateSpec(db, hash, blob)
|
rawdb.WriteGenesisStateSpec(db, hash, blob)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -400,6 +400,7 @@ func (hc *HeaderChain) InsertHeaderChain(chain []*types.Header, start time.Time,
|
||||||
if res.ignored > 0 {
|
if res.ignored > 0 {
|
||||||
context = append(context, []interface{}{"ignored", res.ignored}...)
|
context = append(context, []interface{}{"ignored", res.ignored}...)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("Imported new block headers", context...)
|
log.Debug("Imported new block headers", context...)
|
||||||
return res.status, err
|
return res.status, err
|
||||||
}
|
}
|
||||||
|
|
@ -531,6 +532,7 @@ func (hc *HeaderChain) GetHeadersFrom(number, count uint64) []rlp.RawValue {
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
rlpData, _ := rlp.EncodeToBytes(header)
|
rlpData, _ := rlp.EncodeToBytes(header)
|
||||||
headers = append(headers, rlpData)
|
headers = append(headers, rlpData)
|
||||||
hash = header.ParentHash
|
hash = header.ParentHash
|
||||||
|
|
@ -607,12 +609,15 @@ func (hc *HeaderChain) setHead(headBlock uint64, headTime uint64, updateFn Updat
|
||||||
batch = hc.chainDb.NewBatch()
|
batch = hc.chainDb.NewBatch()
|
||||||
origin = true
|
origin = true
|
||||||
)
|
)
|
||||||
|
|
||||||
done := func(header *types.Header) bool {
|
done := func(header *types.Header) bool {
|
||||||
if headTime > 0 {
|
if headTime > 0 {
|
||||||
return header.Time <= headTime
|
return header.Time <= headTime
|
||||||
}
|
}
|
||||||
|
|
||||||
return header.Number.Uint64() <= headBlock
|
return header.Number.Uint64() <= headBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
for hdr := hc.CurrentHeader(); hdr != nil && !done(hdr); hdr = hc.CurrentHeader() {
|
for hdr := hc.CurrentHeader(); hdr != nil && !done(hdr); hdr = hc.CurrentHeader() {
|
||||||
num := hdr.Number.Uint64()
|
num := hdr.Number.Uint64()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,5 +101,6 @@ func (cacher *txSenderCacher) RecoverFromBlocks(signer types.Signer, blocks []*t
|
||||||
for _, block := range blocks {
|
for _, block := range blocks {
|
||||||
txs = append(txs, block.Transactions()...)
|
txs = append(txs, block.Transactions()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
cacher.Recover(signer, txs)
|
cacher.Recover(signer, txs)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return // Also invalid block, bail out
|
return // Also invalid block, bail out
|
||||||
}
|
}
|
||||||
|
|
||||||
statedb.SetTxContext(tx.Hash(), i)
|
statedb.SetTxContext(tx.Hash(), i)
|
||||||
if err := precacheTransaction(msg, p.config, gaspool, statedb, header, evm); err != nil {
|
if err := precacheTransaction(msg, p.config, gaspool, statedb, header, evm); err != nil {
|
||||||
return // Ugh, something went horribly wrong, bail out
|
return // Ugh, something went horribly wrong, bail out
|
||||||
|
|
|
||||||
|
|
@ -82,10 +82,12 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msg, err := TransactionToMessage(tx, types.MakeSigner(p.config, header.Number), header.BaseFee)
|
msg, err := TransactionToMessage(tx, types.MakeSigner(p.config, header.Number), header.BaseFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
|
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
statedb.SetTxContext(tx.Hash(), i)
|
statedb.SetTxContext(tx.Hash(), i)
|
||||||
receipt, err := applyTransaction(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv, interruptCtx)
|
receipt, err := applyTransaction(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv, interruptCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -207,5 +209,6 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
|
||||||
// Create a new context to be used in the EVM environment
|
// Create a new context to be used in the EVM environment
|
||||||
blockContext := NewEVMBlockContext(header, bc, author)
|
blockContext := NewEVMBlockContext(header, bc, author)
|
||||||
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg)
|
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg)
|
||||||
|
|
||||||
return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv, interruptCtx)
|
return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv, interruptCtx)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ func TestStateProcessorErrors(t *testing.T) {
|
||||||
}), signer, key1)
|
}), signer, key1)
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
var mkDynamicCreationTx = func(nonce uint64, gasLimit uint64, gasTipCap, gasFeeCap *big.Int, data []byte) *types.Transaction {
|
var mkDynamicCreationTx = func(nonce uint64, gasLimit uint64, gasTipCap, gasFeeCap *big.Int, data []byte) *types.Transaction {
|
||||||
tx, _ := types.SignTx(types.NewTx(&types.DynamicFeeTx{
|
tx, _ := types.SignTx(types.NewTx(&types.DynamicFeeTx{
|
||||||
Nonce: nonce,
|
Nonce: nonce,
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation b
|
||||||
} else {
|
} else {
|
||||||
gas = params.TxGas
|
gas = params.TxGas
|
||||||
}
|
}
|
||||||
|
|
||||||
dataLen := uint64(len(data))
|
dataLen := uint64(len(data))
|
||||||
// Bump the required gas by the amount of transactional data
|
// Bump the required gas by the amount of transactional data
|
||||||
if dataLen > 0 {
|
if dataLen > 0 {
|
||||||
|
|
@ -108,6 +109,7 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation b
|
||||||
if (math.MaxUint64-gas)/params.InitCodeWordGas < lenWords {
|
if (math.MaxUint64-gas)/params.InitCodeWordGas < lenWords {
|
||||||
return 0, ErrGasUintOverflow
|
return 0, ErrGasUintOverflow
|
||||||
}
|
}
|
||||||
|
|
||||||
gas += lenWords * params.InitCodeWordGas
|
gas += lenWords * params.InitCodeWordGas
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -165,8 +167,10 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In
|
||||||
if baseFee != nil {
|
if baseFee != nil {
|
||||||
msg.GasPrice = cmath.BigMin(msg.GasPrice.Add(msg.GasTipCap, baseFee), msg.GasFeeCap)
|
msg.GasPrice = cmath.BigMin(msg.GasPrice.Add(msg.GasTipCap, baseFee), msg.GasFeeCap)
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
msg.From, err = types.Sender(s, tx)
|
msg.From, err = types.Sender(s, tx)
|
||||||
|
|
||||||
return msg, err
|
return msg, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -239,6 +243,7 @@ func (st *StateTransition) to() common.Address {
|
||||||
if st.msg == nil || st.msg.To == nil /* contract creation */ {
|
if st.msg == nil || st.msg.To == nil /* contract creation */ {
|
||||||
return common.Address{}
|
return common.Address{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return *st.msg.To
|
return *st.msg.To
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -246,17 +251,21 @@ func (st *StateTransition) buyGas() error {
|
||||||
mgval := new(big.Int).SetUint64(st.msg.GasLimit)
|
mgval := new(big.Int).SetUint64(st.msg.GasLimit)
|
||||||
mgval = mgval.Mul(mgval, st.msg.GasPrice)
|
mgval = mgval.Mul(mgval, st.msg.GasPrice)
|
||||||
balanceCheck := mgval
|
balanceCheck := mgval
|
||||||
|
|
||||||
if st.msg.GasFeeCap != nil {
|
if st.msg.GasFeeCap != nil {
|
||||||
balanceCheck = new(big.Int).SetUint64(st.msg.GasLimit)
|
balanceCheck = new(big.Int).SetUint64(st.msg.GasLimit)
|
||||||
balanceCheck = balanceCheck.Mul(balanceCheck, st.msg.GasFeeCap)
|
balanceCheck = balanceCheck.Mul(balanceCheck, st.msg.GasFeeCap)
|
||||||
balanceCheck.Add(balanceCheck, st.msg.Value)
|
balanceCheck.Add(balanceCheck, st.msg.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
if have, want := st.state.GetBalance(st.msg.From), balanceCheck; have.Cmp(want) < 0 {
|
if have, want := st.state.GetBalance(st.msg.From), balanceCheck; have.Cmp(want) < 0 {
|
||||||
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want)
|
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := st.gp.SubGas(st.msg.GasLimit); err != nil {
|
if err := st.gp.SubGas(st.msg.GasLimit); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
st.gasRemaining += st.msg.GasLimit
|
st.gasRemaining += st.msg.GasLimit
|
||||||
|
|
||||||
st.initialGas = st.msg.GasLimit
|
st.initialGas = st.msg.GasLimit
|
||||||
|
|
@ -296,10 +305,12 @@ func (st *StateTransition) preCheck() error {
|
||||||
return fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh,
|
return fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh,
|
||||||
msg.From.Hex(), l)
|
msg.From.Hex(), l)
|
||||||
}
|
}
|
||||||
|
|
||||||
if l := msg.GasTipCap.BitLen(); l > 256 {
|
if l := msg.GasTipCap.BitLen(); l > 256 {
|
||||||
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas bit length: %d", ErrTipVeryHigh,
|
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas bit length: %d", ErrTipVeryHigh,
|
||||||
msg.From.Hex(), l)
|
msg.From.Hex(), l)
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg.GasFeeCap.Cmp(msg.GasTipCap) < 0 {
|
if msg.GasFeeCap.Cmp(msg.GasTipCap) < 0 {
|
||||||
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s", ErrTipAboveFeeCap,
|
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s", ErrTipAboveFeeCap,
|
||||||
msg.From.Hex(), msg.GasTipCap, msg.GasFeeCap)
|
msg.From.Hex(), msg.GasTipCap, msg.GasFeeCap)
|
||||||
|
|
@ -327,7 +338,9 @@ func (st *StateTransition) preCheck() error {
|
||||||
// nil evm execution result.
|
// nil evm execution result.
|
||||||
func (st *StateTransition) TransitionDb(interruptCtx context.Context) (*ExecutionResult, error) {
|
func (st *StateTransition) TransitionDb(interruptCtx context.Context) (*ExecutionResult, error) {
|
||||||
input1 := st.state.GetBalance(st.msg.From)
|
input1 := st.state.GetBalance(st.msg.From)
|
||||||
|
|
||||||
var input2 *big.Int
|
var input2 *big.Int
|
||||||
|
|
||||||
if !st.noFeeBurnAndTip {
|
if !st.noFeeBurnAndTip {
|
||||||
input2 = st.state.GetBalance(st.evm.Context.Coinbase)
|
input2 = st.state.GetBalance(st.evm.Context.Coinbase)
|
||||||
}
|
}
|
||||||
|
|
@ -348,6 +361,7 @@ func (st *StateTransition) TransitionDb(interruptCtx context.Context) (*Executio
|
||||||
|
|
||||||
if tracer := st.evm.Config.Tracer; tracer != nil {
|
if tracer := st.evm.Config.Tracer; tracer != nil {
|
||||||
tracer.CaptureTxStart(st.initialGas)
|
tracer.CaptureTxStart(st.initialGas)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
tracer.CaptureTxEnd(st.gasRemaining)
|
tracer.CaptureTxEnd(st.gasRemaining)
|
||||||
}()
|
}()
|
||||||
|
|
@ -365,9 +379,11 @@ func (st *StateTransition) TransitionDb(interruptCtx context.Context) (*Executio
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if st.gasRemaining < gas {
|
if st.gasRemaining < gas {
|
||||||
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gasRemaining, gas)
|
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gasRemaining, gas)
|
||||||
}
|
}
|
||||||
|
|
||||||
st.gasRemaining -= gas
|
st.gasRemaining -= gas
|
||||||
|
|
||||||
// Check clause 6
|
// Check clause 6
|
||||||
|
|
@ -406,7 +422,9 @@ func (st *StateTransition) TransitionDb(interruptCtx context.Context) (*Executio
|
||||||
// After EIP-3529: refunds are capped to gasUsed / 5
|
// After EIP-3529: refunds are capped to gasUsed / 5
|
||||||
st.refundGas(params.RefundQuotientEIP3529)
|
st.refundGas(params.RefundQuotientEIP3529)
|
||||||
}
|
}
|
||||||
|
|
||||||
effectiveTip := msg.GasPrice
|
effectiveTip := msg.GasPrice
|
||||||
|
|
||||||
if rules.IsLondon {
|
if rules.IsLondon {
|
||||||
effectiveTip = cmath.BigMin(msg.GasTipCap, new(big.Int).Sub(msg.GasFeeCap, st.evm.Context.BaseFee))
|
effectiveTip = cmath.BigMin(msg.GasTipCap, new(big.Int).Sub(msg.GasFeeCap, st.evm.Context.BaseFee))
|
||||||
}
|
}
|
||||||
|
|
@ -430,12 +448,15 @@ func (st *StateTransition) TransitionDb(interruptCtx context.Context) (*Executio
|
||||||
if rules.IsLondon {
|
if rules.IsLondon {
|
||||||
burntContractAddress := common.HexToAddress(st.evm.ChainConfig().Bor.CalculateBurntContract(st.evm.Context.BlockNumber.Uint64()))
|
burntContractAddress := common.HexToAddress(st.evm.ChainConfig().Bor.CalculateBurntContract(st.evm.Context.BlockNumber.Uint64()))
|
||||||
burnAmount := new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.evm.Context.BaseFee)
|
burnAmount := new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.evm.Context.BaseFee)
|
||||||
|
|
||||||
if !st.noFeeBurnAndTip {
|
if !st.noFeeBurnAndTip {
|
||||||
st.state.AddBalance(burntContractAddress, burnAmount)
|
st.state.AddBalance(burntContractAddress, burnAmount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !st.noFeeBurnAndTip {
|
if !st.noFeeBurnAndTip {
|
||||||
st.state.AddBalance(st.evm.Context.Coinbase, amount)
|
st.state.AddBalance(st.evm.Context.Coinbase, amount)
|
||||||
|
|
||||||
output1 := new(big.Int).SetBytes(input1.Bytes())
|
output1 := new(big.Int).SetBytes(input1.Bytes())
|
||||||
output2 := new(big.Int).SetBytes(input2.Bytes())
|
output2 := new(big.Int).SetBytes(input2.Bytes())
|
||||||
|
|
||||||
|
|
@ -472,6 +493,7 @@ func (st *StateTransition) refundGas(refundQuotient uint64) {
|
||||||
if refund > st.state.GetRefund() {
|
if refund > st.state.GetRefund() {
|
||||||
refund = st.state.GetRefund()
|
refund = st.state.GetRefund()
|
||||||
}
|
}
|
||||||
|
|
||||||
st.gasRemaining += refund
|
st.gasRemaining += refund
|
||||||
|
|
||||||
// Return ETH for remaining gas, exchanged at the original rate.
|
// Return ETH for remaining gas, exchanged at the original rate.
|
||||||
|
|
|
||||||
|
|
@ -1984,10 +1984,12 @@ func TestIssue23496(t *testing.T) {
|
||||||
SnapshotWait: true,
|
SnapshotWait: true,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
chain, err := core.NewBlockChain(db, config, gspec, nil, engine, vm.Config{}, nil, nil, nil)
|
chain, err := core.NewBlockChain(db, config, gspec, nil, engine, vm.Config{}, nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create chain: %v", err)
|
t.Fatalf("Failed to create chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, 4, func(i int, b *core.BlockGen) {
|
_, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, 4, func(i int, b *core.BlockGen) {
|
||||||
b.SetCoinbase(common.Address{0x02})
|
b.SetCoinbase(common.Address{0x02})
|
||||||
b.SetDifficulty(big.NewInt(1000000))
|
b.SetDifficulty(big.NewInt(1000000))
|
||||||
|
|
@ -1997,14 +1999,17 @@ func TestIssue23496(t *testing.T) {
|
||||||
if _, err := chain.InsertChain(blocks[:1]); err != nil {
|
if _, err := chain.InsertChain(blocks[:1]); err != nil {
|
||||||
t.Fatalf("Failed to import canonical chain start: %v", err)
|
t.Fatalf("Failed to import canonical chain start: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = chain.StateCache().TrieDB().Commit(blocks[0].Root(), true)
|
err = chain.StateCache().TrieDB().Commit(blocks[0].Root(), true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("on trieDB.Commit", err)
|
t.Fatal("on trieDB.Commit", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert block B2 and commit the snapshot into disk
|
// Insert block B2 and commit the snapshot into disk
|
||||||
if _, err := chain.InsertChain(blocks[1:2]); err != nil {
|
if _, err := chain.InsertChain(blocks[1:2]); err != nil {
|
||||||
t.Fatalf("Failed to import canonical chain start: %v", err)
|
t.Fatalf("Failed to import canonical chain start: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := chain.Snaps().Cap(blocks[1].Root(), 0); err != nil {
|
if err := chain.Snaps().Cap(blocks[1].Root(), 0); err != nil {
|
||||||
t.Fatalf("Failed to flatten snapshots: %v", err)
|
t.Fatalf("Failed to flatten snapshots: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -2035,20 +2040,24 @@ func TestIssue23496(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to reopen persistent database: %v", err)
|
t.Fatalf("Failed to reopen persistent database: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
chain, err = core.NewBlockChain(db, nil, gspec, nil, engine, vm.Config{}, nil, nil, nil)
|
chain, err = core.NewBlockChain(db, nil, gspec, nil, engine, vm.Config{}, nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to recreate chain: %v", err)
|
t.Fatalf("Failed to recreate chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
if head := chain.CurrentHeader(); head.Number.Uint64() != uint64(4) {
|
if head := chain.CurrentHeader(); head.Number.Uint64() != uint64(4) {
|
||||||
t.Errorf("Head header mismatch: have %d, want %d", head.Number, 4)
|
t.Errorf("Head header mismatch: have %d, want %d", head.Number, 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
if head := chain.CurrentSnapBlock(); head.Number.Uint64() != uint64(4) {
|
if head := chain.CurrentSnapBlock(); head.Number.Uint64() != uint64(4) {
|
||||||
t.Errorf("Head fast block mismatch: have %d, want %d", head.Number, uint64(4))
|
t.Errorf("Head fast block mismatch: have %d, want %d", head.Number, uint64(4))
|
||||||
}
|
}
|
||||||
|
|
||||||
if head := chain.CurrentBlock(); head.Number.Uint64() != uint64(1) {
|
if head := chain.CurrentBlock(); head.Number.Uint64() != uint64(1) {
|
||||||
t.Errorf("Head block mismatch: have %d, want %d", head.Number, uint64(1))
|
t.Errorf("Head block mismatch: have %d, want %d", head.Number, uint64(1))
|
||||||
}
|
}
|
||||||
|
|
@ -2057,12 +2066,15 @@ func TestIssue23496(t *testing.T) {
|
||||||
if _, err := chain.InsertChain(blocks[1:]); err != nil {
|
if _, err := chain.InsertChain(blocks[1:]); err != nil {
|
||||||
t.Fatalf("Failed to import canonical chain tail: %v", err)
|
t.Fatalf("Failed to import canonical chain tail: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if head := chain.CurrentHeader(); head.Number.Uint64() != uint64(4) {
|
if head := chain.CurrentHeader(); head.Number.Uint64() != uint64(4) {
|
||||||
t.Errorf("Head header mismatch: have %d, want %d", head.Number, 4)
|
t.Errorf("Head header mismatch: have %d, want %d", head.Number, 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
if head := chain.CurrentSnapBlock(); head.Number.Uint64() != uint64(4) {
|
if head := chain.CurrentSnapBlock(); head.Number.Uint64() != uint64(4) {
|
||||||
t.Errorf("Head fast block mismatch: have %d, want %d", head.Number, uint64(4))
|
t.Errorf("Head fast block mismatch: have %d, want %d", head.Number, uint64(4))
|
||||||
}
|
}
|
||||||
|
|
||||||
if head := chain.CurrentBlock(); head.Number.Uint64() != uint64(4) {
|
if head := chain.CurrentBlock(); head.Number.Uint64() != uint64(4) {
|
||||||
t.Errorf("Head block mismatch: have %d, want %d", head.Number, uint64(4))
|
t.Errorf("Head block mismatch: have %d, want %d", head.Number, uint64(4))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1984,10 +1984,12 @@ func testSetHead(t *testing.T, tt *rewindTest, snapshots bool) {
|
||||||
config.SnapshotLimit = 256
|
config.SnapshotLimit = 256
|
||||||
config.SnapshotWait = true
|
config.SnapshotWait = true
|
||||||
}
|
}
|
||||||
|
|
||||||
chain, err := core.NewBlockChain(db, config, gspec, nil, engine, vm.Config{}, nil, nil, nil)
|
chain, err := core.NewBlockChain(db, config, gspec, nil, engine, vm.Config{}, nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create chain: %v", err)
|
t.Fatalf("Failed to create chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
// If sidechain blocks are needed, make a light chain and import it
|
// If sidechain blocks are needed, make a light chain and import it
|
||||||
|
|
@ -2000,6 +2002,7 @@ func testSetHead(t *testing.T, tt *rewindTest, snapshots bool) {
|
||||||
t.Fatalf("Failed to import side chain: %v", err)
|
t.Fatalf("Failed to import side chain: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
canonblocks, _ := core.GenerateChain(gspec.Config, gspec.ToBlock(), engine, rawdb.NewMemoryDatabase(), tt.canonicalBlocks, func(i int, b *core.BlockGen) {
|
canonblocks, _ := core.GenerateChain(gspec.Config, gspec.ToBlock(), engine, rawdb.NewMemoryDatabase(), tt.canonicalBlocks, func(i int, b *core.BlockGen) {
|
||||||
b.SetCoinbase(common.Address{0x02})
|
b.SetCoinbase(common.Address{0x02})
|
||||||
b.SetDifficulty(big.NewInt(1000000))
|
b.SetDifficulty(big.NewInt(1000000))
|
||||||
|
|
@ -2052,9 +2055,11 @@ func testSetHead(t *testing.T, tt *rewindTest, snapshots bool) {
|
||||||
if head := chain.CurrentHeader(); head.Number.Uint64() != tt.expHeadHeader {
|
if head := chain.CurrentHeader(); head.Number.Uint64() != tt.expHeadHeader {
|
||||||
t.Errorf("Head header mismatch: have %d, want %d", head.Number, tt.expHeadHeader)
|
t.Errorf("Head header mismatch: have %d, want %d", head.Number, tt.expHeadHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
if head := chain.CurrentSnapBlock(); head.Number.Uint64() != tt.expHeadFastBlock {
|
if head := chain.CurrentSnapBlock(); head.Number.Uint64() != tt.expHeadFastBlock {
|
||||||
t.Errorf("Head fast block mismatch: have %d, want %d", head.Number, tt.expHeadFastBlock)
|
t.Errorf("Head fast block mismatch: have %d, want %d", head.Number, tt.expHeadFastBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
if head := chain.CurrentBlock(); head.Number.Uint64() != tt.expHeadBlock {
|
if head := chain.CurrentBlock(); head.Number.Uint64() != tt.expHeadBlock {
|
||||||
t.Errorf("Head block mismatch: have %d, want %d", head.Number, tt.expHeadBlock)
|
t.Errorf("Head block mismatch: have %d, want %d", head.Number, tt.expHeadBlock)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,10 +84,12 @@ func (basic *snapshotTestBasic) prepare(t *testing.T) (*core.BlockChain, []*type
|
||||||
// will happen during the block insertion.
|
// will happen during the block insertion.
|
||||||
cacheConfig = core.DefaultCacheConfig
|
cacheConfig = core.DefaultCacheConfig
|
||||||
)
|
)
|
||||||
|
|
||||||
chain, err := core.NewBlockChain(db, cacheConfig, gspec, nil, engine, vm.Config{}, nil, nil, nil)
|
chain, err := core.NewBlockChain(db, cacheConfig, gspec, nil, engine, vm.Config{}, nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create chain: %v", err)
|
t.Fatalf("Failed to create chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
genDb, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, basic.chainBlocks, func(i int, b *core.BlockGen) {})
|
genDb, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, basic.chainBlocks, func(i int, b *core.BlockGen) {})
|
||||||
|
|
||||||
// Insert the blocks with configured settings.
|
// Insert the blocks with configured settings.
|
||||||
|
|
@ -326,6 +328,7 @@ func (snaptest *gappedSnapshotTest) test(t *testing.T) {
|
||||||
TrieTimeLimit: 5 * time.Minute,
|
TrieTimeLimit: 5 * time.Minute,
|
||||||
SnapshotLimit: 0,
|
SnapshotLimit: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
newchain, err := core.NewBlockChain(snaptest.db, cacheConfig, snaptest.gspec, nil, snaptest.engine, vm.Config{}, nil, nil, nil)
|
newchain, err := core.NewBlockChain(snaptest.db, cacheConfig, snaptest.gspec, nil, snaptest.engine, vm.Config{}, nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to recreate chain: %v", err)
|
t.Fatalf("Failed to recreate chain: %v", err)
|
||||||
|
|
@ -401,6 +404,7 @@ func (snaptest *wipeCrashSnapshotTest) test(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to recreate chain: %v", err)
|
t.Fatalf("Failed to recreate chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newBlocks, _ := core.GenerateChain(params.TestChainConfig, blocks[len(blocks)-1], snaptest.engine, snaptest.genDb, snaptest.newBlocks, func(i int, b *core.BlockGen) {})
|
newBlocks, _ := core.GenerateChain(params.TestChainConfig, blocks[len(blocks)-1], snaptest.engine, snaptest.genDb, snaptest.newBlocks, func(i int, b *core.BlockGen) {})
|
||||||
newchain.InsertChain(newBlocks)
|
newchain.InsertChain(newBlocks)
|
||||||
newchain.Stop()
|
newchain.Stop()
|
||||||
|
|
@ -422,6 +426,7 @@ func (snaptest *wipeCrashSnapshotTest) test(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to recreate chain: %v", err)
|
t.Fatalf("Failed to recreate chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer newchain.Stop()
|
defer newchain.Stop()
|
||||||
snaptest.verify(t, newchain, blocks)
|
snaptest.verify(t, newchain, blocks)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4705,15 +4705,18 @@ func BenchmarkMultiAccountBatchInsert(b *testing.B) {
|
||||||
defer pool.Stop()
|
defer pool.Stop()
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
batches := make(types.Transactions, b.N)
|
batches := make(types.Transactions, b.N)
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
key, _ := crypto.GenerateKey()
|
key, _ := crypto.GenerateKey()
|
||||||
account := crypto.PubkeyToAddress(key.PublicKey)
|
account := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
pool.currentState.AddBalance(account, big.NewInt(1000000))
|
pool.currentState.AddBalance(account, big.NewInt(1000000))
|
||||||
|
|
||||||
tx := transaction(uint64(0), 100000, key)
|
tx := transaction(uint64(0), 100000, key)
|
||||||
batches[i] = tx
|
batches[i] = tx
|
||||||
}
|
}
|
||||||
// Benchmark importing the transactions into the queue
|
// Benchmark importing the transactions into the queue
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
||||||
for _, tx := range batches {
|
for _, tx := range batches {
|
||||||
pool.AddRemotesSync([]*types.Transaction{tx})
|
pool.AddRemotesSync([]*types.Transaction{tx})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -508,6 +508,7 @@ func TestEip2929Cases(t *testing.T) {
|
||||||
ops := strings.Join(instrs, ", ")
|
ops := strings.Join(instrs, ", ")
|
||||||
fmt.Printf("### Case %d\n\n", id)
|
fmt.Printf("### Case %d\n\n", id)
|
||||||
id++
|
id++
|
||||||
|
|
||||||
fmt.Printf("%v\n\nBytecode: \n```\n%#x\n```\nOperations: \n```\n%v\n```\n\n",
|
fmt.Printf("%v\n\nBytecode: \n```\n%#x\n```\nOperations: \n```\n%v\n```\n\n",
|
||||||
comment,
|
comment,
|
||||||
code, ops)
|
code, ops)
|
||||||
|
|
|
||||||
10
eth/api.go
10
eth/api.go
|
|
@ -267,6 +267,7 @@ func (api *DebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) {
|
||||||
_, stateDb := api.eth.miner.Pending()
|
_, stateDb := api.eth.miner.Pending()
|
||||||
return stateDb.RawDump(opts), nil
|
return stateDb.RawDump(opts), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var header *types.Header
|
var header *types.Header
|
||||||
if blockNr == rpc.LatestBlockNumber {
|
if blockNr == rpc.LatestBlockNumber {
|
||||||
header = api.eth.blockchain.CurrentBlock()
|
header = api.eth.blockchain.CurrentBlock()
|
||||||
|
|
@ -281,9 +282,11 @@ func (api *DebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) {
|
||||||
}
|
}
|
||||||
header = block.Header()
|
header = block.Header()
|
||||||
}
|
}
|
||||||
|
|
||||||
if header == nil {
|
if header == nil {
|
||||||
return state.Dump{}, fmt.Errorf("block #%d not found", blockNr)
|
return state.Dump{}, fmt.Errorf("block #%d not found", blockNr)
|
||||||
}
|
}
|
||||||
|
|
||||||
stateDb, err := api.eth.BlockChain().StateAt(header.Root)
|
stateDb, err := api.eth.BlockChain().StateAt(header.Root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return state.Dump{}, err
|
return state.Dump{}, err
|
||||||
|
|
@ -419,10 +422,13 @@ func (api *DebugAPI) StorageRangeAt(ctx context.Context, blockHash common.Hash,
|
||||||
if block == nil {
|
if block == nil {
|
||||||
return StorageRangeResult{}, fmt.Errorf("block %#x not found", blockHash)
|
return StorageRangeResult{}, fmt.Errorf("block %#x not found", blockHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, statedb, release, err := api.eth.stateAtTransaction(ctx, block, txIndex, 0)
|
_, _, statedb, release, err := api.eth.stateAtTransaction(ctx, block, txIndex, 0)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return StorageRangeResult{}, err
|
return StorageRangeResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer release()
|
defer release()
|
||||||
|
|
||||||
st, err := statedb.StorageTrie(contractAddress)
|
st, err := statedb.StorageTrie(contractAddress)
|
||||||
|
|
@ -523,6 +529,7 @@ func (api *DebugAPI) getModifiedAccounts(startBlock, endBlock *types.Block) ([]c
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
newTrie, err := trie.NewStateTrie(trie.StateTrieID(endBlock.Root()), triedb)
|
newTrie, err := trie.NewStateTrie(trie.StateTrieID(endBlock.Root()), triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -599,6 +606,7 @@ func (api *DebugAPI) GetAccessibleState(from, to rpc.BlockNumber) (uint64, error
|
||||||
return uint64(i), nil
|
return uint64(i), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0, errors.New("no state found")
|
return 0, errors.New("no state found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -609,6 +617,8 @@ func (api *DebugAPI) SetTrieFlushInterval(interval string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
api.eth.blockchain.SetTrieFlushInterval(t)
|
api.eth.blockchain.SetTrieFlushInterval(t)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,24 +74,32 @@ func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumb
|
||||||
if number == rpc.LatestBlockNumber {
|
if number == rpc.LatestBlockNumber {
|
||||||
return b.eth.blockchain.CurrentBlock(), nil
|
return b.eth.blockchain.CurrentBlock(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if number == rpc.FinalizedBlockNumber {
|
if number == rpc.FinalizedBlockNumber {
|
||||||
if !b.eth.Merger().TDDReached() {
|
if !b.eth.Merger().TDDReached() {
|
||||||
return nil, errors.New("'finalized' tag not supported on pre-merge network")
|
return nil, errors.New("'finalized' tag not supported on pre-merge network")
|
||||||
}
|
}
|
||||||
|
|
||||||
block := b.eth.blockchain.CurrentFinalBlock()
|
block := b.eth.blockchain.CurrentFinalBlock()
|
||||||
|
|
||||||
if block != nil {
|
if block != nil {
|
||||||
return block, nil
|
return block, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, errors.New("finalized block not found")
|
return nil, errors.New("finalized block not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
if number == rpc.SafeBlockNumber {
|
if number == rpc.SafeBlockNumber {
|
||||||
if !b.eth.Merger().TDDReached() {
|
if !b.eth.Merger().TDDReached() {
|
||||||
return nil, errors.New("'safe' tag not supported on pre-merge network")
|
return nil, errors.New("'safe' tag not supported on pre-merge network")
|
||||||
}
|
}
|
||||||
|
|
||||||
block := b.eth.blockchain.CurrentSafeBlock()
|
block := b.eth.blockchain.CurrentSafeBlock()
|
||||||
|
|
||||||
if block != nil {
|
if block != nil {
|
||||||
return block, nil
|
return block, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, errors.New("safe block not found")
|
return nil, errors.New("safe block not found")
|
||||||
}
|
}
|
||||||
return b.eth.blockchain.GetHeaderByNumber(uint64(number)), nil
|
return b.eth.blockchain.GetHeaderByNumber(uint64(number)), nil
|
||||||
|
|
@ -129,18 +137,24 @@ func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumbe
|
||||||
header := b.eth.blockchain.CurrentBlock()
|
header := b.eth.blockchain.CurrentBlock()
|
||||||
return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil
|
return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if number == rpc.FinalizedBlockNumber {
|
if number == rpc.FinalizedBlockNumber {
|
||||||
if !b.eth.Merger().TDDReached() {
|
if !b.eth.Merger().TDDReached() {
|
||||||
return nil, errors.New("'finalized' tag not supported on pre-merge network")
|
return nil, errors.New("'finalized' tag not supported on pre-merge network")
|
||||||
}
|
}
|
||||||
|
|
||||||
header := b.eth.blockchain.CurrentFinalBlock()
|
header := b.eth.blockchain.CurrentFinalBlock()
|
||||||
|
|
||||||
return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil
|
return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if number == rpc.SafeBlockNumber {
|
if number == rpc.SafeBlockNumber {
|
||||||
if !b.eth.Merger().TDDReached() {
|
if !b.eth.Merger().TDDReached() {
|
||||||
return nil, errors.New("'safe' tag not supported on pre-merge network")
|
return nil, errors.New("'safe' tag not supported on pre-merge network")
|
||||||
}
|
}
|
||||||
|
|
||||||
header := b.eth.blockchain.CurrentSafeBlock()
|
header := b.eth.blockchain.CurrentSafeBlock()
|
||||||
|
|
||||||
return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil
|
return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil
|
||||||
}
|
}
|
||||||
return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil
|
return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil
|
||||||
|
|
@ -155,9 +169,11 @@ func (b *EthAPIBackend) GetBody(ctx context.Context, hash common.Hash, number rp
|
||||||
if number < 0 || hash == (common.Hash{}) {
|
if number < 0 || hash == (common.Hash{}) {
|
||||||
return nil, errors.New("invalid arguments; expect hash and no special block numbers")
|
return nil, errors.New("invalid arguments; expect hash and no special block numbers")
|
||||||
}
|
}
|
||||||
|
|
||||||
if body := b.eth.blockchain.GetBody(hash); body != nil {
|
if body := b.eth.blockchain.GetBody(hash); body != nil {
|
||||||
return body, nil
|
return body, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, errors.New("block body not found")
|
return nil, errors.New("block body not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -246,6 +262,7 @@ func (b *EthAPIBackend) GetEVM(ctx context.Context, msg *core.Message, state *st
|
||||||
}
|
}
|
||||||
txContext := core.NewEVMTxContext(msg)
|
txContext := core.NewEVMTxContext(msg)
|
||||||
context := core.NewEVMBlockContext(header, b.eth.BlockChain(), nil)
|
context := core.NewEVMBlockContext(header, b.eth.BlockChain(), nil)
|
||||||
|
|
||||||
return vm.NewEVM(context, txContext, state, b.eth.blockchain.Config(), *vmConfig), state.Error, nil
|
return vm.NewEVM(context, txContext, state, b.eth.blockchain.Config(), *vmConfig), state.Error, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,7 @@ func TestStorageRangeAt(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := storageRangeAt(tr, test.start, test.limit)
|
result, err := storageRangeAt(tr, test.start, test.limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := pruner.RecoverPruning(stack.ResolvePath(""), chainDb, stack.ResolvePath(config.TrieCleanCacheJournal)); err != nil {
|
if err := pruner.RecoverPruning(stack.ResolvePath(""), chainDb, stack.ResolvePath(config.TrieCleanCacheJournal)); err != nil {
|
||||||
log.Error("Failed to recover state", "error", err)
|
log.Error("Failed to recover state", "error", err)
|
||||||
}
|
}
|
||||||
|
|
@ -147,6 +148,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||||
ethashConfig := config.Ethash
|
ethashConfig := config.Ethash
|
||||||
ethashConfig.NotifyFull = config.Miner.NotifyFull
|
ethashConfig.NotifyFull = config.Miner.NotifyFull
|
||||||
cliqueConfig, err := core.LoadCliqueConfig(chainDb, config.Genesis)
|
cliqueConfig, err := core.LoadCliqueConfig(chainDb, config.Genesis)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -180,6 +182,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||||
if gpoParams.Default == nil {
|
if gpoParams.Default == nil {
|
||||||
gpoParams.Default = config.Miner.GasPrice
|
gpoParams.Default = config.Miner.GasPrice
|
||||||
}
|
}
|
||||||
|
|
||||||
ethereum.APIBackend.gpo = gasprice.NewOracle(ethereum.APIBackend, gpoParams)
|
ethereum.APIBackend.gpo = gasprice.NewOracle(ethereum.APIBackend, gpoParams)
|
||||||
|
|
||||||
// Override the chain config with provided settings.
|
// Override the chain config with provided settings.
|
||||||
|
|
@ -199,6 +202,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||||
// END: Bor changes
|
// END: Bor changes
|
||||||
|
|
||||||
bcVersion := rawdb.ReadDatabaseVersion(chainDb)
|
bcVersion := rawdb.ReadDatabaseVersion(chainDb)
|
||||||
|
|
||||||
var dbVer = "<nil>"
|
var dbVer = "<nil>"
|
||||||
if bcVersion != nil {
|
if bcVersion != nil {
|
||||||
dbVer = fmt.Sprintf("%d", *bcVersion)
|
dbVer = fmt.Sprintf("%d", *bcVersion)
|
||||||
|
|
@ -259,6 +263,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||||
if config.TxPool.Journal != "" {
|
if config.TxPool.Journal != "" {
|
||||||
config.TxPool.Journal = stack.ResolvePath(config.TxPool.Journal)
|
config.TxPool.Journal = stack.ResolvePath(config.TxPool.Journal)
|
||||||
}
|
}
|
||||||
|
|
||||||
ethereum.txPool = txpool.NewTxPool(config.TxPool, ethereum.blockchain.Config(), ethereum.blockchain)
|
ethereum.txPool = txpool.NewTxPool(config.TxPool, ethereum.blockchain.Config(), ethereum.blockchain)
|
||||||
|
|
||||||
// Permit the downloader to use the trie cache allowance during fast sync
|
// Permit the downloader to use the trie cache allowance during fast sync
|
||||||
|
|
@ -267,6 +272,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||||
if checkpoint == nil {
|
if checkpoint == nil {
|
||||||
checkpoint = params.TrustedCheckpoints[ethereum.blockchain.Genesis().Hash()]
|
checkpoint = params.TrustedCheckpoints[ethereum.blockchain.Genesis().Hash()]
|
||||||
}
|
}
|
||||||
|
|
||||||
if ethereum.handler, err = newHandler(&handlerConfig{
|
if ethereum.handler, err = newHandler(&handlerConfig{
|
||||||
Database: chainDb,
|
Database: chainDb,
|
||||||
Chain: ethereum.blockchain,
|
Chain: ethereum.blockchain,
|
||||||
|
|
@ -294,6 +300,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ethereum.snapDialCandidates, err = dnsclient.NewIterator(ethereum.config.SnapDiscoveryURLs...)
|
ethereum.snapDialCandidates, err = dnsclient.NewIterator(ethereum.config.SnapDiscoveryURLs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,7 @@ func NewConsensusAPI(eth *eth.Ethereum) *ConsensusAPI {
|
||||||
if eth.BlockChain().Config().TerminalTotalDifficulty == nil {
|
if eth.BlockChain().Config().TerminalTotalDifficulty == nil {
|
||||||
log.Warn("Engine API started but chain not configured for merge yet")
|
log.Warn("Engine API started but chain not configured for merge yet")
|
||||||
}
|
}
|
||||||
|
|
||||||
api := &ConsensusAPI{
|
api := &ConsensusAPI{
|
||||||
eth: eth,
|
eth: eth,
|
||||||
remoteBlocks: newHeaderQueue(),
|
remoteBlocks: newHeaderQueue(),
|
||||||
|
|
@ -143,6 +144,7 @@ func NewConsensusAPI(eth *eth.Ethereum) *ConsensusAPI {
|
||||||
invalidTipsets: make(map[common.Hash]*types.Header),
|
invalidTipsets: make(map[common.Hash]*types.Header),
|
||||||
}
|
}
|
||||||
eth.Downloader().SetBadBlockCallback(api.setInvalidAncestor)
|
eth.Downloader().SetBadBlockCallback(api.setInvalidAncestor)
|
||||||
|
|
||||||
go api.heartbeat()
|
go api.heartbeat()
|
||||||
|
|
||||||
return api
|
return api
|
||||||
|
|
@ -167,10 +169,12 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update engine.ForkchoiceStateV1, pa
|
||||||
if payloadAttributes.Withdrawals != nil {
|
if payloadAttributes.Withdrawals != nil {
|
||||||
return engine.STATUS_INVALID, engine.InvalidParams.With(fmt.Errorf("withdrawals not supported in V1"))
|
return engine.STATUS_INVALID, engine.InvalidParams.With(fmt.Errorf("withdrawals not supported in V1"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if api.eth.BlockChain().Config().IsShanghai(payloadAttributes.Timestamp) {
|
if api.eth.BlockChain().Config().IsShanghai(payloadAttributes.Timestamp) {
|
||||||
return engine.STATUS_INVALID, engine.InvalidParams.With(fmt.Errorf("forkChoiceUpdateV1 called post-shanghai"))
|
return engine.STATUS_INVALID, engine.InvalidParams.With(fmt.Errorf("forkChoiceUpdateV1 called post-shanghai"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return api.forkchoiceUpdated(update, payloadAttributes)
|
return api.forkchoiceUpdated(update, payloadAttributes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -181,6 +185,7 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV2(update engine.ForkchoiceStateV1, pa
|
||||||
return engine.STATUS_INVALID, engine.InvalidParams.With(err)
|
return engine.STATUS_INVALID, engine.InvalidParams.With(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return api.forkchoiceUpdated(update, payloadAttributes)
|
return api.forkchoiceUpdated(update, payloadAttributes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,6 +201,7 @@ func (api *ConsensusAPI) verifyPayloadAttributes(attr *engine.PayloadAttributes)
|
||||||
return errors.New("missing withdrawals list")
|
return errors.New("missing withdrawals list")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -242,7 +248,9 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl
|
||||||
merger.ReachTTD()
|
merger.ReachTTD()
|
||||||
api.eth.Downloader().Cancel()
|
api.eth.Downloader().Cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
context := []interface{}{"number", header.Number, "hash", header.Hash()}
|
context := []interface{}{"number", header.Number, "hash", header.Hash()}
|
||||||
|
|
||||||
if update.FinalizedBlockHash != (common.Hash{}) {
|
if update.FinalizedBlockHash != (common.Hash{}) {
|
||||||
if finalized == nil {
|
if finalized == nil {
|
||||||
context = append(context, []interface{}{"finalized", "unknown"}...)
|
context = append(context, []interface{}{"finalized", "unknown"}...)
|
||||||
|
|
@ -250,10 +258,13 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl
|
||||||
context = append(context, []interface{}{"finalized", finalized.Number}...)
|
context = append(context, []interface{}{"finalized", finalized.Number}...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Forkchoice requested sync to new head", context...)
|
log.Info("Forkchoice requested sync to new head", context...)
|
||||||
|
|
||||||
if err := api.eth.Downloader().BeaconSync(api.eth.SyncMode(), header, finalized); err != nil {
|
if err := api.eth.Downloader().BeaconSync(api.eth.SyncMode(), header, finalized); err != nil {
|
||||||
return engine.STATUS_SYNCING, err
|
return engine.STATUS_SYNCING, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return engine.STATUS_SYNCING, nil
|
return engine.STATUS_SYNCING, nil
|
||||||
}
|
}
|
||||||
// Block is known locally, just sanity check that the beacon client does not
|
// Block is known locally, just sanity check that the beacon client does not
|
||||||
|
|
@ -268,15 +279,18 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl
|
||||||
log.Error("TDs unavailable for TTD check", "number", block.NumberU64(), "hash", update.HeadBlockHash, "td", td, "parent", block.ParentHash(), "ptd", ptd)
|
log.Error("TDs unavailable for TTD check", "number", block.NumberU64(), "hash", update.HeadBlockHash, "td", td, "parent", block.ParentHash(), "ptd", ptd)
|
||||||
return engine.STATUS_INVALID, errors.New("TDs unavailable for TDD check")
|
return engine.STATUS_INVALID, errors.New("TDs unavailable for TDD check")
|
||||||
}
|
}
|
||||||
|
|
||||||
if td.Cmp(ttd) < 0 {
|
if td.Cmp(ttd) < 0 {
|
||||||
log.Error("Refusing beacon update to pre-merge", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0)))
|
log.Error("Refusing beacon update to pre-merge", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0)))
|
||||||
return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil
|
return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if block.NumberU64() > 0 && ptd.Cmp(ttd) >= 0 {
|
if block.NumberU64() > 0 && ptd.Cmp(ttd) >= 0 {
|
||||||
log.Error("Parent block is already post-ttd", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0)))
|
log.Error("Parent block is already post-ttd", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0)))
|
||||||
return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil
|
return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
valid := func(id *engine.PayloadID) engine.ForkChoiceResponse {
|
valid := func(id *engine.PayloadID) engine.ForkChoiceResponse {
|
||||||
return engine.ForkChoiceResponse{
|
return engine.ForkChoiceResponse{
|
||||||
PayloadStatus: engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &update.HeadBlockHash},
|
PayloadStatus: engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &update.HeadBlockHash},
|
||||||
|
|
@ -349,16 +363,20 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl
|
||||||
if api.localBlocks.has(id) {
|
if api.localBlocks.has(id) {
|
||||||
return valid(&id), nil
|
return valid(&id), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
payload, err := api.eth.Miner().BuildPayload(args)
|
payload, err := api.eth.Miner().BuildPayload(args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to build payload", "err", err)
|
log.Error("Failed to build payload", "err", err)
|
||||||
return valid(nil), engine.InvalidPayloadAttributes.With(err)
|
return valid(nil), engine.InvalidPayloadAttributes.With(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
api.localBlocks.put(id, payload)
|
api.localBlocks.put(id, payload)
|
||||||
|
|
||||||
return valid(&id), nil
|
return valid(&id), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return valid(nil), nil
|
return valid(nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExchangeTransitionConfigurationV1 checks the given configuration against
|
// ExchangeTransitionConfigurationV1 checks the given configuration against
|
||||||
// the configuration of the node.
|
// the configuration of the node.
|
||||||
|
|
@ -387,6 +405,7 @@ func (api *ConsensusAPI) ExchangeTransitionConfigurationV1(config engine.Transit
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("invalid terminal block hash")
|
return nil, fmt.Errorf("invalid terminal block hash")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &engine.TransitionConfigurationV1{TerminalTotalDifficulty: (*hexutil.Big)(ttd)}, nil
|
return &engine.TransitionConfigurationV1{TerminalTotalDifficulty: (*hexutil.Big)(ttd)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -396,6 +415,7 @@ func (api *ConsensusAPI) GetPayloadV1(payloadID engine.PayloadID) (*engine.Execu
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return data.ExecutionPayload, nil
|
return data.ExecutionPayload, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -418,6 +438,7 @@ func (api *ConsensusAPI) NewPayloadV1(params engine.ExecutableData) (engine.Payl
|
||||||
if params.Withdrawals != nil {
|
if params.Withdrawals != nil {
|
||||||
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(fmt.Errorf("withdrawals not supported in V1"))
|
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(fmt.Errorf("withdrawals not supported in V1"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return api.newPayload(params)
|
return api.newPayload(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -430,6 +451,7 @@ func (api *ConsensusAPI) NewPayloadV2(params engine.ExecutableData) (engine.Payl
|
||||||
} else if params.Withdrawals != nil {
|
} else if params.Withdrawals != nil {
|
||||||
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(fmt.Errorf("non-nil withdrawals pre-shanghai"))
|
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(fmt.Errorf("non-nil withdrawals pre-shanghai"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return api.newPayload(params)
|
return api.newPayload(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -466,6 +488,7 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData) (engine.Payloa
|
||||||
if block := api.eth.BlockChain().GetBlockByHash(params.BlockHash); block != nil {
|
if block := api.eth.BlockChain().GetBlockByHash(params.BlockHash); block != nil {
|
||||||
log.Warn("Ignoring already known beacon payload", "number", params.Number, "hash", params.BlockHash, "age", common.PrettyAge(time.Unix(int64(block.Time()), 0)))
|
log.Warn("Ignoring already known beacon payload", "number", params.Number, "hash", params.BlockHash, "age", common.PrettyAge(time.Unix(int64(block.Time()), 0)))
|
||||||
hash := block.Hash()
|
hash := block.Hash()
|
||||||
|
|
||||||
return engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &hash}, nil
|
return engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &hash}, nil
|
||||||
}
|
}
|
||||||
// If this block was rejected previously, keep rejecting it
|
// If this block was rejected previously, keep rejecting it
|
||||||
|
|
@ -489,10 +512,12 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData) (engine.Payloa
|
||||||
ttd = api.eth.BlockChain().Config().TerminalTotalDifficulty
|
ttd = api.eth.BlockChain().Config().TerminalTotalDifficulty
|
||||||
gptd = api.eth.BlockChain().GetTd(parent.ParentHash(), parent.NumberU64()-1)
|
gptd = api.eth.BlockChain().GetTd(parent.ParentHash(), parent.NumberU64()-1)
|
||||||
)
|
)
|
||||||
|
|
||||||
if ptd.Cmp(ttd) < 0 {
|
if ptd.Cmp(ttd) < 0 {
|
||||||
log.Warn("Ignoring pre-merge payload", "number", params.Number, "hash", params.BlockHash, "td", ptd, "ttd", ttd)
|
log.Warn("Ignoring pre-merge payload", "number", params.Number, "hash", params.BlockHash, "td", ptd, "ttd", ttd)
|
||||||
return engine.INVALID_TERMINAL_BLOCK, nil
|
return engine.INVALID_TERMINAL_BLOCK, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if parent.Difficulty().BitLen() > 0 && gptd != nil && gptd.Cmp(ttd) >= 0 {
|
if parent.Difficulty().BitLen() > 0 && gptd != nil && gptd.Cmp(ttd) >= 0 {
|
||||||
log.Error("Ignoring pre-merge parent block", "number", params.Number, "hash", params.BlockHash, "td", ptd, "ttd", ttd)
|
log.Error("Ignoring pre-merge parent block", "number", params.Number, "hash", params.BlockHash, "td", ptd, "ttd", ttd)
|
||||||
return engine.INVALID_TERMINAL_BLOCK, nil
|
return engine.INVALID_TERMINAL_BLOCK, nil
|
||||||
|
|
@ -511,6 +536,7 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData) (engine.Payloa
|
||||||
if !api.eth.BlockChain().HasBlockAndState(block.ParentHash(), block.NumberU64()-1) {
|
if !api.eth.BlockChain().HasBlockAndState(block.ParentHash(), block.NumberU64()-1) {
|
||||||
api.remoteBlocks.put(block.Hash(), block.Header())
|
api.remoteBlocks.put(block.Hash(), block.Header())
|
||||||
log.Warn("State not available, ignoring new payload")
|
log.Warn("State not available, ignoring new payload")
|
||||||
|
|
||||||
return engine.PayloadStatusV1{Status: engine.ACCEPTED}, nil
|
return engine.PayloadStatusV1{Status: engine.ACCEPTED}, nil
|
||||||
}
|
}
|
||||||
log.Trace("Inserting block without sethead", "hash", block.Hash(), "number", block.Number)
|
log.Trace("Inserting block without sethead", "hash", block.Hash(), "number", block.Number)
|
||||||
|
|
@ -532,6 +558,7 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData) (engine.Payloa
|
||||||
api.eth.Downloader().Cancel()
|
api.eth.Downloader().Cancel()
|
||||||
}
|
}
|
||||||
hash := block.Hash()
|
hash := block.Hash()
|
||||||
|
|
||||||
return engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &hash}, nil
|
return engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &hash}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -571,6 +598,7 @@ func (api *ConsensusAPI) delayPayloadImport(block *types.Block) (engine.PayloadS
|
||||||
// and cannot afford concurrent out-if-band modifications via imports.
|
// and cannot afford concurrent out-if-band modifications via imports.
|
||||||
log.Warn("Ignoring payload while snap syncing", "number", block.NumberU64(), "hash", block.Hash())
|
log.Warn("Ignoring payload while snap syncing", "number", block.NumberU64(), "hash", block.Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
return engine.PayloadStatusV1{Status: engine.SYNCING}, nil
|
return engine.PayloadStatusV1{Status: engine.SYNCING}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -609,17 +637,20 @@ func (api *ConsensusAPI) checkInvalidAncestor(check common.Hash, head common.Has
|
||||||
delete(api.invalidTipsets, descendant)
|
delete(api.invalidTipsets, descendant)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Not too many failures yet, mark the head of the invalid chain as invalid
|
// Not too many failures yet, mark the head of the invalid chain as invalid
|
||||||
if check != head {
|
if check != head {
|
||||||
log.Warn("Marked new chain head as invalid", "hash", head, "badnumber", invalid.Number, "badhash", badHash)
|
log.Warn("Marked new chain head as invalid", "hash", head, "badnumber", invalid.Number, "badhash", badHash)
|
||||||
|
|
||||||
for len(api.invalidTipsets) >= invalidTipsetsCap {
|
for len(api.invalidTipsets) >= invalidTipsetsCap {
|
||||||
for key := range api.invalidTipsets {
|
for key := range api.invalidTipsets {
|
||||||
delete(api.invalidTipsets, key)
|
delete(api.invalidTipsets, key)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
api.invalidTipsets[head] = invalid
|
api.invalidTipsets[head] = invalid
|
||||||
}
|
}
|
||||||
// If the last valid hash is the terminal pow block, return 0x0 for latest valid hash
|
// If the last valid hash is the terminal pow block, return 0x0 for latest valid hash
|
||||||
|
|
@ -627,7 +658,9 @@ func (api *ConsensusAPI) checkInvalidAncestor(check common.Hash, head common.Has
|
||||||
if header := api.eth.BlockChain().GetHeader(invalid.ParentHash, invalid.Number.Uint64()-1); header != nil && header.Difficulty.Sign() != 0 {
|
if header := api.eth.BlockChain().GetHeader(invalid.ParentHash, invalid.Number.Uint64()-1); header != nil && header.Difficulty.Sign() != 0 {
|
||||||
lastValid = &common.Hash{}
|
lastValid = &common.Hash{}
|
||||||
}
|
}
|
||||||
|
|
||||||
failure := "links to previously rejected block"
|
failure := "links to previously rejected block"
|
||||||
|
|
||||||
return &engine.PayloadStatusV1{
|
return &engine.PayloadStatusV1{
|
||||||
Status: engine.INVALID,
|
Status: engine.INVALID,
|
||||||
LatestValidHash: lastValid,
|
LatestValidHash: lastValid,
|
||||||
|
|
@ -648,6 +681,7 @@ func (api *ConsensusAPI) invalid(err error, latestValid *types.Header) engine.Pa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
errorMsg := err.Error()
|
errorMsg := err.Error()
|
||||||
|
|
||||||
return engine.PayloadStatusV1{Status: engine.INVALID, LatestValidHash: ¤tHash, ValidationError: &errorMsg}
|
return engine.PayloadStatusV1{Status: engine.INVALID, LatestValidHash: ¤tHash, ValidationError: &errorMsg}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -702,8 +736,10 @@ func (api *ConsensusAPI) heartbeat() {
|
||||||
} else {
|
} else {
|
||||||
log.Warn("Beacon client online, but no consensus updates received in a while. Please fix your beacon client to follow the chain!")
|
log.Warn("Beacon client online, but no consensus updates received in a while. Please fix your beacon client to follow the chain!")
|
||||||
}
|
}
|
||||||
|
|
||||||
offlineLogged = time.Now()
|
offlineLogged = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -718,10 +754,12 @@ func (api *ConsensusAPI) ExchangeCapabilities([]string) []string {
|
||||||
// of block bodies by the engine api.
|
// of block bodies by the engine api.
|
||||||
func (api *ConsensusAPI) GetPayloadBodiesByHashV1(hashes []common.Hash) []*engine.ExecutionPayloadBodyV1 {
|
func (api *ConsensusAPI) GetPayloadBodiesByHashV1(hashes []common.Hash) []*engine.ExecutionPayloadBodyV1 {
|
||||||
var bodies = make([]*engine.ExecutionPayloadBodyV1, len(hashes))
|
var bodies = make([]*engine.ExecutionPayloadBodyV1, len(hashes))
|
||||||
|
|
||||||
for i, hash := range hashes {
|
for i, hash := range hashes {
|
||||||
block := api.eth.BlockChain().GetBlockByHash(hash)
|
block := api.eth.BlockChain().GetBlockByHash(hash)
|
||||||
bodies[i] = getBody(block)
|
bodies[i] = getBody(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
return bodies
|
return bodies
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -731,20 +769,25 @@ func (api *ConsensusAPI) GetPayloadBodiesByRangeV1(start, count hexutil.Uint64)
|
||||||
if start == 0 || count == 0 {
|
if start == 0 || count == 0 {
|
||||||
return nil, engine.InvalidParams.With(fmt.Errorf("invalid start or count, start: %v count: %v", start, count))
|
return nil, engine.InvalidParams.With(fmt.Errorf("invalid start or count, start: %v count: %v", start, count))
|
||||||
}
|
}
|
||||||
|
|
||||||
if count > 1024 {
|
if count > 1024 {
|
||||||
return nil, engine.TooLargeRequest.With(fmt.Errorf("requested count too large: %v", count))
|
return nil, engine.TooLargeRequest.With(fmt.Errorf("requested count too large: %v", count))
|
||||||
}
|
}
|
||||||
// limit count up until current
|
// limit count up until current
|
||||||
current := api.eth.BlockChain().CurrentBlock().Number.Uint64()
|
current := api.eth.BlockChain().CurrentBlock().Number.Uint64()
|
||||||
last := uint64(start) + uint64(count) - 1
|
last := uint64(start) + uint64(count) - 1
|
||||||
|
|
||||||
if last > current {
|
if last > current {
|
||||||
last = current
|
last = current
|
||||||
}
|
}
|
||||||
|
|
||||||
bodies := make([]*engine.ExecutionPayloadBodyV1, 0, uint64(count))
|
bodies := make([]*engine.ExecutionPayloadBodyV1, 0, uint64(count))
|
||||||
|
|
||||||
for i := uint64(start); i <= last; i++ {
|
for i := uint64(start); i <= last; i++ {
|
||||||
block := api.eth.BlockChain().GetBlockByNumber(i)
|
block := api.eth.BlockChain().GetBlockByNumber(i)
|
||||||
bodies = append(bodies, getBody(block))
|
bodies = append(bodies, getBody(block))
|
||||||
}
|
}
|
||||||
|
|
||||||
return bodies, nil
|
return bodies, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ var (
|
||||||
func generateMergeChain(n int, merged bool) (*core.Genesis, []*types.Block) {
|
func generateMergeChain(n int, merged bool) (*core.Genesis, []*types.Block) {
|
||||||
config := *params.AllEthashProtocolChanges
|
config := *params.AllEthashProtocolChanges
|
||||||
engine := consensus.Engine(beaconConsensus.New(ethash.NewFaker()))
|
engine := consensus.Engine(beaconConsensus.New(ethash.NewFaker()))
|
||||||
|
|
||||||
if merged {
|
if merged {
|
||||||
config.TerminalTotalDifficulty = common.Big0
|
config.TerminalTotalDifficulty = common.Big0
|
||||||
config.TerminalTotalDifficultyPassed = true
|
config.TerminalTotalDifficultyPassed = true
|
||||||
|
|
@ -78,6 +79,7 @@ func generateMergeChain(n int, merged bool) (*core.Genesis, []*types.Block) {
|
||||||
generate := func(i int, g *core.BlockGen) {
|
generate := func(i int, g *core.BlockGen) {
|
||||||
g.OffsetTime(5)
|
g.OffsetTime(5)
|
||||||
g.SetExtra([]byte("test"))
|
g.SetExtra([]byte("test"))
|
||||||
|
|
||||||
tx, _ := types.SignTx(types.NewTransaction(testNonce, common.HexToAddress("0x9a9070028361F7AAbeB3f2F2Dc07F82C4a98A02a"), big.NewInt(1), params.TxGas, big.NewInt(params.InitialBaseFee*2), nil), types.LatestSigner(&config), testKey)
|
tx, _ := types.SignTx(types.NewTransaction(testNonce, common.HexToAddress("0x9a9070028361F7AAbeB3f2F2Dc07F82C4a98A02a"), big.NewInt(1), params.TxGas, big.NewInt(params.InitialBaseFee*2), nil), types.LatestSigner(&config), testKey)
|
||||||
g.AddTx(tx)
|
g.AddTx(tx)
|
||||||
testNonce++
|
testNonce++
|
||||||
|
|
@ -89,6 +91,7 @@ func generateMergeChain(n int, merged bool) (*core.Genesis, []*types.Block) {
|
||||||
for _, b := range blocks {
|
for _, b := range blocks {
|
||||||
totalDifficulty.Add(totalDifficulty, b.Difficulty())
|
totalDifficulty.Add(totalDifficulty, b.Difficulty())
|
||||||
}
|
}
|
||||||
|
|
||||||
config.TerminalTotalDifficulty = totalDifficulty
|
config.TerminalTotalDifficulty = totalDifficulty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,6 +112,7 @@ func TestEth2AssembleBlock(t *testing.T) {
|
||||||
t.Fatalf("error signing transaction, err=%v", err)
|
t.Fatalf("error signing transaction, err=%v", err)
|
||||||
}
|
}
|
||||||
ethservice.TxPool().AddLocal(tx)
|
ethservice.TxPool().AddLocal(tx)
|
||||||
|
|
||||||
blockParams := engine.PayloadAttributes{
|
blockParams := engine.PayloadAttributes{
|
||||||
Timestamp: blocks[9].Time() + 5,
|
Timestamp: blocks[9].Time() + 5,
|
||||||
}
|
}
|
||||||
|
|
@ -127,12 +131,15 @@ func assembleWithTransactions(api *ConsensusAPI, parentHash common.Hash, params
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if have, want := len(execData.Transactions), want; have != want {
|
if have, want := len(execData.Transactions), want; have != want {
|
||||||
err = fmt.Errorf("invalid number of transactions, have %d want %d", have, want)
|
err = fmt.Errorf("invalid number of transactions, have %d want %d", have, want)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
return execData, nil
|
return execData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,6 +154,7 @@ func TestEth2AssembleBlockWithAnotherBlocksTxs(t *testing.T) {
|
||||||
|
|
||||||
// Put the 10th block's tx in the pool and produce a new block
|
// Put the 10th block's tx in the pool and produce a new block
|
||||||
api.eth.TxPool().AddRemotesSync(blocks[9].Transactions())
|
api.eth.TxPool().AddRemotesSync(blocks[9].Transactions())
|
||||||
|
|
||||||
blockParams := engine.PayloadAttributes{
|
blockParams := engine.PayloadAttributes{
|
||||||
Timestamp: blocks[8].Time() + 5,
|
Timestamp: blocks[8].Time() + 5,
|
||||||
}
|
}
|
||||||
|
|
@ -180,12 +188,14 @@ func TestEth2PrepareAndGetPayload(t *testing.T) {
|
||||||
// We need to properly set the terminal total difficulty
|
// We need to properly set the terminal total difficulty
|
||||||
genesis.Config.TerminalTotalDifficulty.Sub(genesis.Config.TerminalTotalDifficulty, blocks[9].Difficulty())
|
genesis.Config.TerminalTotalDifficulty.Sub(genesis.Config.TerminalTotalDifficulty, blocks[9].Difficulty())
|
||||||
n, ethservice := startEthService(t, genesis, blocks[:9])
|
n, ethservice := startEthService(t, genesis, blocks[:9])
|
||||||
|
|
||||||
defer n.Close()
|
defer n.Close()
|
||||||
|
|
||||||
api := NewConsensusAPI(ethservice)
|
api := NewConsensusAPI(ethservice)
|
||||||
|
|
||||||
// Put the 10th block's tx in the pool and produce a new block
|
// Put the 10th block's tx in the pool and produce a new block
|
||||||
ethservice.TxPool().AddLocals(blocks[9].Transactions())
|
ethservice.TxPool().AddLocals(blocks[9].Transactions())
|
||||||
|
|
||||||
blockParams := engine.PayloadAttributes{
|
blockParams := engine.PayloadAttributes{
|
||||||
Timestamp: blocks[8].Time() + 5,
|
Timestamp: blocks[8].Time() + 5,
|
||||||
}
|
}
|
||||||
|
|
@ -195,11 +205,13 @@ func TestEth2PrepareAndGetPayload(t *testing.T) {
|
||||||
FinalizedBlockHash: common.Hash{},
|
FinalizedBlockHash: common.Hash{},
|
||||||
}
|
}
|
||||||
_, err := api.ForkchoiceUpdatedV1(fcState, &blockParams)
|
_, err := api.ForkchoiceUpdatedV1(fcState, &blockParams)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error preparing payload, err=%v", err)
|
t.Fatalf("error preparing payload, err=%v", err)
|
||||||
}
|
}
|
||||||
// give the payload some time to be built
|
// give the payload some time to be built
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
payloadID := (&miner.BuildPayloadArgs{
|
payloadID := (&miner.BuildPayloadArgs{
|
||||||
Parent: fcState.HeadBlockHash,
|
Parent: fcState.HeadBlockHash,
|
||||||
Timestamp: blockParams.Timestamp,
|
Timestamp: blockParams.Timestamp,
|
||||||
|
|
@ -207,17 +219,21 @@ func TestEth2PrepareAndGetPayload(t *testing.T) {
|
||||||
Random: blockParams.Random,
|
Random: blockParams.Random,
|
||||||
}).Id()
|
}).Id()
|
||||||
execData, err := api.GetPayloadV1(payloadID)
|
execData, err := api.GetPayloadV1(payloadID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error getting payload, err=%v", err)
|
t.Fatalf("error getting payload, err=%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(execData.Transactions) != blocks[9].Transactions().Len() {
|
if len(execData.Transactions) != blocks[9].Transactions().Len() {
|
||||||
t.Fatalf("invalid number of transactions %d != 1", len(execData.Transactions))
|
t.Fatalf("invalid number of transactions %d != 1", len(execData.Transactions))
|
||||||
}
|
}
|
||||||
// Test invalid payloadID
|
// Test invalid payloadID
|
||||||
var invPayload engine.PayloadID
|
var invPayload engine.PayloadID
|
||||||
|
|
||||||
copy(invPayload[:], payloadID[:])
|
copy(invPayload[:], payloadID[:])
|
||||||
invPayload[0] = ^invPayload[0]
|
invPayload[0] = ^invPayload[0]
|
||||||
_, err = api.GetPayloadV1(invPayload)
|
_, err = api.GetPayloadV1(invPayload)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error retrieving invalid payload")
|
t.Fatal("expected error retrieving invalid payload")
|
||||||
}
|
}
|
||||||
|
|
@ -287,6 +303,7 @@ func TestInvalidPayloadTimestamp(t *testing.T) {
|
||||||
|
|
||||||
func TestEth2NewBlock(t *testing.T) {
|
func TestEth2NewBlock(t *testing.T) {
|
||||||
t.Skip("ETH2 in Bor")
|
t.Skip("ETH2 in Bor")
|
||||||
|
|
||||||
genesis, preMergeBlocks := generateMergeChain(10, false)
|
genesis, preMergeBlocks := generateMergeChain(10, false)
|
||||||
n, ethservice := startEthService(t, genesis, preMergeBlocks)
|
n, ethservice := startEthService(t, genesis, preMergeBlocks)
|
||||||
defer n.Close()
|
defer n.Close()
|
||||||
|
|
@ -316,11 +333,13 @@ func TestEth2NewBlock(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create the executable data %v", err)
|
t.Fatalf("Failed to create the executable data %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
block, err := engine.ExecutableDataToBlock(*execData)
|
block, err := engine.ExecutableDataToBlock(*execData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to convert executable data to block %v", err)
|
t.Fatalf("Failed to convert executable data to block %v", err)
|
||||||
}
|
}
|
||||||
newResp, err := api.NewPayloadV1(*execData)
|
newResp, err := api.NewPayloadV1(*execData)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
t.Fatalf("Failed to insert block: %v", err)
|
t.Fatalf("Failed to insert block: %v", err)
|
||||||
|
|
@ -330,14 +349,17 @@ func TestEth2NewBlock(t *testing.T) {
|
||||||
t.Fatalf("Chain head shouldn't be updated")
|
t.Fatalf("Chain head shouldn't be updated")
|
||||||
}
|
}
|
||||||
checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
|
checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
|
||||||
|
|
||||||
fcState := engine.ForkchoiceStateV1{
|
fcState := engine.ForkchoiceStateV1{
|
||||||
HeadBlockHash: block.Hash(),
|
HeadBlockHash: block.Hash(),
|
||||||
SafeBlockHash: block.Hash(),
|
SafeBlockHash: block.Hash(),
|
||||||
FinalizedBlockHash: block.Hash(),
|
FinalizedBlockHash: block.Hash(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
|
if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
|
||||||
t.Fatalf("Failed to insert block: %v", err)
|
t.Fatalf("Failed to insert block: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if have, want := ethservice.BlockChain().CurrentBlock().Number.Uint64(), block.NumberU64(); have != want {
|
if have, want := ethservice.BlockChain().CurrentBlock().Number.Uint64(), block.NumberU64(); have != want {
|
||||||
t.Fatalf("Chain head should be updated, have %d want %d", have, want)
|
t.Fatalf("Chain head should be updated, have %d want %d", have, want)
|
||||||
}
|
}
|
||||||
|
|
@ -350,22 +372,28 @@ func TestEth2NewBlock(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
head = ethservice.BlockChain().CurrentBlock().Number.Uint64()
|
head = ethservice.BlockChain().CurrentBlock().Number.Uint64()
|
||||||
)
|
)
|
||||||
|
|
||||||
parent = preMergeBlocks[len(preMergeBlocks)-1]
|
parent = preMergeBlocks[len(preMergeBlocks)-1]
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
execData, err := assembleBlock(api, parent.Hash(), &engine.PayloadAttributes{
|
execData, err := assembleBlock(api, parent.Hash(), &engine.PayloadAttributes{
|
||||||
Timestamp: parent.Time() + 6,
|
Timestamp: parent.Time() + 6,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create the executable data %v", err)
|
t.Fatalf("Failed to create the executable data %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
block, err := engine.ExecutableDataToBlock(*execData)
|
block, err := engine.ExecutableDataToBlock(*execData)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to convert executable data to block %v", err)
|
t.Fatalf("Failed to convert executable data to block %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newResp, err := api.NewPayloadV1(*execData)
|
newResp, err := api.NewPayloadV1(*execData)
|
||||||
if err != nil || newResp.Status != "VALID" {
|
if err != nil || newResp.Status != "VALID" {
|
||||||
t.Fatalf("Failed to insert block: %v", err)
|
t.Fatalf("Failed to insert block: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ethservice.BlockChain().CurrentBlock().Number.Uint64() != head {
|
if ethservice.BlockChain().CurrentBlock().Number.Uint64() != head {
|
||||||
t.Fatalf("Chain head shouldn't be updated")
|
t.Fatalf("Chain head shouldn't be updated")
|
||||||
}
|
}
|
||||||
|
|
@ -375,9 +403,11 @@ func TestEth2NewBlock(t *testing.T) {
|
||||||
SafeBlockHash: block.Hash(),
|
SafeBlockHash: block.Hash(),
|
||||||
FinalizedBlockHash: block.Hash(),
|
FinalizedBlockHash: block.Hash(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
|
if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
|
||||||
t.Fatalf("Failed to insert block: %v", err)
|
t.Fatalf("Failed to insert block: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ethservice.BlockChain().CurrentBlock().Number.Uint64() != block.NumberU64() {
|
if ethservice.BlockChain().CurrentBlock().Number.Uint64() != block.NumberU64() {
|
||||||
t.Fatalf("Chain head should be updated")
|
t.Fatalf("Chain head should be updated")
|
||||||
}
|
}
|
||||||
|
|
@ -487,38 +517,48 @@ func TestFullAPI(t *testing.T) {
|
||||||
func setupBlocks(t *testing.T, ethservice *eth.Ethereum, n int, parent *types.Header, callback func(parent *types.Header), withdrawals [][]*types.Withdrawal) []*types.Header {
|
func setupBlocks(t *testing.T, ethservice *eth.Ethereum, n int, parent *types.Header, callback func(parent *types.Header), withdrawals [][]*types.Withdrawal) []*types.Header {
|
||||||
api := NewConsensusAPI(ethservice)
|
api := NewConsensusAPI(ethservice)
|
||||||
var blocks []*types.Header
|
var blocks []*types.Header
|
||||||
|
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
callback(parent)
|
callback(parent)
|
||||||
|
|
||||||
var w []*types.Withdrawal
|
var w []*types.Withdrawal
|
||||||
|
|
||||||
if withdrawals != nil {
|
if withdrawals != nil {
|
||||||
w = withdrawals[i]
|
w = withdrawals[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
payload := getNewPayload(t, api, parent, w)
|
payload := getNewPayload(t, api, parent, w)
|
||||||
execResp, err := api.NewPayloadV2(*payload)
|
execResp, err := api.NewPayloadV2(*payload)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't execute payload: %v", err)
|
t.Fatalf("can't execute payload: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if execResp.Status != engine.VALID {
|
if execResp.Status != engine.VALID {
|
||||||
t.Fatalf("invalid status: %v", execResp.Status)
|
t.Fatalf("invalid status: %v", execResp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
fcState := engine.ForkchoiceStateV1{
|
fcState := engine.ForkchoiceStateV1{
|
||||||
HeadBlockHash: payload.BlockHash,
|
HeadBlockHash: payload.BlockHash,
|
||||||
SafeBlockHash: payload.ParentHash,
|
SafeBlockHash: payload.ParentHash,
|
||||||
FinalizedBlockHash: payload.ParentHash,
|
FinalizedBlockHash: payload.ParentHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
|
if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
|
||||||
t.Fatalf("Failed to insert block: %v", err)
|
t.Fatalf("Failed to insert block: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ethservice.BlockChain().CurrentBlock().Number.Uint64() != payload.Number {
|
if ethservice.BlockChain().CurrentBlock().Number.Uint64() != payload.Number {
|
||||||
t.Fatal("Chain head should be updated")
|
t.Fatal("Chain head should be updated")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ethservice.BlockChain().CurrentFinalBlock().Number.Uint64() != payload.Number-1 {
|
if ethservice.BlockChain().CurrentFinalBlock().Number.Uint64() != payload.Number-1 {
|
||||||
t.Fatal("Finalized block should be updated")
|
t.Fatal("Finalized block should be updated")
|
||||||
}
|
}
|
||||||
parent = ethservice.BlockChain().CurrentBlock()
|
parent = ethservice.BlockChain().CurrentBlock()
|
||||||
blocks = append(blocks, parent)
|
blocks = append(blocks, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
return blocks
|
return blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -588,6 +628,7 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
|
||||||
|
|
||||||
genesis, preMergeBlocks := generateMergeChain(10, false)
|
genesis, preMergeBlocks := generateMergeChain(10, false)
|
||||||
n, ethservice := startEthService(t, genesis, preMergeBlocks)
|
n, ethservice := startEthService(t, genesis, preMergeBlocks)
|
||||||
|
|
||||||
defer n.Close()
|
defer n.Close()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -597,6 +638,7 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
|
||||||
// This EVM code generates a log when the contract is created.
|
// This EVM code generates a log when the contract is created.
|
||||||
logCode = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
|
logCode = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
statedb, _ := ethservice.BlockChain().StateAt(parent.Root)
|
statedb, _ := ethservice.BlockChain().StateAt(parent.Root)
|
||||||
tx := types.MustSignNewTx(testKey, signer, &types.LegacyTx{
|
tx := types.MustSignNewTx(testKey, signer, &types.LegacyTx{
|
||||||
|
|
@ -607,6 +649,7 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
|
||||||
Data: logCode,
|
Data: logCode,
|
||||||
})
|
})
|
||||||
ethservice.TxPool().AddRemotesSync([]*types.Transaction{tx})
|
ethservice.TxPool().AddRemotesSync([]*types.Transaction{tx})
|
||||||
|
|
||||||
var (
|
var (
|
||||||
params = engine.PayloadAttributes{
|
params = engine.PayloadAttributes{
|
||||||
Timestamp: parent.Time + 1,
|
Timestamp: parent.Time + 1,
|
||||||
|
|
@ -622,45 +665,59 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
|
||||||
resp engine.ForkChoiceResponse
|
resp engine.ForkChoiceResponse
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; ; i++ {
|
for i := 0; ; i++ {
|
||||||
if resp, err = api.ForkchoiceUpdatedV1(fcState, ¶ms); err != nil {
|
if resp, err = api.ForkchoiceUpdatedV1(fcState, ¶ms); err != nil {
|
||||||
t.Fatalf("error preparing payload, err=%v", err)
|
t.Fatalf("error preparing payload, err=%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.PayloadStatus.Status != engine.VALID {
|
if resp.PayloadStatus.Status != engine.VALID {
|
||||||
t.Fatalf("error preparing payload, invalid status: %v", resp.PayloadStatus.Status)
|
t.Fatalf("error preparing payload, invalid status: %v", resp.PayloadStatus.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
// give the payload some time to be built
|
// give the payload some time to be built
|
||||||
time.Sleep(50 * time.Millisecond)
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
|
||||||
if payload, err = api.GetPayloadV1(*resp.PayloadID); err != nil {
|
if payload, err = api.GetPayloadV1(*resp.PayloadID); err != nil {
|
||||||
t.Fatalf("can't get payload: %v", err)
|
t.Fatalf("can't get payload: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(payload.Transactions) > 0 {
|
if len(payload.Transactions) > 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// No luck this time we need to update the params and try again.
|
// No luck this time we need to update the params and try again.
|
||||||
params.Timestamp = params.Timestamp + 1
|
params.Timestamp = params.Timestamp + 1
|
||||||
|
|
||||||
if i > 10 {
|
if i > 10 {
|
||||||
t.Fatalf("payload should not be empty")
|
t.Fatalf("payload should not be empty")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
execResp, err := api.NewPayloadV1(*payload)
|
execResp, err := api.NewPayloadV1(*payload)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't execute payload: %v", err)
|
t.Fatalf("can't execute payload: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if execResp.Status != engine.VALID {
|
if execResp.Status != engine.VALID {
|
||||||
t.Fatalf("invalid status: %v", execResp.Status)
|
t.Fatalf("invalid status: %v", execResp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
fcState = engine.ForkchoiceStateV1{
|
fcState = engine.ForkchoiceStateV1{
|
||||||
HeadBlockHash: payload.BlockHash,
|
HeadBlockHash: payload.BlockHash,
|
||||||
SafeBlockHash: payload.ParentHash,
|
SafeBlockHash: payload.ParentHash,
|
||||||
FinalizedBlockHash: payload.ParentHash,
|
FinalizedBlockHash: payload.ParentHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
|
if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
|
||||||
t.Fatalf("Failed to insert block: %v", err)
|
t.Fatalf("Failed to insert block: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ethservice.BlockChain().CurrentBlock().Number.Uint64() != payload.Number {
|
if ethservice.BlockChain().CurrentBlock().Number.Uint64() != payload.Number {
|
||||||
t.Fatalf("Chain head should be updated")
|
t.Fatalf("Chain head should be updated")
|
||||||
}
|
}
|
||||||
|
|
||||||
parent = ethservice.BlockChain().CurrentBlock()
|
parent = ethservice.BlockChain().CurrentBlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -674,9 +731,11 @@ func assembleBlock(api *ConsensusAPI, parentHash common.Hash, params *engine.Pay
|
||||||
Withdrawals: params.Withdrawals,
|
Withdrawals: params.Withdrawals,
|
||||||
}
|
}
|
||||||
payload, err := api.eth.Miner().BuildPayload(args)
|
payload, err := api.eth.Miner().BuildPayload(args)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return payload.ResolveFull().ExecutionPayload, nil
|
return payload.ResolveFull().ExecutionPayload, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -685,6 +744,7 @@ func TestEmptyBlocks(t *testing.T) {
|
||||||
|
|
||||||
genesis, preMergeBlocks := generateMergeChain(10, false)
|
genesis, preMergeBlocks := generateMergeChain(10, false)
|
||||||
n, ethservice := startEthService(t, genesis, preMergeBlocks)
|
n, ethservice := startEthService(t, genesis, preMergeBlocks)
|
||||||
|
|
||||||
defer n.Close()
|
defer n.Close()
|
||||||
|
|
||||||
commonAncestor := ethservice.BlockChain().CurrentBlock()
|
commonAncestor := ethservice.BlockChain().CurrentBlock()
|
||||||
|
|
@ -700,9 +760,11 @@ func TestEmptyBlocks(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if status.Status != engine.VALID {
|
if status.Status != engine.VALID {
|
||||||
t.Errorf("invalid status: expected VALID got: %v", status.Status)
|
t.Errorf("invalid status: expected VALID got: %v", status.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(status.LatestValidHash[:], payload.BlockHash[:]) {
|
if !bytes.Equal(status.LatestValidHash[:], payload.BlockHash[:]) {
|
||||||
t.Fatalf("invalid LVH: got %v want %v", status.LatestValidHash, payload.BlockHash)
|
t.Fatalf("invalid LVH: got %v want %v", status.LatestValidHash, payload.BlockHash)
|
||||||
}
|
}
|
||||||
|
|
@ -716,6 +778,7 @@ func TestEmptyBlocks(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if status.Status != engine.INVALID {
|
if status.Status != engine.INVALID {
|
||||||
t.Errorf("invalid status: expected INVALID got: %v", status.Status)
|
t.Errorf("invalid status: expected INVALID got: %v", status.Status)
|
||||||
}
|
}
|
||||||
|
|
@ -734,9 +797,11 @@ func TestEmptyBlocks(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if status.Status != engine.SYNCING {
|
if status.Status != engine.SYNCING {
|
||||||
t.Errorf("invalid status: expected SYNCING got: %v", status.Status)
|
t.Errorf("invalid status: expected SYNCING got: %v", status.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
if status.LatestValidHash != nil {
|
if status.LatestValidHash != nil {
|
||||||
t.Fatalf("invalid LVH: got %v wanted nil", status.LatestValidHash)
|
t.Fatalf("invalid LVH: got %v wanted nil", status.LatestValidHash)
|
||||||
}
|
}
|
||||||
|
|
@ -756,6 +821,7 @@ func getNewPayload(t *testing.T, api *ConsensusAPI, parent *types.Header, withdr
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return payload
|
return payload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -765,6 +831,7 @@ func setBlockhash(data *engine.ExecutableData) *engine.ExecutableData {
|
||||||
txs, _ := decodeTransactions(data.Transactions)
|
txs, _ := decodeTransactions(data.Transactions)
|
||||||
number := big.NewInt(0)
|
number := big.NewInt(0)
|
||||||
number.SetUint64(data.Number)
|
number.SetUint64(data.Number)
|
||||||
|
|
||||||
header := &types.Header{
|
header := &types.Header{
|
||||||
ParentHash: data.ParentHash,
|
ParentHash: data.ParentHash,
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
|
|
@ -784,18 +851,22 @@ func setBlockhash(data *engine.ExecutableData) *engine.ExecutableData {
|
||||||
}
|
}
|
||||||
block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */)
|
block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */)
|
||||||
data.BlockHash = block.Hash()
|
data.BlockHash = block.Hash()
|
||||||
|
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeTransactions(enc [][]byte) ([]*types.Transaction, error) {
|
func decodeTransactions(enc [][]byte) ([]*types.Transaction, error) {
|
||||||
var txs = make([]*types.Transaction, len(enc))
|
var txs = make([]*types.Transaction, len(enc))
|
||||||
|
|
||||||
for i, encTx := range enc {
|
for i, encTx := range enc {
|
||||||
var tx types.Transaction
|
var tx types.Transaction
|
||||||
if err := tx.UnmarshalBinary(encTx); err != nil {
|
if err := tx.UnmarshalBinary(encTx); err != nil {
|
||||||
return nil, fmt.Errorf("invalid transaction %d: %v", i, err)
|
return nil, fmt.Errorf("invalid transaction %d: %v", i, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
txs[i] = &tx
|
txs[i] = &tx
|
||||||
}
|
}
|
||||||
|
|
||||||
return txs, nil
|
return txs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -806,13 +877,16 @@ func TestTrickRemoteBlockCache(t *testing.T) {
|
||||||
genesis, preMergeBlocks := generateMergeChain(10, false)
|
genesis, preMergeBlocks := generateMergeChain(10, false)
|
||||||
nodeA, ethserviceA := startEthService(t, genesis, preMergeBlocks)
|
nodeA, ethserviceA := startEthService(t, genesis, preMergeBlocks)
|
||||||
nodeB, ethserviceB := startEthService(t, genesis, preMergeBlocks)
|
nodeB, ethserviceB := startEthService(t, genesis, preMergeBlocks)
|
||||||
|
|
||||||
defer nodeA.Close()
|
defer nodeA.Close()
|
||||||
defer nodeB.Close()
|
defer nodeB.Close()
|
||||||
|
|
||||||
for nodeB.Server().NodeInfo().Ports.Listener == 0 {
|
for nodeB.Server().NodeInfo().Ports.Listener == 0 {
|
||||||
time.Sleep(250 * time.Millisecond)
|
time.Sleep(250 * time.Millisecond)
|
||||||
}
|
}
|
||||||
nodeA.Server().AddPeer(nodeB.Server().Self())
|
nodeA.Server().AddPeer(nodeB.Server().Self())
|
||||||
nodeB.Server().AddPeer(nodeA.Server().Self())
|
nodeB.Server().AddPeer(nodeA.Server().Self())
|
||||||
|
|
||||||
apiA := NewConsensusAPI(ethserviceA)
|
apiA := NewConsensusAPI(ethserviceA)
|
||||||
apiB := NewConsensusAPI(ethserviceB)
|
apiB := NewConsensusAPI(ethserviceB)
|
||||||
|
|
||||||
|
|
@ -850,6 +924,7 @@ func TestTrickRemoteBlockCache(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if status.Status == engine.VALID {
|
if status.Status == engine.VALID {
|
||||||
t.Error("invalid status: VALID on an invalid chain")
|
t.Error("invalid status: VALID on an invalid chain")
|
||||||
}
|
}
|
||||||
|
|
@ -858,9 +933,11 @@ func TestTrickRemoteBlockCache(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.PayloadStatus.Status == engine.VALID {
|
if resp.PayloadStatus.Status == engine.VALID {
|
||||||
t.Error("invalid status: VALID on an invalid chain")
|
t.Error("invalid status: VALID on an invalid chain")
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -871,6 +948,7 @@ func TestInvalidBloom(t *testing.T) {
|
||||||
genesis, preMergeBlocks := generateMergeChain(10, false)
|
genesis, preMergeBlocks := generateMergeChain(10, false)
|
||||||
n, ethservice := startEthService(t, genesis, preMergeBlocks)
|
n, ethservice := startEthService(t, genesis, preMergeBlocks)
|
||||||
ethservice.Merger().ReachTTD()
|
ethservice.Merger().ReachTTD()
|
||||||
|
|
||||||
defer n.Close()
|
defer n.Close()
|
||||||
|
|
||||||
commonAncestor := ethservice.BlockChain().CurrentBlock()
|
commonAncestor := ethservice.BlockChain().CurrentBlock()
|
||||||
|
|
@ -883,9 +961,11 @@ func TestInvalidBloom(t *testing.T) {
|
||||||
payload := getNewPayload(t, api, commonAncestor, nil)
|
payload := getNewPayload(t, api, commonAncestor, nil)
|
||||||
payload.LogsBloom = append(payload.LogsBloom, byte(1))
|
payload.LogsBloom = append(payload.LogsBloom, byte(1))
|
||||||
status, err := api.NewPayloadV1(*payload)
|
status, err := api.NewPayloadV1(*payload)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if status.Status != engine.INVALID {
|
if status.Status != engine.INVALID {
|
||||||
t.Errorf("invalid status: expected INVALID got: %v", status.Status)
|
t.Errorf("invalid status: expected INVALID got: %v", status.Status)
|
||||||
}
|
}
|
||||||
|
|
@ -896,7 +976,9 @@ func TestNewPayloadOnInvalidTerminalBlock(t *testing.T) {
|
||||||
|
|
||||||
genesis, preMergeBlocks := generateMergeChain(100, false)
|
genesis, preMergeBlocks := generateMergeChain(100, false)
|
||||||
n, ethservice := startEthService(t, genesis, preMergeBlocks)
|
n, ethservice := startEthService(t, genesis, preMergeBlocks)
|
||||||
|
|
||||||
defer n.Close()
|
defer n.Close()
|
||||||
|
|
||||||
api := NewConsensusAPI(ethservice)
|
api := NewConsensusAPI(ethservice)
|
||||||
|
|
||||||
// Test parent already post TTD in FCU
|
// Test parent already post TTD in FCU
|
||||||
|
|
@ -907,9 +989,11 @@ func TestNewPayloadOnInvalidTerminalBlock(t *testing.T) {
|
||||||
FinalizedBlockHash: common.Hash{},
|
FinalizedBlockHash: common.Hash{},
|
||||||
}
|
}
|
||||||
resp, err := api.ForkchoiceUpdatedV1(fcState, nil)
|
resp, err := api.ForkchoiceUpdatedV1(fcState, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error sending forkchoice, err=%v", err)
|
t.Fatalf("error sending forkchoice, err=%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.PayloadStatus != engine.INVALID_TERMINAL_BLOCK {
|
if resp.PayloadStatus != engine.INVALID_TERMINAL_BLOCK {
|
||||||
t.Fatalf("error sending invalid forkchoice, invalid status: %v", resp.PayloadStatus.Status)
|
t.Fatalf("error sending invalid forkchoice, invalid status: %v", resp.PayloadStatus.Status)
|
||||||
}
|
}
|
||||||
|
|
@ -922,9 +1006,11 @@ func TestNewPayloadOnInvalidTerminalBlock(t *testing.T) {
|
||||||
FeeRecipient: parent.Coinbase(),
|
FeeRecipient: parent.Coinbase(),
|
||||||
}
|
}
|
||||||
payload, err := api.eth.Miner().BuildPayload(args)
|
payload, err := api.eth.Miner().BuildPayload(args)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error preparing payload, err=%v", err)
|
t.Fatalf("error preparing payload, err=%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data := *payload.Resolve().ExecutionPayload
|
data := *payload.Resolve().ExecutionPayload
|
||||||
// We need to recompute the blockhash, since the miner computes a wrong (correct) blockhash
|
// We need to recompute the blockhash, since the miner computes a wrong (correct) blockhash
|
||||||
txs, _ := decodeTransactions(data.Transactions)
|
txs, _ := decodeTransactions(data.Transactions)
|
||||||
|
|
@ -952,6 +1038,7 @@ func TestNewPayloadOnInvalidTerminalBlock(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error sending NewPayload, err=%v", err)
|
t.Fatalf("error sending NewPayload, err=%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp2 != engine.INVALID_TERMINAL_BLOCK {
|
if resp2 != engine.INVALID_TERMINAL_BLOCK {
|
||||||
t.Fatalf("error sending invalid forkchoice, invalid status: %v", resp.PayloadStatus.Status)
|
t.Fatalf("error sending invalid forkchoice, invalid status: %v", resp.PayloadStatus.Status)
|
||||||
}
|
}
|
||||||
|
|
@ -965,12 +1052,14 @@ func TestSimultaneousNewBlock(t *testing.T) {
|
||||||
|
|
||||||
genesis, preMergeBlocks := generateMergeChain(10, false)
|
genesis, preMergeBlocks := generateMergeChain(10, false)
|
||||||
n, ethservice := startEthService(t, genesis, preMergeBlocks)
|
n, ethservice := startEthService(t, genesis, preMergeBlocks)
|
||||||
|
|
||||||
defer n.Close()
|
defer n.Close()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
api = NewConsensusAPI(ethservice)
|
api = NewConsensusAPI(ethservice)
|
||||||
parent = preMergeBlocks[len(preMergeBlocks)-1]
|
parent = preMergeBlocks[len(preMergeBlocks)-1]
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
execData, err := assembleBlock(api, parent.Hash(), &engine.PayloadAttributes{
|
execData, err := assembleBlock(api, parent.Hash(), &engine.PayloadAttributes{
|
||||||
Timestamp: parent.Time() + 5,
|
Timestamp: parent.Time() + 5,
|
||||||
|
|
@ -1005,13 +1094,17 @@ func TestSimultaneousNewBlock(t *testing.T) {
|
||||||
t.Fatal(testErr)
|
t.Fatal(testErr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
block, err := engine.ExecutableDataToBlock(*execData)
|
block, err := engine.ExecutableDataToBlock(*execData)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to convert executable data to block %v", err)
|
t.Fatalf("Failed to convert executable data to block %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ethservice.BlockChain().CurrentBlock().Number.Uint64() != block.NumberU64()-1 {
|
if ethservice.BlockChain().CurrentBlock().Number.Uint64() != block.NumberU64()-1 {
|
||||||
t.Fatalf("Chain head shouldn't be updated")
|
t.Fatalf("Chain head shouldn't be updated")
|
||||||
}
|
}
|
||||||
|
|
||||||
fcState := engine.ForkchoiceStateV1{
|
fcState := engine.ForkchoiceStateV1{
|
||||||
HeadBlockHash: block.Hash(),
|
HeadBlockHash: block.Hash(),
|
||||||
SafeBlockHash: block.Hash(),
|
SafeBlockHash: block.Hash(),
|
||||||
|
|
@ -1040,9 +1133,11 @@ func TestSimultaneousNewBlock(t *testing.T) {
|
||||||
t.Fatal(testErr)
|
t.Fatal(testErr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if have, want := ethservice.BlockChain().CurrentBlock().Number.Uint64(), block.NumberU64(); have != want {
|
if have, want := ethservice.BlockChain().CurrentBlock().Number.Uint64(), block.NumberU64(); have != want {
|
||||||
t.Fatalf("Chain head should be updated, have %d want %d", have, want)
|
t.Fatalf("Chain head should be updated, have %d want %d", have, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
parent = block
|
parent = block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1059,6 +1154,7 @@ func TestWithdrawals(t *testing.T) {
|
||||||
|
|
||||||
n, ethservice := startEthService(t, genesis, blocks)
|
n, ethservice := startEthService(t, genesis, blocks)
|
||||||
ethservice.Merger().ReachTTD()
|
ethservice.Merger().ReachTTD()
|
||||||
|
|
||||||
defer n.Close()
|
defer n.Close()
|
||||||
|
|
||||||
api := NewConsensusAPI(ethservice)
|
api := NewConsensusAPI(ethservice)
|
||||||
|
|
@ -1073,9 +1169,11 @@ func TestWithdrawals(t *testing.T) {
|
||||||
HeadBlockHash: parent.Hash(),
|
HeadBlockHash: parent.Hash(),
|
||||||
}
|
}
|
||||||
resp, err := api.ForkchoiceUpdatedV2(fcState, &blockParams)
|
resp, err := api.ForkchoiceUpdatedV2(fcState, &blockParams)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error preparing payload, err=%v", err)
|
t.Fatalf("error preparing payload, err=%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.PayloadStatus.Status != engine.VALID {
|
if resp.PayloadStatus.Status != engine.VALID {
|
||||||
t.Fatalf("unexpected status (got: %s, want: %s)", resp.PayloadStatus.Status, engine.VALID)
|
t.Fatalf("unexpected status (got: %s, want: %s)", resp.PayloadStatus.Status, engine.VALID)
|
||||||
}
|
}
|
||||||
|
|
@ -1089,9 +1187,11 @@ func TestWithdrawals(t *testing.T) {
|
||||||
Withdrawals: blockParams.Withdrawals,
|
Withdrawals: blockParams.Withdrawals,
|
||||||
}).Id()
|
}).Id()
|
||||||
execData, err := api.GetPayloadV2(payloadID)
|
execData, err := api.GetPayloadV2(payloadID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error getting payload, err=%v", err)
|
t.Fatalf("error getting payload, err=%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if execData.ExecutionPayload.StateRoot != parent.Root {
|
if execData.ExecutionPayload.StateRoot != parent.Root {
|
||||||
t.Fatalf("mismatch state roots (got: %s, want: %s)", execData.ExecutionPayload.StateRoot, blocks[8].Root())
|
t.Fatalf("mismatch state roots (got: %s, want: %s)", execData.ExecutionPayload.StateRoot, blocks[8].Root())
|
||||||
}
|
}
|
||||||
|
|
@ -1123,6 +1223,7 @@ func TestWithdrawals(t *testing.T) {
|
||||||
}
|
}
|
||||||
fcState.HeadBlockHash = execData.ExecutionPayload.BlockHash
|
fcState.HeadBlockHash = execData.ExecutionPayload.BlockHash
|
||||||
_, err = api.ForkchoiceUpdatedV2(fcState, &blockParams)
|
_, err = api.ForkchoiceUpdatedV2(fcState, &blockParams)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error preparing payload, err=%v", err)
|
t.Fatalf("error preparing payload, err=%v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1136,9 +1237,11 @@ func TestWithdrawals(t *testing.T) {
|
||||||
Withdrawals: blockParams.Withdrawals,
|
Withdrawals: blockParams.Withdrawals,
|
||||||
}).Id()
|
}).Id()
|
||||||
execData, err = api.GetPayloadV2(payloadID)
|
execData, err = api.GetPayloadV2(payloadID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error getting payload, err=%v", err)
|
t.Fatalf("error getting payload, err=%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if status, err := api.NewPayloadV2(*execData.ExecutionPayload); err != nil {
|
if status, err := api.NewPayloadV2(*execData.ExecutionPayload); err != nil {
|
||||||
t.Fatalf("error validating payload: %v", err)
|
t.Fatalf("error validating payload: %v", err)
|
||||||
} else if status.Status != engine.VALID {
|
} else if status.Status != engine.VALID {
|
||||||
|
|
@ -1148,6 +1251,7 @@ func TestWithdrawals(t *testing.T) {
|
||||||
// 11: set block as head.
|
// 11: set block as head.
|
||||||
fcState.HeadBlockHash = execData.ExecutionPayload.BlockHash
|
fcState.HeadBlockHash = execData.ExecutionPayload.BlockHash
|
||||||
_, err = api.ForkchoiceUpdatedV2(fcState, nil)
|
_, err = api.ForkchoiceUpdatedV2(fcState, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error preparing payload, err=%v", err)
|
t.Fatalf("error preparing payload, err=%v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1157,6 +1261,7 @@ func TestWithdrawals(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to load db: %v", err)
|
t.Fatalf("unable to load db: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, w := range blockParams.Withdrawals {
|
for i, w := range blockParams.Withdrawals {
|
||||||
// w.Amount is in gwei, balance in wei
|
// w.Amount is in gwei, balance in wei
|
||||||
if db.GetBalance(w.Address).Uint64() != w.Amount*params.GWei {
|
if db.GetBalance(w.Address).Uint64() != w.Amount*params.GWei {
|
||||||
|
|
@ -1175,6 +1280,7 @@ func TestNilWithdrawals(t *testing.T) {
|
||||||
|
|
||||||
n, ethservice := startEthService(t, genesis, blocks)
|
n, ethservice := startEthService(t, genesis, blocks)
|
||||||
ethservice.Merger().ReachTTD()
|
ethservice.Merger().ReachTTD()
|
||||||
|
|
||||||
defer n.Close()
|
defer n.Close()
|
||||||
|
|
||||||
api := NewConsensusAPI(ethservice)
|
api := NewConsensusAPI(ethservice)
|
||||||
|
|
@ -1185,6 +1291,7 @@ func TestNilWithdrawals(t *testing.T) {
|
||||||
blockParams engine.PayloadAttributes
|
blockParams engine.PayloadAttributes
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []test{
|
tests := []test{
|
||||||
// Before Shanghai
|
// Before Shanghai
|
||||||
{
|
{
|
||||||
|
|
@ -1254,8 +1361,10 @@ func TestNilWithdrawals(t *testing.T) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("wanted error on fcuv2 with invalid withdrawals")
|
t.Fatal("wanted error on fcuv2 with invalid withdrawals")
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error preparing payload, err=%v", err)
|
t.Fatalf("error preparing payload, err=%v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1268,9 +1377,11 @@ func TestNilWithdrawals(t *testing.T) {
|
||||||
Random: test.blockParams.Random,
|
Random: test.blockParams.Random,
|
||||||
}).Id()
|
}).Id()
|
||||||
execData, err := api.GetPayloadV2(payloadID)
|
execData, err := api.GetPayloadV2(payloadID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error getting payload, err=%v", err)
|
t.Fatalf("error getting payload, err=%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if status, err := api.NewPayloadV2(*execData.ExecutionPayload); err != nil {
|
if status, err := api.NewPayloadV2(*execData.ExecutionPayload); err != nil {
|
||||||
t.Fatalf("error validating payload: %v", err)
|
t.Fatalf("error validating payload: %v", err)
|
||||||
} else if status.Status != engine.VALID {
|
} else if status.Status != engine.VALID {
|
||||||
|
|
@ -1304,9 +1415,12 @@ func setupBodies(t *testing.T) (*node.Node, *eth.Ethereum, []*types.Block) {
|
||||||
withdrawals := make([][]*types.Withdrawal, 10)
|
withdrawals := make([][]*types.Withdrawal, 10)
|
||||||
withdrawals[0] = nil // should be filtered out by miner
|
withdrawals[0] = nil // should be filtered out by miner
|
||||||
withdrawals[1] = make([]*types.Withdrawal, 0)
|
withdrawals[1] = make([]*types.Withdrawal, 0)
|
||||||
|
|
||||||
for i := 2; i < len(withdrawals); i++ {
|
for i := 2; i < len(withdrawals); i++ {
|
||||||
addr := make([]byte, 20)
|
addr := make([]byte, 20)
|
||||||
|
|
||||||
crand.Read(addr)
|
crand.Read(addr)
|
||||||
|
|
||||||
withdrawals[i] = []*types.Withdrawal{
|
withdrawals[i] = []*types.Withdrawal{
|
||||||
{Index: rand.Uint64(), Validator: rand.Uint64(), Amount: rand.Uint64(), Address: common.BytesToAddress(addr)},
|
{Index: rand.Uint64(), Validator: rand.Uint64(), Amount: rand.Uint64(), Address: common.BytesToAddress(addr)},
|
||||||
}
|
}
|
||||||
|
|
@ -1314,9 +1428,11 @@ func setupBodies(t *testing.T) (*node.Node, *eth.Ethereum, []*types.Block) {
|
||||||
|
|
||||||
postShanghaiHeaders := setupBlocks(t, ethservice, 10, parent, callback, withdrawals)
|
postShanghaiHeaders := setupBlocks(t, ethservice, 10, parent, callback, withdrawals)
|
||||||
postShanghaiBlocks := make([]*types.Block, len(postShanghaiHeaders))
|
postShanghaiBlocks := make([]*types.Block, len(postShanghaiHeaders))
|
||||||
|
|
||||||
for i, header := range postShanghaiHeaders {
|
for i, header := range postShanghaiHeaders {
|
||||||
postShanghaiBlocks[i] = ethservice.BlockChain().GetBlock(header.Hash(), header.Number.Uint64())
|
postShanghaiBlocks[i] = ethservice.BlockChain().GetBlock(header.Hash(), header.Number.Uint64())
|
||||||
}
|
}
|
||||||
|
|
||||||
return n, ethservice, append(blocks, postShanghaiBlocks...)
|
return n, ethservice, append(blocks, postShanghaiBlocks...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1325,6 +1441,7 @@ func allHashes(blocks []*types.Block) []common.Hash {
|
||||||
for _, b := range blocks {
|
for _, b := range blocks {
|
||||||
hashes = append(hashes, b.Hash())
|
hashes = append(hashes, b.Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
return hashes
|
return hashes
|
||||||
}
|
}
|
||||||
func allBodies(blocks []*types.Block) []*types.Body {
|
func allBodies(blocks []*types.Block) []*types.Body {
|
||||||
|
|
@ -1332,6 +1449,7 @@ func allBodies(blocks []*types.Block) []*types.Body {
|
||||||
for _, b := range blocks {
|
for _, b := range blocks {
|
||||||
bodies = append(bodies, b.Body())
|
bodies = append(bodies, b.Body())
|
||||||
}
|
}
|
||||||
|
|
||||||
return bodies
|
return bodies
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1340,6 +1458,7 @@ func TestGetBlockBodiesByHash(t *testing.T) {
|
||||||
|
|
||||||
node, eth, blocks := setupBodies(t)
|
node, eth, blocks := setupBodies(t)
|
||||||
api := NewConsensusAPI(eth)
|
api := NewConsensusAPI(eth)
|
||||||
|
|
||||||
defer node.Close()
|
defer node.Close()
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
|
@ -1398,6 +1517,7 @@ func TestGetBlockBodiesByRange(t *testing.T) {
|
||||||
|
|
||||||
node, eth, blocks := setupBodies(t)
|
node, eth, blocks := setupBodies(t)
|
||||||
api := NewConsensusAPI(eth)
|
api := NewConsensusAPI(eth)
|
||||||
|
|
||||||
defer node.Close()
|
defer node.Close()
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
|
@ -1464,6 +1584,7 @@ func TestGetBlockBodiesByRange(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(result) == len(test.results) {
|
if len(result) == len(test.results) {
|
||||||
for i, r := range result {
|
for i, r := range result {
|
||||||
if !equalBody(test.results[i], r) {
|
if !equalBody(test.results[i], r) {
|
||||||
|
|
@ -1481,7 +1602,9 @@ func TestGetBlockBodiesByRangeInvalidParams(t *testing.T) {
|
||||||
|
|
||||||
node, eth, _ := setupBodies(t)
|
node, eth, _ := setupBodies(t)
|
||||||
api := NewConsensusAPI(eth)
|
api := NewConsensusAPI(eth)
|
||||||
|
|
||||||
defer node.Close()
|
defer node.Close()
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
start hexutil.Uint64
|
start hexutil.Uint64
|
||||||
count hexutil.Uint64
|
count hexutil.Uint64
|
||||||
|
|
@ -1512,11 +1635,13 @@ func TestGetBlockBodiesByRangeInvalidParams(t *testing.T) {
|
||||||
want: engine.TooLargeRequest,
|
want: engine.TooLargeRequest,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tc := range tests {
|
for i, tc := range tests {
|
||||||
result, err := api.GetPayloadBodiesByRangeV1(tc.start, tc.count)
|
result, err := api.GetPayloadBodiesByRangeV1(tc.start, tc.count)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("test %d: expected error, got %v", i, result)
|
t.Fatalf("test %d: expected error, got %v", i, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
if have, want := err.Error(), tc.want.Error(); have != want {
|
if have, want := err.Error(), tc.want.Error(); have != want {
|
||||||
t.Fatalf("test %d: have %s, want %s", i, have, want)
|
t.Fatalf("test %d: have %s, want %s", i, have, want)
|
||||||
}
|
}
|
||||||
|
|
@ -1529,14 +1654,17 @@ func equalBody(a *types.Body, b *engine.ExecutionPayloadBodyV1) bool {
|
||||||
} else if a == nil || b == nil {
|
} else if a == nil || b == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(a.Transactions) != len(b.TransactionData) {
|
if len(a.Transactions) != len(b.TransactionData) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tx := range a.Transactions {
|
for i, tx := range a.Transactions {
|
||||||
data, _ := tx.MarshalBinary()
|
data, _ := tx.MarshalBinary()
|
||||||
if !bytes.Equal(data, b.TransactionData[i]) {
|
if !bytes.Equal(data, b.TransactionData[i]) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return reflect.DeepEqual(a.Withdrawals, b.Withdrawals)
|
return reflect.DeepEqual(a.Withdrawals, b.Withdrawals)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,10 +97,12 @@ func (q *payloadQueue) has(id engine.PayloadID) bool {
|
||||||
if item == nil {
|
if item == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if item.id == id {
|
if item.id == id {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,12 +47,14 @@ func RegisterFullSyncTester(stack *node.Node, backend *eth.Ethereum, block *type
|
||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
}
|
}
|
||||||
stack.RegisterLifecycle(cl)
|
stack.RegisterLifecycle(cl)
|
||||||
|
|
||||||
return cl, nil
|
return cl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start launches the beacon sync with provided sync target.
|
// Start launches the beacon sync with provided sync target.
|
||||||
func (tester *FullSyncTester) Start() error {
|
func (tester *FullSyncTester) Start() error {
|
||||||
tester.wg.Add(1)
|
tester.wg.Add(1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer tester.wg.Done()
|
defer tester.wg.Done()
|
||||||
|
|
||||||
|
|
@ -85,6 +87,7 @@ func (tester *FullSyncTester) Start() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,5 +96,6 @@ func (tester *FullSyncTester) Start() error {
|
||||||
func (tester *FullSyncTester) Stop() error {
|
func (tester *FullSyncTester) Stop() error {
|
||||||
close(tester.closed)
|
close(tester.closed)
|
||||||
tester.wg.Wait()
|
tester.wg.Wait()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,7 @@ func (d *Downloader) findBeaconAncestor() (uint64, error) {
|
||||||
// until sync errors or is finished.
|
// until sync errors or is finished.
|
||||||
func (d *Downloader) fetchBeaconHeaders(from uint64) error {
|
func (d *Downloader) fetchBeaconHeaders(from uint64) error {
|
||||||
var head *types.Header
|
var head *types.Header
|
||||||
|
|
||||||
_, tail, _, err := d.skeleton.Bounds()
|
_, tail, _, err := d.skeleton.Bounds()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -280,11 +281,13 @@ func (d *Downloader) fetchBeaconHeaders(from uint64) error {
|
||||||
// and it should only happen when there are less than 64 post-merge
|
// and it should only happen when there are less than 64 post-merge
|
||||||
// blocks in the network.
|
// blocks in the network.
|
||||||
var localHeaders []*types.Header
|
var localHeaders []*types.Header
|
||||||
|
|
||||||
if from < tail.Number.Uint64() {
|
if from < tail.Number.Uint64() {
|
||||||
count := tail.Number.Uint64() - from
|
count := tail.Number.Uint64() - from
|
||||||
if count > uint64(fsMinFullBlocks) {
|
if count > uint64(fsMinFullBlocks) {
|
||||||
return fmt.Errorf("invalid origin (%d) of beacon sync (%d)", from, tail.Number)
|
return fmt.Errorf("invalid origin (%d) of beacon sync (%d)", from, tail.Number)
|
||||||
}
|
}
|
||||||
|
|
||||||
localHeaders = d.readHeaderRange(tail, int(count))
|
localHeaders = d.readHeaderRange(tail, int(count))
|
||||||
log.Warn("Retrieved beacon headers from local", "from", from, "count", count)
|
log.Warn("Retrieved beacon headers from local", "from", from, "count", count)
|
||||||
}
|
}
|
||||||
|
|
@ -305,6 +308,7 @@ func (d *Downloader) fetchBeaconHeaders(from uint64) error {
|
||||||
number := head.Number.Uint64() - uint64(fsMinFullBlocks)
|
number := head.Number.Uint64() - uint64(fsMinFullBlocks)
|
||||||
|
|
||||||
log.Warn("Pivot seemingly stale, moving", "old", d.pivotHeader.Number, "new", number)
|
log.Warn("Pivot seemingly stale, moving", "old", d.pivotHeader.Number, "new", number)
|
||||||
|
|
||||||
if d.pivotHeader = d.skeleton.Header(number); d.pivotHeader == nil {
|
if d.pivotHeader = d.skeleton.Header(number); d.pivotHeader == nil {
|
||||||
if number < tail.Number.Uint64() {
|
if number < tail.Number.Uint64() {
|
||||||
dist := tail.Number.Uint64() - number
|
dist := tail.Number.Uint64() - number
|
||||||
|
|
@ -320,6 +324,7 @@ func (d *Downloader) fetchBeaconHeaders(from uint64) error {
|
||||||
if d.pivotHeader == nil {
|
if d.pivotHeader == nil {
|
||||||
log.Error("Pivot header is not found", "number", number)
|
log.Error("Pivot header is not found", "number", number)
|
||||||
d.pivotLock.Unlock()
|
d.pivotLock.Unlock()
|
||||||
|
|
||||||
return errNoPivotHeader
|
return errNoPivotHeader
|
||||||
}
|
}
|
||||||
// Write out the pivot into the database so a rollback beyond
|
// Write out the pivot into the database so a rollback beyond
|
||||||
|
|
@ -350,6 +355,7 @@ func (d *Downloader) fetchBeaconHeaders(from uint64) error {
|
||||||
if header == nil {
|
if header == nil {
|
||||||
return fmt.Errorf("missing beacon header %d", from)
|
return fmt.Errorf("missing beacon header %d", from)
|
||||||
}
|
}
|
||||||
|
|
||||||
headers = append(headers, header)
|
headers = append(headers, header)
|
||||||
hashes = append(hashes, headers[i].Hash())
|
hashes = append(hashes, headers[i].Hash())
|
||||||
from++
|
from++
|
||||||
|
|
|
||||||
|
|
@ -371,6 +371,7 @@ func (d *Downloader) LegacySync(id string, head common.Hash, td, ttd *big.Int, m
|
||||||
if errors.Is(err, ErrMergeTransition) {
|
if errors.Is(err, ErrMergeTransition) {
|
||||||
return err // This is an expected fault, don't keep printing it in a spin-loop
|
return err // This is an expected fault, don't keep printing it in a spin-loop
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Warn("Synchronisation failed, retrying", "err", err)
|
log.Warn("Synchronisation failed, retrying", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -524,9 +525,9 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td, ttd *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If no pivot block was returned, the head is below the min full block
|
// If no pivot block was returned, the head is below the min full block
|
||||||
// threshold (i.e. new chain). In that case we won't really fast sync
|
// threshold (i.e. new chain). In that case we won't really fast sync
|
||||||
// anyway, but still need a valid pivot block to avoid some code hitting
|
// anyway, but still need a valid pivot block to avoid some code hitting
|
||||||
// nil panics on access.
|
// nil panics on access.
|
||||||
if mode == SnapSync && pivot == nil {
|
if mode == SnapSync && pivot == nil {
|
||||||
pivot = d.blockchain.CurrentBlock()
|
pivot = d.blockchain.CurrentBlock()
|
||||||
|
|
@ -568,6 +569,7 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td, ttd *
|
||||||
rawdb.WriteLastPivotNumber(d.stateDB, pivotNumber)
|
rawdb.WriteLastPivotNumber(d.stateDB, pivotNumber)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d.committed.Store(true)
|
d.committed.Store(true)
|
||||||
if mode == SnapSync && pivot.Number.Uint64() != 0 {
|
if mode == SnapSync && pivot.Number.Uint64() != 0 {
|
||||||
d.committed.Store(false)
|
d.committed.Store(false)
|
||||||
|
|
@ -1677,6 +1679,7 @@ func (d *Downloader) processSnapSyncContent() error {
|
||||||
if d.chainInsertHook != nil {
|
if d.chainInsertHook != nil {
|
||||||
d.chainInsertHook(results)
|
d.chainInsertHook(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.reportSnapSyncProgress(false)
|
d.reportSnapSyncProgress(false)
|
||||||
|
|
||||||
// If we haven't downloaded the pivot block yet, check pivot staleness
|
// If we haven't downloaded the pivot block yet, check pivot staleness
|
||||||
|
|
@ -1821,6 +1824,7 @@ func (d *Downloader) commitPivotBlock(result *fetchResult) error {
|
||||||
if err := d.blockchain.SnapSyncCommitHead(block.Hash()); err != nil {
|
if err := d.blockchain.SnapSyncCommitHead(block.Hash()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d.committed.Store(true)
|
d.committed.Store(true)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -1859,17 +1863,22 @@ func (d *Downloader) readHeaderRange(last *types.Header, count int) []*types.Hea
|
||||||
current = last
|
current = last
|
||||||
headers []*types.Header
|
headers []*types.Header
|
||||||
)
|
)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
parent := d.lightchain.GetHeaderByHash(current.ParentHash)
|
parent := d.lightchain.GetHeaderByHash(current.ParentHash)
|
||||||
if parent == nil {
|
if parent == nil {
|
||||||
break // The chain is not continuous, or the chain is exhausted
|
break // The chain is not continuous, or the chain is exhausted
|
||||||
}
|
}
|
||||||
|
|
||||||
headers = append(headers, parent)
|
headers = append(headers, parent)
|
||||||
|
|
||||||
if len(headers) >= count {
|
if len(headers) >= count {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
current = parent
|
current = parent
|
||||||
}
|
}
|
||||||
|
|
||||||
return headers
|
return headers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1889,15 +1898,20 @@ func (d *Downloader) reportSnapSyncProgress(force bool) {
|
||||||
bodyBytes, _ = d.stateDB.AncientSize(rawdb.ChainFreezerBodiesTable)
|
bodyBytes, _ = d.stateDB.AncientSize(rawdb.ChainFreezerBodiesTable)
|
||||||
receiptBytes, _ = d.stateDB.AncientSize(rawdb.ChainFreezerReceiptTable)
|
receiptBytes, _ = d.stateDB.AncientSize(rawdb.ChainFreezerReceiptTable)
|
||||||
)
|
)
|
||||||
|
|
||||||
syncedBytes := common.StorageSize(headerBytes + bodyBytes + receiptBytes)
|
syncedBytes := common.StorageSize(headerBytes + bodyBytes + receiptBytes)
|
||||||
|
|
||||||
if syncedBytes == 0 {
|
if syncedBytes == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
header = d.blockchain.CurrentHeader()
|
header = d.blockchain.CurrentHeader()
|
||||||
block = d.blockchain.CurrentSnapBlock()
|
block = d.blockchain.CurrentSnapBlock()
|
||||||
)
|
)
|
||||||
|
|
||||||
syncedBlocks := block.Number.Uint64() - d.syncStartBlock
|
syncedBlocks := block.Number.Uint64() - d.syncStartBlock
|
||||||
|
|
||||||
if syncedBlocks == 0 {
|
if syncedBlocks == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -1907,12 +1921,14 @@ func (d *Downloader) reportSnapSyncProgress(force bool) {
|
||||||
// We're going to cheat for non-merged networks, but that's fine
|
// We're going to cheat for non-merged networks, but that's fine
|
||||||
latest = d.pivotHeader
|
latest = d.pivotHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
if latest == nil {
|
if latest == nil {
|
||||||
// This should really never happen, but add some defensive code for now.
|
// This should really never happen, but add some defensive code for now.
|
||||||
// TODO(karalabe): Remove it eventually if we don't see it blow.
|
// TODO(karalabe): Remove it eventually if we don't see it blow.
|
||||||
log.Error("Nil latest block in sync progress report")
|
log.Error("Nil latest block in sync progress report")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
left = latest.Number.Uint64() - block.Number.Uint64()
|
left = latest.Number.Uint64() - block.Number.Uint64()
|
||||||
eta = time.Since(d.syncStartTime) / time.Duration(syncedBlocks) * time.Duration(left)
|
eta = time.Since(d.syncStartTime) / time.Duration(syncedBlocks) * time.Duration(left)
|
||||||
|
|
@ -1922,6 +1938,8 @@ func (d *Downloader) reportSnapSyncProgress(force bool) {
|
||||||
bodies = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(block.Number.Uint64()), common.StorageSize(bodyBytes).TerminalString())
|
bodies = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(block.Number.Uint64()), common.StorageSize(bodyBytes).TerminalString())
|
||||||
receipts = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(block.Number.Uint64()), common.StorageSize(receiptBytes).TerminalString())
|
receipts = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(block.Number.Uint64()), common.StorageSize(receiptBytes).TerminalString())
|
||||||
)
|
)
|
||||||
|
|
||||||
log.Info("Syncing: chain download in progress", "synced", progress, "chain", syncedBytes, "headers", headers, "bodies", bodies, "receipts", receipts, "eta", common.PrettyDuration(eta))
|
log.Info("Syncing: chain download in progress", "synced", progress, "chain", syncedBytes, "headers", headers, "bodies", bodies, "receipts", receipts, "eta", common.PrettyDuration(eta))
|
||||||
|
|
||||||
d.syncLogTime = time.Now()
|
d.syncLogTime = time.Now()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,11 @@ func newTesterWithNotification(t *testing.T, success func()) *downloadTester {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
db.Close()
|
db.Close()
|
||||||
})
|
})
|
||||||
|
|
||||||
gspec := &core.Genesis{
|
gspec := &core.Genesis{
|
||||||
Config: params.TestChainConfig,
|
Config: params.TestChainConfig,
|
||||||
Alloc: core.GenesisAlloc{testAddress: {Balance: big.NewInt(1000000000000000)}},
|
Alloc: core.GenesisAlloc{testAddress: {Balance: big.NewInt(1000000000000000)}},
|
||||||
|
|
@ -440,9 +442,11 @@ func assertOwnChain(t *testing.T, tester *downloadTester, length int) {
|
||||||
if hs := int(tester.chain.CurrentHeader().Number.Uint64()) + 1; hs != headers {
|
if hs := int(tester.chain.CurrentHeader().Number.Uint64()) + 1; hs != headers {
|
||||||
t.Fatalf("synchronised headers mismatch: have %v, want %v", hs, headers)
|
t.Fatalf("synchronised headers mismatch: have %v, want %v", hs, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
if bs := int(tester.chain.CurrentBlock().Number.Uint64()) + 1; bs != blocks {
|
if bs := int(tester.chain.CurrentBlock().Number.Uint64()) + 1; bs != blocks {
|
||||||
t.Fatalf("synchronised blocks mismatch: have %v, want %v", bs, blocks)
|
t.Fatalf("synchronised blocks mismatch: have %v, want %v", bs, blocks)
|
||||||
}
|
}
|
||||||
|
|
||||||
if rs := int(tester.chain.CurrentSnapBlock().Number.Uint64()) + 1; rs != receipts {
|
if rs := int(tester.chain.CurrentSnapBlock().Number.Uint64()) + 1; rs != receipts {
|
||||||
t.Fatalf("synchronised receipts mismatch: have %v, want %v", rs, receipts)
|
t.Fatalf("synchronised receipts mismatch: have %v, want %v", rs, receipts)
|
||||||
}
|
}
|
||||||
|
|
@ -517,6 +521,7 @@ func testThrottling(t *testing.T, protocol uint, mode SyncMode) {
|
||||||
|
|
||||||
// Wrap the importer to allow stepping
|
// Wrap the importer to allow stepping
|
||||||
var blocked atomic.Uint32
|
var blocked atomic.Uint32
|
||||||
|
|
||||||
proceed := make(chan struct{})
|
proceed := make(chan struct{})
|
||||||
tester.downloader.chainInsertHook = func(results []*fetchResult) {
|
tester.downloader.chainInsertHook = func(results []*fetchResult) {
|
||||||
blocked.Store(uint32(len(results)))
|
blocked.Store(uint32(len(results)))
|
||||||
|
|
@ -984,9 +989,11 @@ func testEmptyShortCircuit(t *testing.T, protocol uint, mode SyncMode) {
|
||||||
receiptsNeeded++
|
receiptsNeeded++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(bodiesHave.Load()) != bodiesNeeded {
|
if int(bodiesHave.Load()) != bodiesNeeded {
|
||||||
t.Errorf("body retrieval count mismatch: have %v, want %v", bodiesHave.Load(), bodiesNeeded)
|
t.Errorf("body retrieval count mismatch: have %v, want %v", bodiesHave.Load(), bodiesNeeded)
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(receiptsHave.Load()) != receiptsNeeded {
|
if int(receiptsHave.Load()) != receiptsNeeded {
|
||||||
t.Errorf("receipt retrieval count mismatch: have %v, want %v", receiptsHave.Load(), receiptsNeeded)
|
t.Errorf("receipt retrieval count mismatch: have %v, want %v", receiptsHave.Load(), receiptsNeeded)
|
||||||
}
|
}
|
||||||
|
|
@ -1790,6 +1797,7 @@ func testBeaconSync(t *testing.T, protocol uint, mode SyncMode) {
|
||||||
{name: "Beacon sync with long local chain", local: blockCacheMaxItems - 15 - fsMinFullBlocks/2},
|
{name: "Beacon sync with long local chain", local: blockCacheMaxItems - 15 - fsMinFullBlocks/2},
|
||||||
{name: "Beacon sync with full local chain", local: blockCacheMaxItems - 15 - 1},
|
{name: "Beacon sync with full local chain", local: blockCacheMaxItems - 15 - 1},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
t.Run(c.name, func(t *testing.T) {
|
t.Run(c.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
|
||||||
|
|
@ -286,6 +286,7 @@ func (d *Downloader) concurrentFetch(queue typedQueue, beaconMode bool) error {
|
||||||
_, exp := timeouts.Peek()
|
_, exp := timeouts.Peek()
|
||||||
timeout.Reset(time.Until(time.Unix(0, -exp)))
|
timeout.Reset(time.Until(time.Unix(0, -exp)))
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(ordering, req)
|
delete(ordering, req)
|
||||||
|
|
||||||
// New timeout potentially set if there are more requests pending,
|
// New timeout potentially set if there are more requests pending,
|
||||||
|
|
|
||||||
|
|
@ -436,6 +436,7 @@ func (q *queue) ReserveHeaders(p *peerConnection, count int) *fetchRequest {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send = from
|
send = from
|
||||||
}
|
}
|
||||||
// Merge all the skipped batches back
|
// Merge all the skipped batches back
|
||||||
|
|
@ -783,6 +784,7 @@ func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, txListH
|
||||||
if uncleListHashes[index] != header.UncleHash {
|
if uncleListHashes[index] != header.UncleHash {
|
||||||
return errInvalidBody
|
return errInvalidBody
|
||||||
}
|
}
|
||||||
|
|
||||||
if header.WithdrawalsHash == nil {
|
if header.WithdrawalsHash == nil {
|
||||||
// nil hash means that withdrawals should not be present in body
|
// nil hash means that withdrawals should not be present in body
|
||||||
if withdrawalLists[index] != nil {
|
if withdrawalLists[index] != nil {
|
||||||
|
|
|
||||||
|
|
@ -345,6 +345,7 @@ func XTestDelivery(t *testing.T) {
|
||||||
uncleHashes[i] = types.CalcUncleHash(uncles)
|
uncleHashes[i] = types.CalcUncleHash(uncles)
|
||||||
}
|
}
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
_, err := q.DeliverBodies(peer.id, txset, txsHashes, uncleset, uncleHashes, nil, nil)
|
_, err := q.DeliverBodies(peer.id, txset, txsHashes, uncleset, uncleHashes, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("delivered %d bodies %v\n", len(txset), err)
|
fmt.Printf("delivered %d bodies %v\n", len(txset), err)
|
||||||
|
|
|
||||||
|
|
@ -366,6 +366,7 @@ func (s *skeleton) sync(head *types.Header) (*types.Header, error) {
|
||||||
if linked {
|
if linked {
|
||||||
s.filler.resume()
|
s.filler.resume()
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if filled := s.filler.suspend(); filled != nil {
|
if filled := s.filler.suspend(); filled != nil {
|
||||||
// If something was filled, try to delete stale sync helpers. If
|
// If something was filled, try to delete stale sync helpers. If
|
||||||
|
|
@ -1013,14 +1014,16 @@ func (s *skeleton) processResponse(res *headerResponse) (linked bool, merged boo
|
||||||
context = append(context, fmt.Sprintf("stale_next_%d", i+1))
|
context = append(context, fmt.Sprintf("stale_next_%d", i+1))
|
||||||
context = append(context, s.progress.Subchains[i+1].Next)
|
context = append(context, s.progress.Subchains[i+1].Next)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Error("Cleaning spurious beacon sync leftovers", context...)
|
log.Error("Cleaning spurious beacon sync leftovers", context...)
|
||||||
s.progress.Subchains = s.progress.Subchains[:1]
|
|
||||||
|
|
||||||
// Note, here we didn't actually delete the headers at all,
|
// Note, here we didn't actually delete the headers at all,
|
||||||
// just the metadata. We could implement a cleanup mechanism,
|
// just the metadata. We could implement a cleanup mechanism,
|
||||||
// but further modifying corrupted state is kind of asking
|
// but further modifying corrupted state is kind of asking
|
||||||
// for it. Unless there's a good enough reason to risk it,
|
// for it. Unless there's a good enough reason to risk it,
|
||||||
// better to live with the small database junk.
|
// better to live with the small database junk.
|
||||||
|
|
||||||
|
s.progress.Subchains = s.progress.Subchains[:1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
@ -1116,6 +1119,7 @@ func (s *skeleton) cleanStales(filled *types.Header) error {
|
||||||
end = number // delete until the requested threshold
|
end = number // delete until the requested threshold
|
||||||
batch = s.db.NewBatch()
|
batch = s.db.NewBatch()
|
||||||
)
|
)
|
||||||
|
|
||||||
s.progress.Subchains[0].Tail = number
|
s.progress.Subchains[0].Tail = number
|
||||||
s.progress.Subchains[0].Next = filled.ParentHash
|
s.progress.Subchains[0].Next = filled.ParentHash
|
||||||
|
|
||||||
|
|
@ -1132,6 +1136,7 @@ func (s *skeleton) cleanStales(filled *types.Header) error {
|
||||||
}
|
}
|
||||||
// Execute the trimming and the potential rewiring of the progress
|
// Execute the trimming and the potential rewiring of the progress
|
||||||
s.saveSyncStatus(batch)
|
s.saveSyncStatus(batch)
|
||||||
|
|
||||||
for n := start; n < end; n++ {
|
for n := start; n < end; n++ {
|
||||||
// If the batch grew too big, flush it and continue with a new batch.
|
// If the batch grew too big, flush it and continue with a new batch.
|
||||||
// The catch is that the sync metadata needs to reflect the actually
|
// The catch is that the sync metadata needs to reflect the actually
|
||||||
|
|
@ -1148,17 +1153,21 @@ func (s *skeleton) cleanStales(filled *types.Header) error {
|
||||||
if err := batch.Write(); err != nil {
|
if err := batch.Write(); err != nil {
|
||||||
log.Crit("Failed to write beacon trim data", "err", err)
|
log.Crit("Failed to write beacon trim data", "err", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.Reset()
|
batch.Reset()
|
||||||
|
|
||||||
s.progress.Subchains[0].Tail = tmpTail
|
s.progress.Subchains[0].Tail = tmpTail
|
||||||
s.progress.Subchains[0].Next = tmpNext
|
s.progress.Subchains[0].Next = tmpNext
|
||||||
s.saveSyncStatus(batch)
|
s.saveSyncStatus(batch)
|
||||||
}
|
}
|
||||||
|
|
||||||
rawdb.DeleteSkeletonHeader(batch, n)
|
rawdb.DeleteSkeletonHeader(batch, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := batch.Write(); err != nil {
|
if err := batch.Write(); err != nil {
|
||||||
log.Crit("Failed to write beacon trim data", "err", err)
|
log.Crit("Failed to write beacon trim data", "err", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1187,19 +1196,23 @@ func (s *skeleton) Bounds() (head *types.Header, tail *types.Header, final *type
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
head = rawdb.ReadSkeletonHeader(s.db, progress.Subchains[0].Head)
|
head = rawdb.ReadSkeletonHeader(s.db, progress.Subchains[0].Head)
|
||||||
|
|
||||||
if head == nil {
|
if head == nil {
|
||||||
return nil, nil, nil, fmt.Errorf("head skeleton header %d is missing", progress.Subchains[0].Head)
|
return nil, nil, nil, fmt.Errorf("head skeleton header %d is missing", progress.Subchains[0].Head)
|
||||||
}
|
}
|
||||||
tail = rawdb.ReadSkeletonHeader(s.db, progress.Subchains[0].Tail)
|
tail = rawdb.ReadSkeletonHeader(s.db, progress.Subchains[0].Tail)
|
||||||
|
|
||||||
if tail == nil {
|
if tail == nil {
|
||||||
return nil, nil, nil, fmt.Errorf("tail skeleton header %d is missing", progress.Subchains[0].Tail)
|
return nil, nil, nil, fmt.Errorf("tail skeleton header %d is missing", progress.Subchains[0].Tail)
|
||||||
}
|
}
|
||||||
|
|
||||||
if progress.Finalized != nil && tail.Number.Uint64() <= *progress.Finalized && *progress.Finalized <= head.Number.Uint64() {
|
if progress.Finalized != nil && tail.Number.Uint64() <= *progress.Finalized && *progress.Finalized <= head.Number.Uint64() {
|
||||||
final = rawdb.ReadSkeletonHeader(s.db, *progress.Finalized)
|
final = rawdb.ReadSkeletonHeader(s.db, *progress.Finalized)
|
||||||
if final == nil {
|
if final == nil {
|
||||||
return nil, nil, nil, fmt.Errorf("finalized skeleton header %d is missing", *progress.Finalized)
|
return nil, nil, nil, fmt.Errorf("finalized skeleton header %d is missing", *progress.Finalized)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return head, tail, final, nil
|
return head, tail, final, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ func (hf *hookedBackfiller) suspend() *types.Header {
|
||||||
if hf.suspendHook != nil {
|
if hf.suspendHook != nil {
|
||||||
return hf.suspendHook()
|
return hf.suspendHook()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil // we don't really care about header cleanups for now
|
return nil // we don't really care about header cleanups for now
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,6 +162,7 @@ func (p *skeletonTestPeer) RequestHeadersByNumber(origin uint64, amount int, ski
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.served.Add(uint64(len(headers)))
|
p.served.Add(uint64(len(headers)))
|
||||||
|
|
||||||
hashes := make([]common.Hash, len(headers))
|
hashes := make([]common.Hash, len(headers))
|
||||||
|
|
@ -487,6 +489,7 @@ func TestSkeletonSyncExtend(t *testing.T) {
|
||||||
skeleton.Sync(tt.head, nil, true)
|
skeleton.Sync(tt.head, nil, true)
|
||||||
|
|
||||||
<-wait
|
<-wait
|
||||||
|
|
||||||
if err := skeleton.Sync(tt.extend, nil, false); err != tt.err {
|
if err := skeleton.Sync(tt.extend, nil, false); err != tt.err {
|
||||||
t.Errorf("test %d: extension failure mismatch: have %v, want %v", i, err, tt.err)
|
t.Errorf("test %d: extension failure mismatch: have %v, want %v", i, err, tt.err)
|
||||||
}
|
}
|
||||||
|
|
@ -530,6 +533,7 @@ func TestSkeletonSyncRetrievals(t *testing.T) {
|
||||||
for i := 0; i < len(chain)/2; i++ { // Fork at block #5000
|
for i := 0; i < len(chain)/2; i++ { // Fork at block #5000
|
||||||
sidechain = append(sidechain, chain[i])
|
sidechain = append(sidechain, chain[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := len(chain) / 2; i < len(chain); i++ {
|
for i := len(chain) / 2; i < len(chain); i++ {
|
||||||
sidechain = append(sidechain, &types.Header{
|
sidechain = append(sidechain, &types.Header{
|
||||||
ParentHash: sidechain[i-1].Hash(),
|
ParentHash: sidechain[i-1].Hash(),
|
||||||
|
|
@ -824,6 +828,7 @@ func TestSkeletonSyncRetrievals(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Create a backfiller if we need to run more advanced tests
|
// Create a backfiller if we need to run more advanced tests
|
||||||
filler := newHookedBackfiller()
|
filler := newHookedBackfiller()
|
||||||
|
|
||||||
if tt.fill {
|
if tt.fill {
|
||||||
var filled *types.Header
|
var filled *types.Header
|
||||||
|
|
||||||
|
|
@ -892,18 +897,23 @@ func TestSkeletonSyncRetrievals(t *testing.T) {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !tt.unpredictable {
|
if !tt.unpredictable {
|
||||||
var served uint64
|
var served uint64
|
||||||
for _, peer := range tt.peers {
|
for _, peer := range tt.peers {
|
||||||
served += peer.served.Load()
|
served += peer.served.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
if served != tt.midserve {
|
if served != tt.midserve {
|
||||||
t.Errorf("test %d, mid state: served headers mismatch: have %d, want %d", i, served, tt.midserve)
|
t.Errorf("test %d, mid state: served headers mismatch: have %d, want %d", i, served, tt.midserve)
|
||||||
}
|
}
|
||||||
|
|
||||||
var drops uint64
|
var drops uint64
|
||||||
|
|
||||||
for _, peer := range tt.peers {
|
for _, peer := range tt.peers {
|
||||||
drops += peer.dropped.Load()
|
drops += peer.dropped.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
if drops != tt.middrop {
|
if drops != tt.middrop {
|
||||||
t.Errorf("test %d, mid state: dropped peers mismatch: have %d, want %d", i, drops, tt.middrop)
|
t.Errorf("test %d, mid state: dropped peers mismatch: have %d, want %d", i, drops, tt.middrop)
|
||||||
}
|
}
|
||||||
|
|
@ -934,6 +944,7 @@ func TestSkeletonSyncRetrievals(t *testing.T) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
waitStart = time.Now()
|
waitStart = time.Now()
|
||||||
|
|
||||||
for waitTime := 20 * time.Millisecond; time.Since(waitStart) < 2*time.Second; waitTime = waitTime * 2 {
|
for waitTime := 20 * time.Millisecond; time.Since(waitStart) < 2*time.Second; waitTime = waitTime * 2 {
|
||||||
time.Sleep(waitTime)
|
time.Sleep(waitTime)
|
||||||
// Check the post-init end state if it matches the required results
|
// Check the post-init end state if it matches the required results
|
||||||
|
|
@ -952,19 +963,25 @@ func TestSkeletonSyncRetrievals(t *testing.T) {
|
||||||
for _, peer := range tt.peers {
|
for _, peer := range tt.peers {
|
||||||
served += peer.served.Load()
|
served += peer.served.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
if tt.newPeer != nil {
|
if tt.newPeer != nil {
|
||||||
served += tt.newPeer.served.Load()
|
served += tt.newPeer.served.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
if served != tt.endserve {
|
if served != tt.endserve {
|
||||||
t.Errorf("test %d, end state: served headers mismatch: have %d, want %d", i, served, tt.endserve)
|
t.Errorf("test %d, end state: served headers mismatch: have %d, want %d", i, served, tt.endserve)
|
||||||
}
|
}
|
||||||
|
|
||||||
drops := uint64(0)
|
drops := uint64(0)
|
||||||
|
|
||||||
for _, peer := range tt.peers {
|
for _, peer := range tt.peers {
|
||||||
drops += peer.dropped.Load()
|
drops += peer.dropped.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
if tt.newPeer != nil {
|
if tt.newPeer != nil {
|
||||||
drops += tt.newPeer.dropped.Load()
|
drops += tt.newPeer.dropped.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
if drops != tt.enddrop {
|
if drops != tt.enddrop {
|
||||||
t.Errorf("test %d, end state: dropped peers mismatch: have %d, want %d", i, drops, tt.middrop)
|
t.Errorf("test %d, end state: dropped peers mismatch: have %d, want %d", i, drops, tt.middrop)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,10 @@ func newHandler(config *handlerConfig) (*handler, error) {
|
||||||
// time. But we don't have any recent state for full sync.
|
// time. But we don't have any recent state for full sync.
|
||||||
// In these cases however it's safe to reenable snap sync.
|
// In these cases however it's safe to reenable snap sync.
|
||||||
fullBlock, snapBlock := h.chain.CurrentBlock(), h.chain.CurrentSnapBlock()
|
fullBlock, snapBlock := h.chain.CurrentBlock(), h.chain.CurrentSnapBlock()
|
||||||
|
|
||||||
if fullBlock.Number.Uint64() == 0 && snapBlock.Number.Uint64() > 0 {
|
if fullBlock.Number.Uint64() == 0 && snapBlock.Number.Uint64() > 0 {
|
||||||
|
log.Warn("Preventing switching sync mode from full sync to snap sync")
|
||||||
|
|
||||||
// Note: Ideally this should never happen with bor, but to be extra
|
// Note: Ideally this should never happen with bor, but to be extra
|
||||||
// preventive we won't allow it to roll over to snap sync until
|
// preventive we won't allow it to roll over to snap sync until
|
||||||
// we have it working
|
// we have it working
|
||||||
|
|
@ -171,8 +174,6 @@ func newHandler(config *handlerConfig) (*handler, error) {
|
||||||
// TODO(snap): Uncomment when we have snap sync working
|
// TODO(snap): Uncomment when we have snap sync working
|
||||||
// h.snapSync = uint32(1)
|
// h.snapSync = uint32(1)
|
||||||
// log.Warn("Switch sync mode from full sync to snap sync")
|
// log.Warn("Switch sync mode from full sync to snap sync")
|
||||||
|
|
||||||
log.Warn("Preventing switching sync mode from full sync to snap sync")
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if h.chain.CurrentBlock().Number.Uint64() > 0 {
|
if h.chain.CurrentBlock().Number.Uint64() > 0 {
|
||||||
|
|
@ -348,6 +349,7 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error {
|
||||||
number = head.Number.Uint64()
|
number = head.Number.Uint64()
|
||||||
td = h.chain.GetTd(hash, number)
|
td = h.chain.GetTd(hash, number)
|
||||||
)
|
)
|
||||||
|
|
||||||
forkID := forkid.NewID(h.chain.Config(), genesis.Hash(), number, head.Time)
|
forkID := forkid.NewID(h.chain.Config(), genesis.Hash(), number, head.Time)
|
||||||
if err := peer.Handshake(h.networkID, td, hash, genesis.Hash(), forkID, h.forkFilter); err != nil {
|
if err := peer.Handshake(h.networkID, td, hash, genesis.Hash(), forkID, h.forkFilter); err != nil {
|
||||||
peer.Log().Debug("Ethereum handshake failed", "err", err)
|
peer.Log().Debug("Ethereum handshake failed", "err", err)
|
||||||
|
|
@ -464,6 +466,7 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
go func(number uint64, hash common.Hash, req *eth.Request) {
|
go func(number uint64, hash common.Hash, req *eth.Request) {
|
||||||
// Ensure the request gets cancelled in case of error/drop
|
// Ensure the request gets cancelled in case of error/drop
|
||||||
defer req.Close()
|
defer req.Close()
|
||||||
|
|
|
||||||
|
|
@ -697,6 +697,7 @@ func testBroadcastBlock(t *testing.T, peers, bcasts int) {
|
||||||
}
|
}
|
||||||
// Initiate a block propagation across the peers
|
// Initiate a block propagation across the peers
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
header := source.chain.CurrentBlock()
|
header := source.chain.CurrentBlock()
|
||||||
source.handler.BroadcastBlock(source.chain.GetBlock(header.Hash(), header.Number.Uint64()), true)
|
source.handler.BroadcastBlock(source.chain.GetBlock(header.Hash(), header.Number.Uint64()), true)
|
||||||
|
|
||||||
|
|
@ -784,8 +785,10 @@ func testBroadcastMalformedBlock(t *testing.T, protocol uint) {
|
||||||
|
|
||||||
malformedUncles := head
|
malformedUncles := head
|
||||||
malformedUncles.UncleHash[0]++
|
malformedUncles.UncleHash[0]++
|
||||||
|
|
||||||
malformedTransactions := head
|
malformedTransactions := head
|
||||||
malformedTransactions.TxHash[0]++
|
malformedTransactions.TxHash[0]++
|
||||||
|
|
||||||
malformedEverything := head
|
malformedEverything := head
|
||||||
malformedEverything.UncleHash[0]++
|
malformedEverything.UncleHash[0]++
|
||||||
malformedEverything.TxHash[0]++
|
malformedEverything.TxHash[0]++
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,7 @@ func handleMessage(backend Backend, peer *Peer) error {
|
||||||
if peer.Version() == ETH67 {
|
if peer.Version() == ETH67 {
|
||||||
handlers = eth67
|
handlers = eth67
|
||||||
}
|
}
|
||||||
|
|
||||||
if peer.Version() >= ETH68 {
|
if peer.Version() >= ETH68 {
|
||||||
handlers = eth68
|
handlers = eth68
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -111,9 +111,11 @@ func newTestBackendWithGenerator(blocks int, shanghai bool, generator func(int,
|
||||||
if _, err := chain.InsertChain(bs); err != nil {
|
if _, err := chain.InsertChain(bs); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, block := range bs {
|
for _, block := range bs {
|
||||||
chain.StateCache().TrieDB().Commit(block.Root(), false)
|
chain.StateCache().TrieDB().Commit(block.Root(), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
txconfig := txpool.DefaultConfig
|
txconfig := txpool.DefaultConfig
|
||||||
txconfig.Journal = "" // Don't litter the disk with test journals
|
txconfig.Journal = "" // Don't litter the disk with test journals
|
||||||
|
|
||||||
|
|
@ -430,6 +432,7 @@ func testGetBlockBodies(t *testing.T, protocol uint) {
|
||||||
hashes = append(hashes, hash)
|
hashes = append(hashes, hash)
|
||||||
if tt.available[j] && len(bodies) < tt.expected {
|
if tt.available[j] && len(bodies) < tt.expected {
|
||||||
block := backend.chain.GetBlockByHash(hash)
|
block := backend.chain.GetBlockByHash(hash)
|
||||||
|
|
||||||
bodies = append(bodies, &BlockBody{Transactions: block.Transactions(), Uncles: block.Uncles(), Withdrawals: block.Withdrawals()})
|
bodies = append(bodies, &BlockBody{Transactions: block.Transactions(), Uncles: block.Uncles(), Withdrawals: block.Withdrawals()})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -524,6 +527,7 @@ func testGetNodeData(t *testing.T, protocol uint, drop bool) {
|
||||||
GetNodeDataPacket: hashes,
|
GetNodeDataPacket: hashes,
|
||||||
})
|
})
|
||||||
msg, err := peer.app.ReadMsg()
|
msg, err := peer.app.ReadMsg()
|
||||||
|
|
||||||
if !drop {
|
if !drop {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to read node data response: %v", err)
|
t.Fatalf("failed to read node data response: %v", err)
|
||||||
|
|
@ -558,6 +562,7 @@ func testGetNodeData(t *testing.T, protocol uint, drop bool) {
|
||||||
|
|
||||||
// Sanity check whether all state matches.
|
// Sanity check whether all state matches.
|
||||||
accounts := []common.Address{testAddr, acc1Addr, acc2Addr}
|
accounts := []common.Address{testAddr, acc1Addr, acc2Addr}
|
||||||
|
|
||||||
for i := uint64(0); i <= backend.chain.CurrentBlock().Number.Uint64(); i++ {
|
for i := uint64(0); i <= backend.chain.CurrentBlock().Number.Uint64(); i++ {
|
||||||
root := backend.chain.GetBlockByNumber(i).Root()
|
root := backend.chain.GetBlockByNumber(i).Root()
|
||||||
reconstructed, _ := state.New(root, state.NewDatabase(reconstructDB), nil)
|
reconstructed, _ := state.New(root, state.NewDatabase(reconstructDB), nil)
|
||||||
|
|
@ -640,6 +645,7 @@ func testGetBlockReceipts(t *testing.T, protocol uint) {
|
||||||
hashes []common.Hash
|
hashes []common.Hash
|
||||||
receipts [][]*types.Receipt
|
receipts [][]*types.Receipt
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := uint64(0); i <= backend.chain.CurrentBlock().Number.Uint64(); i++ {
|
for i := uint64(0); i <= backend.chain.CurrentBlock().Number.Uint64(); i++ {
|
||||||
block := backend.chain.GetBlockByNumber(i)
|
block := backend.chain.GetBlockByNumber(i)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -387,10 +387,12 @@ func handleBlockBodies66(backend Backend, msg Decoder, peer *Peer) error {
|
||||||
for i, body := range res.BlockBodiesPacket {
|
for i, body := range res.BlockBodiesPacket {
|
||||||
txsHashes[i] = types.DeriveSha(types.Transactions(body.Transactions), hasher)
|
txsHashes[i] = types.DeriveSha(types.Transactions(body.Transactions), hasher)
|
||||||
uncleHashes[i] = types.CalcUncleHash(body.Uncles)
|
uncleHashes[i] = types.CalcUncleHash(body.Uncles)
|
||||||
|
|
||||||
if body.Withdrawals != nil {
|
if body.Withdrawals != nil {
|
||||||
withdrawalHashes[i] = types.DeriveSha(types.Withdrawals(body.Withdrawals), hasher)
|
withdrawalHashes[i] = types.DeriveSha(types.Withdrawals(body.Withdrawals), hasher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [][]common.Hash{txsHashes, uncleHashes, withdrawalHashes}
|
return [][]common.Hash{txsHashes, uncleHashes, withdrawalHashes}
|
||||||
}
|
}
|
||||||
return peer.dispatchResponse(&Response{
|
return peer.dispatchResponse(&Response{
|
||||||
|
|
@ -440,6 +442,7 @@ func handleNewPooledTransactionHashes66(backend Backend, msg Decoder, peer *Peer
|
||||||
if !backend.AcceptTxs() {
|
if !backend.AcceptTxs() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ann := new(NewPooledTransactionHashesPacket66)
|
ann := new(NewPooledTransactionHashesPacket66)
|
||||||
if err := msg.Decode(ann); err != nil {
|
if err := msg.Decode(ann); err != nil {
|
||||||
return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
|
return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
|
||||||
|
|
@ -457,10 +460,13 @@ func handleNewPooledTransactionHashes68(backend Backend, msg Decoder, peer *Peer
|
||||||
if !backend.AcceptTxs() {
|
if !backend.AcceptTxs() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ann := new(NewPooledTransactionHashesPacket68)
|
ann := new(NewPooledTransactionHashesPacket68)
|
||||||
|
|
||||||
if err := msg.Decode(ann); err != nil {
|
if err := msg.Decode(ann); err != nil {
|
||||||
return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
|
return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ann.Hashes) != len(ann.Types) || len(ann.Hashes) != len(ann.Sizes) {
|
if len(ann.Hashes) != len(ann.Types) || len(ann.Hashes) != len(ann.Sizes) {
|
||||||
return fmt.Errorf("%w: message %v: invalid len of fields: %v %v %v", errDecode, msg, len(ann.Hashes), len(ann.Types), len(ann.Sizes))
|
return fmt.Errorf("%w: message %v: invalid len of fields: %v %v %v", errDecode, msg, len(ann.Hashes), len(ann.Types), len(ann.Sizes))
|
||||||
}
|
}
|
||||||
|
|
@ -468,6 +474,7 @@ func handleNewPooledTransactionHashes68(backend Backend, msg Decoder, peer *Peer
|
||||||
for _, hash := range ann.Hashes {
|
for _, hash := range ann.Hashes {
|
||||||
peer.markTransaction(hash)
|
peer.markTransaction(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
return backend.Handle(peer, ann)
|
return backend.Handle(peer, ann)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,7 @@ func (p *BlockBodiesPacket) Unpack() ([][]*types.Transaction, [][]*types.Header,
|
||||||
for i, body := range *p {
|
for i, body := range *p {
|
||||||
txset[i], uncleset[i], withdrawalset[i] = body.Transactions, body.Uncles, body.Withdrawals
|
txset[i], uncleset[i], withdrawalset[i] = body.Transactions, body.Uncles, body.Withdrawals
|
||||||
}
|
}
|
||||||
|
|
||||||
return txset, uncleset, withdrawalset
|
return txset, uncleset, withdrawalset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1510,6 +1510,7 @@ func makeAccountTrieWithStorageWithUniqueStorage(accounts, slots int, code bool)
|
||||||
trie, _ := trie.New(id, db)
|
trie, _ := trie.New(id, db)
|
||||||
storageTries[common.BytesToHash(key)] = trie
|
storageTries[common.BytesToHash(key)] = trie
|
||||||
}
|
}
|
||||||
|
|
||||||
return db.Scheme(), accTrie, entries, storageTries, storageEntries
|
return db.Scheme(), accTrie, entries, storageTries, storageEntries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1537,6 +1538,7 @@ func makeAccountTrieWithStorage(accounts, slots int, code, boundary bool) (strin
|
||||||
stNodes *trie.NodeSet
|
stNodes *trie.NodeSet
|
||||||
stEntries entrySlice
|
stEntries entrySlice
|
||||||
)
|
)
|
||||||
|
|
||||||
if boundary {
|
if boundary {
|
||||||
stRoot, stNodes, stEntries = makeBoundaryStorageTrie(common.BytesToHash(key), slots, db)
|
stRoot, stNodes, stEntries = makeBoundaryStorageTrie(common.BytesToHash(key), slots, db)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1572,15 +1574,19 @@ func makeAccountTrieWithStorage(accounts, slots int, code, boundary bool) (strin
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := uint64(1); i <= uint64(accounts); i++ {
|
for i := uint64(1); i <= uint64(accounts); i++ {
|
||||||
key := key32(i)
|
key := key32(i)
|
||||||
id := trie.StorageTrieID(root, common.BytesToHash(key), storageRoots[common.BytesToHash(key)])
|
id := trie.StorageTrieID(root, common.BytesToHash(key), storageRoots[common.BytesToHash(key)])
|
||||||
|
|
||||||
trie, err := trie.New(id, db)
|
trie, err := trie.New(id, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
storageTries[common.BytesToHash(key)] = trie
|
storageTries[common.BytesToHash(key)] = trie
|
||||||
}
|
}
|
||||||
|
|
||||||
return db.Scheme(), accTrie, entries, storageTries, storageEntries
|
return db.Scheme(), accTrie, entries, storageTries, storageEntries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1603,7 +1609,9 @@ func makeStorageTrieWithSeed(owner common.Hash, n, seed uint64, db *trie.Databas
|
||||||
entries = append(entries, elem)
|
entries = append(entries, elem)
|
||||||
}
|
}
|
||||||
sort.Sort(entries)
|
sort.Sort(entries)
|
||||||
|
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
|
|
||||||
return root, nodes, entries
|
return root, nodes, entries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1654,12 +1662,15 @@ func makeBoundaryStorageTrie(owner common.Hash, n int, db *trie.Database) (commo
|
||||||
entries = append(entries, elem)
|
entries = append(entries, elem)
|
||||||
}
|
}
|
||||||
sort.Sort(entries)
|
sort.Sort(entries)
|
||||||
|
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
|
|
||||||
return root, nodes, entries
|
return root, nodes, entries
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyTrie(db ethdb.KeyValueStore, root common.Hash, t *testing.T) {
|
func verifyTrie(db ethdb.KeyValueStore, root common.Hash, t *testing.T) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
triedb := trie.NewDatabase(rawdb.NewDatabase(db))
|
triedb := trie.NewDatabase(rawdb.NewDatabase(db))
|
||||||
accTrie, err := trie.New(trie.StateTrieID(root), triedb)
|
accTrie, err := trie.New(trie.StateTrieID(root), triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1678,6 +1689,7 @@ func verifyTrie(db ethdb.KeyValueStore, root common.Hash, t *testing.T) {
|
||||||
log.Crit("Invalid account encountered during snapshot creation", "err", err)
|
log.Crit("Invalid account encountered during snapshot creation", "err", err)
|
||||||
}
|
}
|
||||||
accounts++
|
accounts++
|
||||||
|
|
||||||
if acc.Root != types.EmptyRootHash {
|
if acc.Root != types.EmptyRootHash {
|
||||||
id := trie.StorageTrieID(root, common.BytesToHash(accIt.Key), acc.Root)
|
id := trie.StorageTrieID(root, common.BytesToHash(accIt.Key), acc.Root)
|
||||||
storeTrie, err := trie.NewStateTrie(id, triedb)
|
storeTrie, err := trie.NewStateTrie(id, triedb)
|
||||||
|
|
@ -1716,6 +1728,7 @@ func TestSyncAccountPerformance(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
nodeScheme, sourceAccountTrie, elems := makeAccountTrieNoStorage(100)
|
nodeScheme, sourceAccountTrie, elems := makeAccountTrieNoStorage(100)
|
||||||
|
|
||||||
mkSource := func(name string) *testPeer {
|
mkSource := func(name string) *testPeer {
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ func (eth *Ethereum) StateAtBlock(ctx context.Context, block *types.Block, reexe
|
||||||
// function to deref it.
|
// function to deref it.
|
||||||
if statedb, err = eth.blockchain.StateAt(block.Root()); err == nil {
|
if statedb, err = eth.blockchain.StateAt(block.Root()); err == nil {
|
||||||
statedb.Database().TrieDB().Reference(block.Root(), common.Hash{})
|
statedb.Database().TrieDB().Reference(block.Root(), common.Hash{})
|
||||||
|
|
||||||
return statedb, func() {
|
return statedb, func() {
|
||||||
statedb.Database().TrieDB().Dereference(block.Root())
|
statedb.Database().TrieDB().Dereference(block.Root())
|
||||||
}, nil
|
}, nil
|
||||||
|
|
@ -188,6 +189,7 @@ func (eth *Ethereum) StateAtBlock(ctx context.Context, block *types.Block, reexe
|
||||||
nodes, imgs := database.TrieDB().Size()
|
nodes, imgs := database.TrieDB().Size()
|
||||||
log.Info("Historical state regenerated", "block", current.NumberU64(), "elapsed", time.Since(start), "nodes", nodes, "preimages", imgs)
|
log.Info("Historical state regenerated", "block", current.NumberU64(), "elapsed", time.Since(start), "nodes", nodes, "preimages", imgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
return statedb, func() { database.TrieDB().Dereference(block.Root()) }, nil
|
return statedb, func() { database.TrieDB().Dereference(block.Root()) }, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -224,6 +226,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
||||||
// Not yet the searched for transaction, execute on top of the current state
|
// Not yet the searched for transaction, execute on top of the current state
|
||||||
vmenv := vm.NewEVM(context, txContext, statedb, eth.blockchain.Config(), vm.Config{})
|
vmenv := vm.NewEVM(context, txContext, statedb, eth.blockchain.Config(), vm.Config{})
|
||||||
statedb.SetTxContext(tx.Hash(), idx)
|
statedb.SetTxContext(tx.Hash(), idx)
|
||||||
|
// nolint : contextcheck
|
||||||
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()), nil); err != nil {
|
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()), nil); err != nil {
|
||||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
||||||
}
|
}
|
||||||
|
|
@ -231,5 +234,6 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
||||||
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
|
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
|
||||||
statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
|
statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
|
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -286,6 +286,7 @@ func (h *handler) doSync(op *chainSyncOp) error {
|
||||||
atomic.StoreUint32(&h.acceptTxs, 1)
|
atomic.StoreUint32(&h.acceptTxs, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if head.Number.Uint64() > 0 {
|
if head.Number.Uint64() > 0 {
|
||||||
// We've completed a sync cycle, notify all peers of new state. This path is
|
// We've completed a sync cycle, notify all peers of new state. This path is
|
||||||
// essential in star-topology networks where a gateway node needs to notify
|
// essential in star-topology networks where a gateway node needs to notify
|
||||||
|
|
|
||||||
|
|
@ -288,15 +288,18 @@ func (api *API) TraceChain(ctx context.Context, start, end rpc.BlockNumber, conf
|
||||||
if !supported {
|
if !supported {
|
||||||
return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
|
return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
|
||||||
}
|
}
|
||||||
|
|
||||||
sub := notifier.CreateSubscription()
|
sub := notifier.CreateSubscription()
|
||||||
|
|
||||||
// nolint : contextcheck
|
// nolint : contextcheck
|
||||||
resCh := api.traceChain(from, to, config, notifier.Closed())
|
resCh := api.traceChain(from, to, config, notifier.Closed())
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for result := range resCh {
|
for result := range resCh {
|
||||||
notifier.Notify(sub.ID, result)
|
notifier.Notify(sub.ID, result)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return sub, nil
|
return sub, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -350,6 +353,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
||||||
txs = txs[:len(txs)-1]
|
txs = txs[:len(txs)-1]
|
||||||
stateSyncPresent = false
|
stateSyncPresent = false
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tx := range task.block.Transactions() {
|
for i, tx := range task.block.Transactions() {
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee())
|
||||||
txctx := &Context{
|
txctx := &Context{
|
||||||
|
|
@ -421,6 +425,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
||||||
default:
|
default:
|
||||||
log.Info("Chain tracing finished", "start", start.NumberU64(), "end", end.NumberU64(), "transactions", traced, "elapsed", time.Since(begin))
|
log.Info("Chain tracing finished", "start", start.NumberU64(), "end", end.NumberU64(), "transactions", traced, "elapsed", time.Since(begin))
|
||||||
}
|
}
|
||||||
|
|
||||||
close(resCh)
|
close(resCh)
|
||||||
}()
|
}()
|
||||||
// Feed all the blocks both into the tracer, as well as fast process concurrently
|
// Feed all the blocks both into the tracer, as well as fast process concurrently
|
||||||
|
|
@ -442,6 +447,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
||||||
failed = err
|
failed = err
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
next, err := api.blockByNumber(ctx, rpc.BlockNumber(number+1))
|
next, err := api.blockByNumber(ctx, rpc.BlockNumber(number+1))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
failed = err
|
failed = err
|
||||||
|
|
@ -460,10 +466,12 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
||||||
// limit, the trie database will be reconstructed from scratch only
|
// limit, the trie database will be reconstructed from scratch only
|
||||||
// if the relevant state is available in disk.
|
// if the relevant state is available in disk.
|
||||||
var preferDisk bool
|
var preferDisk bool
|
||||||
|
|
||||||
if statedb != nil {
|
if statedb != nil {
|
||||||
s1, s2 := statedb.Database().TrieDB().Size()
|
s1, s2 := statedb.Database().TrieDB().Size()
|
||||||
preferDisk = s1+s2 > defaultTracechainMemLimit
|
preferDisk = s1+s2 > defaultTracechainMemLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
statedb, release, err = api.backend.StateAtBlock(ctx, block, reexec, statedb, false, preferDisk)
|
statedb, release, err = api.backend.StateAtBlock(ctx, block, reexec, statedb, false, preferDisk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
failed = err
|
failed = err
|
||||||
|
|
@ -495,6 +503,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
||||||
next = start.NumberU64() + 1
|
next = start.NumberU64() + 1
|
||||||
done = make(map[uint64]*blockTraceResult)
|
done = make(map[uint64]*blockTraceResult)
|
||||||
)
|
)
|
||||||
|
|
||||||
for res := range resCh {
|
for res := range resCh {
|
||||||
// Queue up next received result
|
// Queue up next received result
|
||||||
result := &blockTraceResult{
|
result := &blockTraceResult{
|
||||||
|
|
@ -518,6 +527,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return retCh
|
return retCh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -636,10 +646,12 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
|
||||||
if config != nil && config.Reexec != nil {
|
if config != nil && config.Reexec != nil {
|
||||||
reexec = *config.Reexec
|
reexec = *config.Reexec
|
||||||
}
|
}
|
||||||
|
|
||||||
statedb, release, err := api.backend.StateAtBlock(ctx, parent, reexec, nil, true, false)
|
statedb, release, err := api.backend.StateAtBlock(ctx, parent, reexec, nil, true, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer release()
|
defer release()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -660,6 +672,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
|
||||||
txContext = core.NewEVMTxContext(msg)
|
txContext = core.NewEVMTxContext(msg)
|
||||||
vmenv = vm.NewEVM(vmctx, txContext, statedb, chainConfig, vm.Config{})
|
vmenv = vm.NewEVM(vmctx, txContext, statedb, chainConfig, vm.Config{})
|
||||||
)
|
)
|
||||||
|
|
||||||
statedb.SetTxContext(tx.Hash(), i)
|
statedb.SetTxContext(tx.Hash(), i)
|
||||||
//nolint: nestif
|
//nolint: nestif
|
||||||
if stateSyncPresent && i == len(txs)-1 {
|
if stateSyncPresent && i == len(txs)-1 {
|
||||||
|
|
@ -758,6 +771,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer release()
|
defer release()
|
||||||
|
|
||||||
// create and add empty mvHashMap in statedb as StateAtBlock does not have mvHashmap in it.
|
// create and add empty mvHashMap in statedb as StateAtBlock does not have mvHashmap in it.
|
||||||
|
|
@ -778,6 +792,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
|
||||||
if threads > len(txs) {
|
if threads > len(txs) {
|
||||||
threads = len(txs)
|
threads = len(txs)
|
||||||
}
|
}
|
||||||
|
|
||||||
jobs := make(chan *txTraceTask, threads)
|
jobs := make(chan *txTraceTask, threads)
|
||||||
for th := 0; th < threads; th++ {
|
for th := 0; th < threads; th++ {
|
||||||
pend.Add(1)
|
pend.Add(1)
|
||||||
|
|
@ -982,10 +997,12 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
|
||||||
if config != nil && config.Reexec != nil {
|
if config != nil && config.Reexec != nil {
|
||||||
reexec = *config.Reexec
|
reexec = *config.Reexec
|
||||||
}
|
}
|
||||||
|
|
||||||
statedb, release, err := api.backend.StateAtBlock(ctx, parent, reexec, nil, true, false)
|
statedb, release, err := api.backend.StateAtBlock(ctx, parent, reexec, nil, true, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer release()
|
defer release()
|
||||||
|
|
||||||
// Retrieve the tracing configurations, or use default values
|
// Retrieve the tracing configurations, or use default values
|
||||||
|
|
@ -1040,6 +1057,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
|
||||||
if !canon {
|
if !canon {
|
||||||
prefix = fmt.Sprintf("%valt-", prefix)
|
prefix = fmt.Sprintf("%valt-", prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
dump, err = os.CreateTemp(os.TempDir(), prefix)
|
dump, err = os.CreateTemp(os.TempDir(), prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -1143,10 +1161,12 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
msg, vmctx, statedb, release, err := api.backend.StateAtTransaction(ctx, block, int(index), reexec)
|
msg, vmctx, statedb, release, err := api.backend.StateAtTransaction(ctx, block, int(index), reexec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer release()
|
defer release()
|
||||||
|
|
||||||
txctx := &Context{
|
txctx := &Context{
|
||||||
|
|
@ -1190,18 +1210,22 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
|
||||||
if config != nil && config.Reexec != nil {
|
if config != nil && config.Reexec != nil {
|
||||||
reexec = *config.Reexec
|
reexec = *config.Reexec
|
||||||
}
|
}
|
||||||
|
|
||||||
statedb, release, err := api.backend.StateAtBlock(ctx, block, reexec, nil, true, false)
|
statedb, release, err := api.backend.StateAtBlock(ctx, block, reexec, nil, true, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer release()
|
defer release()
|
||||||
|
|
||||||
vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||||
|
|
||||||
// Apply the customization rules if required.
|
// Apply the customization rules if required.
|
||||||
if config != nil {
|
if config != nil {
|
||||||
if err := config.StateOverrides.Apply(statedb); err != nil {
|
if err := config.StateOverrides.Apply(statedb); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
config.BlockOverrides.Apply(&vmctx)
|
config.BlockOverrides.Apply(&vmctx)
|
||||||
}
|
}
|
||||||
// Execute the trace
|
// Execute the trace
|
||||||
|
|
@ -1238,6 +1262,7 @@ func (api *API) traceTx(ctx context.Context, message *core.Message, txctx *Conte
|
||||||
timeout = defaultTraceTimeout
|
timeout = defaultTraceTimeout
|
||||||
txContext = core.NewEVMTxContext(message)
|
txContext = core.NewEVMTxContext(message)
|
||||||
)
|
)
|
||||||
|
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = &TraceConfig{}
|
config = &TraceConfig{}
|
||||||
}
|
}
|
||||||
|
|
@ -1249,6 +1274,7 @@ func (api *API) traceTx(ctx context.Context, message *core.Message, txctx *Conte
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vmenv := vm.NewEVM(vmctx, txContext, statedb, api.backend.ChainConfig(), vm.Config{Tracer: tracer, NoBaseFee: true})
|
vmenv := vm.NewEVM(vmctx, txContext, statedb, api.backend.ChainConfig(), vm.Config{Tracer: tracer, NoBaseFee: true})
|
||||||
|
|
||||||
// Define a meaningful timeout of a single transaction trace
|
// Define a meaningful timeout of a single transaction trace
|
||||||
|
|
@ -1257,15 +1283,19 @@ func (api *API) traceTx(ctx context.Context, message *core.Message, txctx *Conte
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deadlineCtx, cancel := context.WithTimeout(ctx, timeout)
|
deadlineCtx, cancel := context.WithTimeout(ctx, timeout)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
<-deadlineCtx.Done()
|
<-deadlineCtx.Done()
|
||||||
|
|
||||||
if errors.Is(deadlineCtx.Err(), context.DeadlineExceeded) {
|
if errors.Is(deadlineCtx.Err(), context.DeadlineExceeded) {
|
||||||
tracer.Stop(errors.New("execution timeout"))
|
tracer.Stop(errors.New("execution timeout"))
|
||||||
// Stop evm execution. Note cancellation is not necessarily immediate.
|
// Stop evm execution. Note cancellation is not necessarily immediate.
|
||||||
vmenv.Cancel()
|
vmenv.Cancel()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// Call Prepare to clear out the statedb access list
|
// Call Prepare to clear out the statedb access list
|
||||||
|
|
@ -1287,6 +1317,7 @@ func (api *API) traceTx(ctx context.Context, message *core.Message, txctx *Conte
|
||||||
return nil, fmt.Errorf("tracing failed: %w", err)
|
return nil, fmt.Errorf("tracing failed: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tracer.GetResult()
|
return tracer.GetResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1314,30 +1345,37 @@ func overrideConfig(original *params.ChainConfig, override *params.ChainConfig)
|
||||||
chainConfigCopy.BerlinBlock = block
|
chainConfigCopy.BerlinBlock = block
|
||||||
canon = false
|
canon = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if block := override.LondonBlock; block != nil {
|
if block := override.LondonBlock; block != nil {
|
||||||
chainConfigCopy.LondonBlock = block
|
chainConfigCopy.LondonBlock = block
|
||||||
canon = false
|
canon = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if block := override.ArrowGlacierBlock; block != nil {
|
if block := override.ArrowGlacierBlock; block != nil {
|
||||||
chainConfigCopy.ArrowGlacierBlock = block
|
chainConfigCopy.ArrowGlacierBlock = block
|
||||||
canon = false
|
canon = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if block := override.GrayGlacierBlock; block != nil {
|
if block := override.GrayGlacierBlock; block != nil {
|
||||||
chainConfigCopy.GrayGlacierBlock = block
|
chainConfigCopy.GrayGlacierBlock = block
|
||||||
canon = false
|
canon = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if block := override.MergeNetsplitBlock; block != nil {
|
if block := override.MergeNetsplitBlock; block != nil {
|
||||||
chainConfigCopy.MergeNetsplitBlock = block
|
chainConfigCopy.MergeNetsplitBlock = block
|
||||||
canon = false
|
canon = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if timestamp := override.ShanghaiTime; timestamp != nil {
|
if timestamp := override.ShanghaiTime; timestamp != nil {
|
||||||
chainConfigCopy.ShanghaiTime = timestamp
|
chainConfigCopy.ShanghaiTime = timestamp
|
||||||
canon = false
|
canon = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if timestamp := override.CancunTime; timestamp != nil {
|
if timestamp := override.CancunTime; timestamp != nil {
|
||||||
chainConfigCopy.CancunTime = timestamp
|
chainConfigCopy.CancunTime = timestamp
|
||||||
canon = false
|
canon = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if timestamp := override.PragueTime; timestamp != nil {
|
if timestamp := override.PragueTime; timestamp != nil {
|
||||||
chainConfigCopy.PragueTime = timestamp
|
chainConfigCopy.PragueTime = timestamp
|
||||||
canon = false
|
canon = false
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ func (api *API) traceBorBlock(ctx context.Context, block *types.Block, config *T
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer release()
|
defer release()
|
||||||
|
|
||||||
// Execute all the transaction contained within the block concurrently
|
// Execute all the transaction contained within the block concurrently
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue