2020-07-14 01:56:29 +00:00
|
|
|
package commands
|
2020-07-07 04:00:25 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
2020-07-25 07:35:08 +00:00
|
|
|
"os"
|
2020-07-25 17:18:45 +00:00
|
|
|
"path"
|
|
|
|
"sync"
|
2020-08-05 10:13:35 +00:00
|
|
|
"text/tabwriter"
|
2020-07-25 17:18:45 +00:00
|
|
|
"time"
|
2020-07-07 04:00:25 +00:00
|
|
|
|
2020-10-28 03:18:10 +00:00
|
|
|
"github.com/c2h5oh/datasize"
|
2020-07-25 07:35:08 +00:00
|
|
|
"github.com/ledgerwatch/lmdb-go/lmdb"
|
2020-10-28 03:18:10 +00:00
|
|
|
"github.com/ledgerwatch/turbo-geth/cmd/utils"
|
2020-07-25 17:18:45 +00:00
|
|
|
"github.com/ledgerwatch/turbo-geth/common"
|
2020-07-07 04:00:25 +00:00
|
|
|
"github.com/ledgerwatch/turbo-geth/common/dbutils"
|
|
|
|
"github.com/ledgerwatch/turbo-geth/core"
|
2020-10-28 03:18:10 +00:00
|
|
|
"github.com/ledgerwatch/turbo-geth/core/rawdb"
|
2020-07-17 05:52:09 +00:00
|
|
|
"github.com/ledgerwatch/turbo-geth/eth/stagedsync"
|
2020-07-07 04:00:25 +00:00
|
|
|
"github.com/ledgerwatch/turbo-geth/eth/stagedsync/stages"
|
|
|
|
"github.com/ledgerwatch/turbo-geth/ethdb"
|
|
|
|
"github.com/ledgerwatch/turbo-geth/log"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
)
|
|
|
|
|
|
|
|
var cmdResetState = &cobra.Command{
|
|
|
|
Use: "reset_state",
|
2020-08-10 17:46:06 +00:00
|
|
|
Short: "Reset StateStages (5,6,7,8,9,10) and buckets",
|
2020-07-07 04:00:25 +00:00
|
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
2020-08-19 11:46:20 +00:00
|
|
|
ctx := utils.RootContext()
|
2020-10-28 03:18:10 +00:00
|
|
|
db := openDatabase(chaindata, true)
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
err := resetState(db, ctx)
|
2020-07-07 04:00:25 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Error(err.Error())
|
|
|
|
return err
|
|
|
|
}
|
2020-07-25 07:35:08 +00:00
|
|
|
if compact {
|
|
|
|
if err := copyCompact(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-07 04:00:25 +00:00
|
|
|
return nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2020-08-10 23:38:19 +00:00
|
|
|
var cmdClearUnwindStack = &cobra.Command{
|
|
|
|
Use: "clear_unwind_stack",
|
|
|
|
Short: "Clear unwind stack",
|
|
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
2020-08-19 11:46:20 +00:00
|
|
|
ctx := utils.RootContext()
|
2020-10-28 03:18:10 +00:00
|
|
|
db := openDatabase(chaindata, true)
|
|
|
|
defer db.Close()
|
|
|
|
|
|
|
|
err := clearUnwindStack(db, ctx)
|
2020-08-10 23:38:19 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Error(err.Error())
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2020-07-07 04:00:25 +00:00
|
|
|
func init() {
|
|
|
|
withChaindata(cmdResetState)
|
2020-07-25 07:35:08 +00:00
|
|
|
withCompact(cmdResetState)
|
2020-07-07 04:00:25 +00:00
|
|
|
|
|
|
|
rootCmd.AddCommand(cmdResetState)
|
2020-08-10 23:38:19 +00:00
|
|
|
|
|
|
|
withChaindata(cmdClearUnwindStack)
|
|
|
|
|
|
|
|
rootCmd.AddCommand(cmdClearUnwindStack)
|
|
|
|
}
|
|
|
|
|
2020-10-28 03:18:10 +00:00
|
|
|
func clearUnwindStack(db rawdb.DatabaseWriter, _ context.Context) error {
|
2020-09-05 16:07:27 +00:00
|
|
|
for _, stage := range stages.AllStages {
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageUnwind(db, stage, 0); err != nil {
|
2020-08-10 23:38:19 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
2020-07-07 04:00:25 +00:00
|
|
|
}
|
|
|
|
|
2020-10-28 03:18:10 +00:00
|
|
|
func resetState(db ethdb.Database, _ context.Context) error {
|
2020-07-07 04:00:25 +00:00
|
|
|
fmt.Printf("Before reset: \n")
|
|
|
|
if err := printStages(db); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// don't reset senders here
|
|
|
|
if err := resetExec(db); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-07-17 05:52:09 +00:00
|
|
|
if err := stagedsync.ResetHashState(db); err != nil {
|
2020-07-07 04:00:25 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := resetHistory(db); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-09-28 17:18:36 +00:00
|
|
|
if err := resetLogIndex(db); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-10-12 08:39:04 +00:00
|
|
|
if err := resetCallTraces(db); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-07-07 10:07:14 +00:00
|
|
|
if err := resetTxLookup(db); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-09-03 08:20:04 +00:00
|
|
|
if err := resetTxPool(db); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-09-11 10:33:46 +00:00
|
|
|
if err := resetFinish(db); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-07-07 04:00:25 +00:00
|
|
|
|
|
|
|
// set genesis after reset all buckets
|
|
|
|
if _, _, err := core.DefaultGenesisBlock().CommitGenesisState(db, false); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Printf("After reset: \n")
|
|
|
|
if err := printStages(db); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2020-07-07 10:07:14 +00:00
|
|
|
|
2020-10-28 03:18:10 +00:00
|
|
|
func resetSenders(db rawdb.DatabaseWriter) error {
|
|
|
|
if err := db.(ethdb.BucketsMigrator).ClearBuckets(
|
2020-07-07 07:11:10 +00:00
|
|
|
dbutils.Senders,
|
|
|
|
); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageProgress(db, stages.Senders, 0); err != nil {
|
2020-07-15 11:53:12 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageUnwind(db, stages.Senders, 0); err != nil {
|
2020-07-15 11:53:12 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
2020-07-07 07:11:10 +00:00
|
|
|
}
|
2020-07-07 04:00:25 +00:00
|
|
|
|
2020-10-28 03:18:10 +00:00
|
|
|
func resetExec(db rawdb.DatabaseWriter) error {
|
|
|
|
if err := db.(ethdb.BucketsMigrator).ClearBuckets(
|
2020-07-07 04:00:25 +00:00
|
|
|
dbutils.CurrentStateBucket,
|
|
|
|
dbutils.ContractCodeBucket,
|
|
|
|
dbutils.PlainStateBucket,
|
|
|
|
dbutils.PlainAccountChangeSetBucket,
|
|
|
|
dbutils.PlainStorageChangeSetBucket,
|
|
|
|
dbutils.PlainContractCodeBucket,
|
2020-09-01 06:48:25 +00:00
|
|
|
dbutils.BlockReceiptsPrefix,
|
2020-10-25 08:38:55 +00:00
|
|
|
dbutils.Log,
|
2020-07-07 04:00:25 +00:00
|
|
|
dbutils.IncarnationMapBucket,
|
|
|
|
dbutils.CodeBucket,
|
|
|
|
); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageProgress(db, stages.Execution, 0); err != nil {
|
2020-07-15 11:53:12 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageUnwind(db, stages.Execution, 0); err != nil {
|
2020-07-15 11:53:12 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
2020-07-07 04:00:25 +00:00
|
|
|
}
|
|
|
|
|
2020-10-28 03:18:10 +00:00
|
|
|
func resetHistory(db rawdb.DatabaseWriter) error {
|
|
|
|
if err := db.(ethdb.BucketsMigrator).ClearBuckets(
|
2020-07-07 04:00:25 +00:00
|
|
|
dbutils.AccountsHistoryBucket,
|
|
|
|
dbutils.StorageHistoryBucket,
|
|
|
|
); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageProgress(db, stages.AccountHistoryIndex, 0); err != nil {
|
2020-07-07 04:00:25 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageProgress(db, stages.StorageHistoryIndex, 0); err != nil {
|
2020-07-07 04:00:25 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageUnwind(db, stages.AccountHistoryIndex, 0); err != nil {
|
2020-07-15 11:53:12 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageUnwind(db, stages.StorageHistoryIndex, 0); err != nil {
|
2020-07-15 11:53:12 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-07-07 04:00:25 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-28 03:18:10 +00:00
|
|
|
func resetLogIndex(db rawdb.DatabaseWriter) error {
|
|
|
|
if err := db.(ethdb.BucketsMigrator).ClearBuckets(
|
2020-09-28 17:18:36 +00:00
|
|
|
dbutils.LogAddressIndex,
|
|
|
|
dbutils.LogTopicIndex,
|
|
|
|
); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageProgress(db, stages.LogIndex, 0); err != nil {
|
2020-09-28 17:18:36 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageUnwind(db, stages.LogIndex, 0); err != nil {
|
2020-09-28 17:18:36 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-28 03:18:10 +00:00
|
|
|
func resetCallTraces(db rawdb.DatabaseWriter) error {
|
|
|
|
if err := db.(ethdb.BucketsMigrator).ClearBuckets(
|
2020-10-12 08:39:04 +00:00
|
|
|
dbutils.CallFromIndex,
|
|
|
|
dbutils.CallToIndex,
|
|
|
|
); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageProgress(db, stages.CallTraces, 0); err != nil {
|
2020-10-12 08:39:04 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageUnwind(db, stages.CallTraces, 0); err != nil {
|
2020-10-12 08:39:04 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-28 03:18:10 +00:00
|
|
|
func resetTxLookup(db rawdb.DatabaseWriter) error {
|
|
|
|
if err := db.(ethdb.BucketsMigrator).ClearBuckets(
|
2020-07-07 10:07:14 +00:00
|
|
|
dbutils.TxLookupPrefix,
|
|
|
|
); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageProgress(db, stages.TxLookup, 0); err != nil {
|
2020-07-07 10:07:14 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageUnwind(db, stages.TxLookup, 0); err != nil {
|
2020-07-15 11:53:12 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-07-07 10:07:14 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2020-09-03 08:20:04 +00:00
|
|
|
|
|
|
|
func resetTxPool(db ethdb.Putter) error {
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageProgress(db, stages.TxPool, 0); err != nil {
|
2020-09-03 08:20:04 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageUnwind(db, stages.TxPool, 0); err != nil {
|
2020-09-03 08:20:04 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-09-11 10:33:46 +00:00
|
|
|
func resetFinish(db ethdb.Putter) error {
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageProgress(db, stages.Finish, 0); err != nil {
|
2020-09-11 10:33:46 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-12-21 11:01:37 +00:00
|
|
|
if err := stages.SaveStageUnwind(db, stages.Finish, 0); err != nil {
|
2020-09-11 10:33:46 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-11-22 21:25:26 +00:00
|
|
|
func printStages(db ethdb.Getter) error {
|
2020-07-07 04:00:25 +00:00
|
|
|
var err error
|
|
|
|
var progress uint64
|
2020-08-05 10:13:35 +00:00
|
|
|
w := new(tabwriter.Writer)
|
|
|
|
defer w.Flush()
|
|
|
|
w.Init(os.Stdout, 8, 8, 0, '\t', 0)
|
2020-09-05 16:07:27 +00:00
|
|
|
for _, stage := range stages.AllStages {
|
2020-12-21 11:01:37 +00:00
|
|
|
if progress, err = stages.GetStageProgress(db, stage); err != nil {
|
2020-07-07 04:00:25 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-09-05 16:07:27 +00:00
|
|
|
fmt.Fprintf(w, "%s \t %d\n", string(stage), progress)
|
2020-07-07 04:00:25 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2020-07-25 07:35:08 +00:00
|
|
|
|
|
|
|
func copyCompact() error {
|
|
|
|
from := chaindata
|
|
|
|
backup := from + "_backup"
|
|
|
|
to := chaindata + "_copy"
|
|
|
|
|
|
|
|
log.Info("Start db copy-compact")
|
|
|
|
|
|
|
|
env, errOpen := lmdb.NewEnv()
|
|
|
|
if errOpen != nil {
|
|
|
|
return errOpen
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := env.Open(from, lmdb.Readonly, 0644); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-08-02 11:53:08 +00:00
|
|
|
_ = os.RemoveAll(to)
|
2020-07-25 07:35:08 +00:00
|
|
|
if err := os.MkdirAll(to, 0744); err != nil {
|
|
|
|
return fmt.Errorf("could not create dir: %s, %w", to, err)
|
|
|
|
}
|
2020-10-10 06:05:18 +00:00
|
|
|
|
|
|
|
f1, err := os.Stat(path.Join(from, "data.mdb"))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = env.SetMapSize(f1.Size() + int64((1 * datasize.GB).Bytes()))
|
|
|
|
if err != nil {
|
2020-07-25 07:35:08 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-07-25 17:18:45 +00:00
|
|
|
|
|
|
|
f, err := os.Stat(path.Join(from, "data.mdb"))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx, stopLogging := context.WithCancel(context.Background())
|
|
|
|
defer stopLogging()
|
|
|
|
wg := sync.WaitGroup{}
|
|
|
|
wg.Add(1)
|
|
|
|
go func() {
|
|
|
|
defer wg.Done()
|
|
|
|
|
|
|
|
for {
|
2020-07-27 13:51:59 +00:00
|
|
|
time.Sleep(20 * time.Second)
|
|
|
|
|
2020-07-25 17:18:45 +00:00
|
|
|
select {
|
|
|
|
case <-ctx.Done():
|
|
|
|
return
|
|
|
|
default:
|
|
|
|
}
|
2020-07-27 13:51:59 +00:00
|
|
|
|
2020-07-25 17:18:45 +00:00
|
|
|
f2, err := os.Stat(path.Join(to, "data.mdb"))
|
|
|
|
if err != nil {
|
|
|
|
log.Error("Progress check failed", "err", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
log.Info("Progress", "done", common.StorageSize(f2.Size()), "from", common.StorageSize(f.Size()))
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2020-07-25 07:35:08 +00:00
|
|
|
if err := env.CopyFlag(to, lmdb.CopyCompact); err != nil {
|
|
|
|
return fmt.Errorf("%w, from: %s, to: %s", err, from, to)
|
|
|
|
}
|
2020-07-25 17:18:45 +00:00
|
|
|
|
|
|
|
stopLogging()
|
|
|
|
wg.Wait()
|
2020-07-25 07:35:08 +00:00
|
|
|
if err := os.Rename(from, backup); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := os.Rename(to, from); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := os.RemoveAll(backup); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|