mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 22:56:43 +00:00
core: add : impossible reorg block dump (#754)
* add : impossible reorg block dump * chg : 3 seperate files for impossoble reorg dump * add : use exportBlocks method and RLP blocks before writing * chg : small changes
This commit is contained in:
parent
4ca527255b
commit
f973926ef0
1 changed files with 71 additions and 0 deletions
|
|
@ -18,12 +18,16 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"compress/gzip"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -2241,6 +2245,35 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
|
||||||
} else {
|
} else {
|
||||||
// len(newChain) == 0 && len(oldChain) > 0
|
// len(newChain) == 0 && len(oldChain) > 0
|
||||||
// rewind the canonical chain to a lower point.
|
// rewind the canonical chain to a lower point.
|
||||||
|
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
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)))
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
} 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{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))
|
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)),
|
// Insert the new chain(except the head block(reverse order)),
|
||||||
|
|
@ -2293,6 +2326,44 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
|
||||||
return nil
|
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
|
// InsertBlockWithoutSetHead executes the block, runs the necessary verification
|
||||||
// upon it and then persist the block and the associate state into the database.
|
// 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
|
// The key difference between the InsertChain is it won't do the canonical chain
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue