From 140d87c486f82ea3aa9007379c99d6b8b4211d0d Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Thu, 23 Feb 2023 15:05:14 +0530 Subject: [PATCH 1/4] add : impossible reorg block dump --- core/blockchain.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/core/blockchain.go b/core/blockchain.go index cbcf02fef4..e7fb13c959 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -22,6 +22,8 @@ import ( "fmt" "io" "math/big" + "os" + "path/filepath" "sort" "sync" "sync/atomic" @@ -2191,6 +2193,20 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { } else { // len(newChain) == 0 && len(oldChain) > 0 // rewind the canonical chain to a lower point. + out := fmt.Sprintf("oldChain: %+v,\n\noldBlock : %+v,\n\nnewBlock : %+v", oldChain, oldBlock, newBlock) + + home, err := os.UserHomeDir() + if err != nil { + log.Error("Impossible reorg : Unable to get user home dir", "Error", err) + } + + outPath := filepath.Join(home, fmt.Sprintf("impossibleReorg-%v.txt", time.Now().Format(time.RFC3339))) + + err = os.WriteFile(outPath, []byte(out), 0600) + if err != nil { + log.Error("Impossible reorg : Unable to write to file", "Error", err) + } + log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "oldblocks", len(oldChain), "newnum", newBlock.Number(), "newhash", newBlock.Hash(), "newblocks", len(newChain)) } // Insert the new chain(except the head block(reverse order)), From d97e7742f22ae67588a7d5b69d40c9af6066d212 Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Thu, 23 Feb 2023 16:30:53 +0530 Subject: [PATCH 2/4] chg : 3 seperate files for impossoble reorg dump --- core/blockchain.go | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index e7fb13c959..fa4c7a04b6 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2193,18 +2193,33 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { } else { // len(newChain) == 0 && len(oldChain) > 0 // rewind the canonical chain to a lower point. - out := fmt.Sprintf("oldChain: %+v,\n\noldBlock : %+v,\n\nnewBlock : %+v", oldChain, oldBlock, newBlock) home, err := os.UserHomeDir() if err != nil { - log.Error("Impossible reorg : Unable to get user home dir", "Error", err) + fmt.Println("Impossible reorg : Unable to get user home dir", "Error", err) } + outPath := filepath.Join(home, "impossible-reorgs", fmt.Sprintf("%v-impossibleReorg", time.Now().Format(time.RFC3339))) - outPath := filepath.Join(home, fmt.Sprintf("impossibleReorg-%v.txt", time.Now().Format(time.RFC3339))) + if _, err := os.Stat(outPath); errors.Is(err, os.ErrNotExist) { + err := os.MkdirAll(outPath, os.ModePerm) + if err != nil { + log.Error("Impossible reorg : Unable to create Dir", "Error", err) + } + } + + err = os.WriteFile(filepath.Join(outPath, "oldchain.txt"), []byte(fmt.Sprintf("%+v", oldChain)), 0600) + if err != nil { + log.Error("Impossible reorg : Unable to write to oldchain.txt", "Error", err) + } + + err = os.WriteFile(filepath.Join(outPath, "oldBlock.txt"), []byte(fmt.Sprintf("%+v", oldBlock)), 0600) + if err != nil { + log.Error("Impossible reorg : Unable to write to oldblock.txt", "Error", err) + } - err = os.WriteFile(outPath, []byte(out), 0600) + err = os.WriteFile(filepath.Join(outPath, "newBlock.txt"), []byte(fmt.Sprintf("%+v", newBlock)), 0600) if err != nil { - log.Error("Impossible reorg : Unable to write to file", "Error", err) + log.Error("Impossible reorg : Unable to write to newBlock.txt", "Error", err) } log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "oldblocks", len(oldChain), "newnum", newBlock.Number(), "newhash", newBlock.Hash(), "newblocks", len(newChain)) From f736533e5fdc15a94f72fbda205fb408775bc07a Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Thu, 23 Feb 2023 18:11:46 +0530 Subject: [PATCH 3/4] add : use exportBlocks method and RLP blocks before writing --- core/blockchain.go | 52 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index fa4c7a04b6..8e47c81f93 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -18,6 +18,7 @@ package core import ( + "compress/gzip" "errors" "fmt" "io" @@ -25,6 +26,7 @@ import ( "os" "path/filepath" "sort" + "strings" "sync" "sync/atomic" "time" @@ -2207,19 +2209,19 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { } } - err = os.WriteFile(filepath.Join(outPath, "oldchain.txt"), []byte(fmt.Sprintf("%+v", oldChain)), 0600) + err = ExportBlocks(oldChain, filepath.Join(outPath, "oldChain.gz")) if err != nil { - log.Error("Impossible reorg : Unable to write to oldchain.txt", "Error", err) + log.Error("Impossible reorg : Unable to export oldChain", "Error", err) } - err = os.WriteFile(filepath.Join(outPath, "oldBlock.txt"), []byte(fmt.Sprintf("%+v", oldBlock)), 0600) + err = ExportBlocks([]*types.Block{oldBlock}, filepath.Join(outPath, "oldBlock.gz")) if err != nil { - log.Error("Impossible reorg : Unable to write to oldblock.txt", "Error", err) + log.Error("Impossible reorg : Unable to export oldBlock", "Error", err) } - err = os.WriteFile(filepath.Join(outPath, "newBlock.txt"), []byte(fmt.Sprintf("%+v", newBlock)), 0600) + err = ExportBlocks([]*types.Block{newBlock}, filepath.Join(outPath, "newBlock.gz")) if err != nil { - log.Error("Impossible reorg : Unable to write to newBlock.txt", "Error", err) + log.Error("Impossible reorg : Unable to export newBlock", "Error", err) } log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "oldblocks", len(oldChain), "newnum", newBlock.Number(), "newhash", newBlock.Hash(), "newblocks", len(newChain)) @@ -2274,6 +2276,44 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { return nil } +// ExportBlocks exports blocks into the specified file, truncating any data +// already present in the file. +func ExportBlocks(blocks []*types.Block, fn string) error { + log.Info("Exporting blockchain", "file", fn) + + // Open the file handle and potentially wrap with a gzip stream + fh, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) + if err != nil { + return err + } + defer fh.Close() + + var writer io.Writer = fh + if strings.HasSuffix(fn, ".gz") { + writer = gzip.NewWriter(writer) + defer writer.(*gzip.Writer).Close() + } + // Iterate over the blocks and export them + if err := ExportN(writer, blocks); err != nil { + return err + } + + log.Info("Exported blocks", "file", fn) + + return nil +} + +// ExportBlock writes a block to the given writer. +func ExportN(w io.Writer, blocks []*types.Block) error { + for _, block := range blocks { + if err := block.EncodeRLP(w); err != nil { + return err + } + } + + return nil +} + // InsertBlockWithoutSetHead executes the block, runs the necessary verification // upon it and then persist the block and the associate state into the database. // The key difference between the InsertChain is it won't do the canonical chain From 3a20d124be900e7fa032ccbac0e6dbfefae6c977 Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Thu, 23 Feb 2023 18:14:17 +0530 Subject: [PATCH 4/4] chg : small changes --- core/blockchain.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 8e47c81f93..fd26ab4f01 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2207,21 +2207,21 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { if err != nil { log.Error("Impossible reorg : Unable to create Dir", "Error", err) } - } - - err = ExportBlocks(oldChain, filepath.Join(outPath, "oldChain.gz")) - if err != nil { - log.Error("Impossible reorg : Unable to export oldChain", "Error", err) - } + } else { + err = ExportBlocks(oldChain, filepath.Join(outPath, "oldChain.gz")) + if err != nil { + log.Error("Impossible reorg : Unable to export oldChain", "Error", err) + } - err = ExportBlocks([]*types.Block{oldBlock}, filepath.Join(outPath, "oldBlock.gz")) - if err != nil { - log.Error("Impossible reorg : Unable to export oldBlock", "Error", err) - } + err = ExportBlocks([]*types.Block{oldBlock}, filepath.Join(outPath, "oldBlock.gz")) + if err != nil { + log.Error("Impossible reorg : Unable to export oldBlock", "Error", err) + } - err = ExportBlocks([]*types.Block{newBlock}, filepath.Join(outPath, "newBlock.gz")) - if err != nil { - log.Error("Impossible reorg : Unable to export newBlock", "Error", err) + err = ExportBlocks([]*types.Block{newBlock}, filepath.Join(outPath, "newBlock.gz")) + if err != nil { + log.Error("Impossible reorg : Unable to export newBlock", "Error", err) + } } log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "oldblocks", len(oldChain), "newnum", newBlock.Number(), "newhash", newBlock.Hash(), "newblocks", len(newChain))