diff --git a/cmd/hack/hack.go b/cmd/hack/hack.go index 9a797d816218b173c15f7a87bb6ea0b92df7ebea..010a2419cece75817de4625bfea6992aa3dadbdb 100644 --- a/cmd/hack/hack.go +++ b/cmd/hack/hack.go @@ -15,9 +15,11 @@ import ( _ "net/http/pprof" //nolint:gosec "os" "os/signal" + "regexp" "runtime" "runtime/pprof" "sort" + "strconv" "strings" "syscall" "time" @@ -2380,6 +2382,79 @@ func junkdb() error { return nil } +func histStats() error { + files, err := os.ReadDir(".") + if err != nil { + return err + } + endBlockMap := map[uint64]struct{}{} + pageMap := map[string]map[uint64]uint64{} + keys := []string{"ahistory", "shistory", "abitmap", "sbitmap"} + for _, k := range keys { + pageMap[k] = map[uint64]uint64{} + } + re := regexp.MustCompile(`(ahistory|shistory|abitmap|sbitmap).([0-9]+).txt`) + for _, f := range files { + name := f.Name() + subs := re.FindStringSubmatch(name) + if len(subs) != 3 { + if len(subs) != 0 { + log.Warn("File ignored by changes scan, more than 3 submatches", "name", name, "submatches", len(subs)) + } + continue + } + var endBlock uint64 + if endBlock, err = strconv.ParseUint(subs[2], 10, 64); err != nil { + return err + } + endBlockMap[endBlock] = struct{}{} + var ff *os.File + if ff, err = os.Open(name); err != nil { + return err + } + scanner := bufio.NewScanner(ff) + // Skip 5 lines + for i := 0; i < 5; i++ { + scanner.Scan() + } + var totalPages uint64 + for i := 0; i < 3; i++ { + scanner.Scan() + line := scanner.Text() + p := strings.Index(line, ": ") + var pages uint64 + if pages, err = strconv.ParseUint(line[p+2:], 10, 64); err != nil { + return err + } + totalPages += pages + } + pageMap[subs[1]][endBlock] = totalPages + ff.Close() + } + var endBlocks []uint64 + for endBlock := range endBlockMap { + endBlocks = append(endBlocks, endBlock) + } + sort.Slice(endBlocks, func(i, j int) bool { + return endBlocks[i] < endBlocks[j] + }) + var lastEndBlock uint64 + fmt.Printf("endBlock,%s\n", strings.Join(keys, ",")) + for _, endBlock := range endBlocks { + fmt.Printf("%d", endBlock) + for _, k := range keys { + if lastEndBlock == 0 { + fmt.Printf(",%.3f", float64(pageMap[k][endBlock])/256.0/1024.0) + } else { + fmt.Printf(",%.3f", float64(pageMap[k][endBlock]-pageMap[k][lastEndBlock])/256.0/1024.0) + } + } + fmt.Printf("\n") + lastEndBlock = endBlock + } + return nil +} + func main() { debug.RaiseFdLimit() flag.Parse() @@ -2553,6 +2628,8 @@ func main() { err = mainnetGenesis() case "junkdb": err = junkdb() + case "histStats": + err = histStats() } if err != nil { diff --git a/cmd/state/commands/check_change_sets.go b/cmd/state/commands/check_change_sets.go index 38713577e6a5e6f9c28ac5bde91c72914d6aae7e..199e7e778ef7da811abfa22fb94c6cdd4f35a54f 100644 --- a/cmd/state/commands/check_change_sets.go +++ b/cmd/state/commands/check_change_sets.go @@ -120,17 +120,19 @@ func CheckChangeSets(genesis *core.Genesis, logger log.Logger, blockNum uint64, if err != nil { return err } - var block *types.Block - block, _, err = rawdb.ReadBlockWithSenders(rwtx, blockHash, blockNum) + var b *types.Block + b, _, err = rawdb.ReadBlockWithSenders(rwtx, blockHash, blockNum) if err != nil { return err } - if block == nil { + if b == nil { break } - intraBlockState := state.New(state.NewPlainState(historyTx, block.NumberU64()-1)) - csw := state.NewChangeSetWriterPlain(nil /* db */, block.NumberU64()-1) + reader := state.NewPlainState(historyTx, blockNum-1) + reader.SetTrace(blockNum == uint64(block)) + intraBlockState := state.New(reader) + csw := state.NewChangeSetWriterPlain(nil /* db */, blockNum-1) var blockWriter state.StateWriter if nocheck { blockWriter = noOpWriter @@ -140,19 +142,19 @@ func CheckChangeSets(genesis *core.Genesis, logger log.Logger, blockNum uint64, getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(rwtx, hash, number) } contractHasTEVM := ethdb.GetHasTEVM(rwtx) - receipts, err1 := runBlock(intraBlockState, noOpWriter, blockWriter, chainConfig, getHeader, contractHasTEVM, block, vmConfig) + receipts, err1 := runBlock(intraBlockState, noOpWriter, blockWriter, chainConfig, getHeader, contractHasTEVM, b, vmConfig) if err1 != nil { return err1 } if writeReceipts { - if chainConfig.IsByzantium(block.NumberU64()) { + if chainConfig.IsByzantium(blockNum) { receiptSha := types.DeriveSha(receipts) - if receiptSha != block.ReceiptHash() { - return fmt.Errorf("mismatched receipt headers for block %d", block.NumberU64()) + if receiptSha != b.ReceiptHash() { + return fmt.Errorf("mismatched receipt headers for block %d", blockNum) } } - if err := rawdb.AppendReceipts(rwtx, block.NumberU64(), receipts); err != nil { + if err := rawdb.AppendReceipts(rwtx, blockNum, receipts); err != nil { return err } } @@ -226,7 +228,7 @@ func CheckChangeSets(genesis *core.Genesis, logger log.Logger, blockNum uint64, fmt.Println("interrupted, please wait for cleanup...") case <-commitEvery.C: if writeReceipts { - log.Info("Committing receipts", "up to block", block.NumberU64()) + log.Info("Committing receipts", "up to block", b.NumberU64()) if err = rwtx.Commit(); err != nil { return err } diff --git a/cmd/state/commands/history2.go b/cmd/state/commands/history2.go index 88e93db01f022a7c63bace089810b822b9311308..7ded3435d73b704bf66850d7f4cbf0fcb3cc8018 100644 --- a/cmd/state/commands/history2.go +++ b/cmd/state/commands/history2.go @@ -26,9 +26,14 @@ import ( "github.com/spf13/cobra" ) +var ( + traceBlock int +) + func init() { withBlock(history2Cmd) withDatadir(history2Cmd) + history2Cmd.Flags().IntVar(&traceBlock, "traceblock", 0, "block number at which to turn on tracing") rootCmd.AddCommand(history2Cmd) } @@ -62,7 +67,7 @@ func History2(genesis *core.Genesis, logger log.Logger) error { } defer historyTx.Rollback() aggPath := filepath.Join(datadir, "aggregator") - h, err3 := aggregator.NewHistory(aggPath, 499_999, aggregationStep) + h, err3 := aggregator.NewHistory(aggPath, block, aggregationStep) if err3 != nil { return fmt.Errorf("create history: %w", err3) } @@ -71,7 +76,7 @@ func History2(genesis *core.Genesis, logger log.Logger) error { vmConfig := vm.Config{} interrupt := false - blockNum := block + blockNum := uint64(0) var txNum uint64 = 1 trace := false logEvery := time.NewTicker(logInterval) @@ -104,7 +109,9 @@ func History2(genesis *core.Genesis, logger log.Logger) error { } r := h.MakeHistoryReader() readWrapper := &HistoryWrapper{r: r} - //readWrapper.trace = blockNum == 999_999 + if traceBlock != 0 { + readWrapper.trace = blockNum == uint64(traceBlock) + } writeWrapper := state.NewNoopWriter() getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(historyTx, hash, number) } if txNum, _, err = runHistory2(trace, blockNum, txNum, readWrapper, writeWrapper, chainConfig, getHeader, b, vmConfig); err != nil { @@ -138,11 +145,13 @@ func runHistory2(trace bool, blockNum, txNumStart uint64, hw *HistoryWrapper, ww daoBlock = false } ibs.Prepare(tx.Hash(), block.Hash(), i) - receipt, _, err := core.ApplyTransaction(chainConfig, getHeader, engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig, nil) if err != nil { return 0, nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) } + if traceBlock != 0 && blockNum == uint64(traceBlock) { + fmt.Printf("tx idx %d, num %d, gas used %d\n", i, txNum, receipt.GasUsed) + } receipts = append(receipts, receipt) txNum++ } diff --git a/core/state/plain_readonly.go b/core/state/plain_readonly.go index a75c79503c3b0208cc7c3433bafb7900a45683cf..dc076b8867454b3ffe41422b0eb6424d4eb8923e 100644 --- a/core/state/plain_readonly.go +++ b/core/state/plain_readonly.go @@ -19,6 +19,7 @@ package state import ( "bytes" "encoding/binary" + "fmt" "github.com/google/btree" "github.com/holiman/uint256" @@ -45,6 +46,7 @@ type PlainState struct { tx kv.Tx blockNr uint64 storage map[common.Address]*btree.BTree + trace bool } func NewPlainState(tx kv.Tx, blockNr uint64) *PlainState { @@ -61,6 +63,10 @@ func NewPlainState(tx kv.Tx, blockNr uint64) *PlainState { } } +func (s *PlainState) SetTrace(trace bool) { + s.trace = trace +} + func (s *PlainState) SetBlockNr(blockNr uint64) { s.blockNr = blockNr } @@ -175,6 +181,9 @@ func (s *PlainState) ReadAccountStorage(address common.Address, incarnation uint if err != nil { return nil, err } + if s.trace { + fmt.Printf("ReadAccountStorage [%x] [%x] => [%x]\n", address, *key, enc) + } if len(enc) == 0 { return nil, nil } diff --git a/go.mod b/go.mod index adb4374c622cd16b991376b208632a0f82103277..20f570ad526b4e43852dcc863962a58296d87ee8 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220212125515-3442f42457cb + github.com/ledgerwatch/erigon-lib v0.0.0-20220212145123-d9367b582a21 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect diff --git a/go.sum b/go.sum index 1025344a9e6c60d9607db5709ed9790a022eab09..c130a49d8eb4d587255f1e3d6fc08723ccc9e39a 100644 --- a/go.sum +++ b/go.sum @@ -632,8 +632,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220212125515-3442f42457cb h1:kzS/0e5EHNBeFGybHt2zboOlDeoPydFfjQqBvGhCt8c= -github.com/ledgerwatch/erigon-lib v0.0.0-20220212125515-3442f42457cb/go.mod h1:phuzMr8tLvqjo5cQVA9jj8odAso6eLyS4LFmUJrDFGw= +github.com/ledgerwatch/erigon-lib v0.0.0-20220212145123-d9367b582a21 h1:W0u7HzNxrwtSNISHac902xrJlT2O66gkuaBQdgNfHZI= +github.com/ledgerwatch/erigon-lib v0.0.0-20220212145123-d9367b582a21/go.mod h1:phuzMr8tLvqjo5cQVA9jj8odAso6eLyS4LFmUJrDFGw= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ=