From 0fde3f8b48918b46b899f7236fd234cca728a1a4 Mon Sep 17 00:00:00 2001 From: Aaron Buchwald Date: Fri, 22 Oct 2021 18:32:10 -0400 Subject: [PATCH] Add simple helper for writing/reading blocks from file --- core/types/block.go | 33 ++++++++++++++++++++++++++++ core/types/block_test.go | 46 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/core/types/block.go b/core/types/block.go index 360f1eb47c2bc..839eb71cecba4 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -21,7 +21,9 @@ import ( "encoding/binary" "fmt" "io" + "io/ioutil" "math/big" + "os" "reflect" "sync/atomic" "time" @@ -383,3 +385,34 @@ func (b *Block) Hash() common.Hash { } type Blocks []*Block + +func WriteBlocks(w io.Writer, blocks Blocks) error { + return rlp.Encode(w, blocks) +} + +func ReadBlocks(b []byte) ([]*Block, error) { + blocks := new(Blocks) + if err := rlp.DecodeBytes(b, blocks); err != nil { + return nil, err + } + return *blocks, nil +} + +func WriteBlocksToFile(filename string, blocks Blocks) error { + f, err := os.Create(filename) + if err != nil { + return err + } + defer f.Close() + + return WriteBlocks(f, blocks) +} + +func ReadBlocksFromFile(filename string) ([]*Block, error) { + b, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + + return ReadBlocks(b) +} diff --git a/core/types/block_test.go b/core/types/block_test.go index 0b9a4def8d287..8b412b242753a 100644 --- a/core/types/block_test.go +++ b/core/types/block_test.go @@ -20,6 +20,7 @@ import ( "bytes" "hash" "math/big" + "path" "reflect" "testing" @@ -217,6 +218,51 @@ func BenchmarkEncodeBlock(b *testing.B) { } } +func TestEncodeBlocks(t *testing.T) { + blocks := []*Block{ + makeBenchBlock(), + makeBenchBlock(), + makeBenchBlock(), + } + + buffer := bytes.NewBuffer(make([]byte, 0, 32000)) + if err := WriteBlocks(buffer, blocks); err != nil { + t.Fatal(err) + } + + decodedBlocks, err := ReadBlocks(buffer.Bytes()) + if err != nil { + t.Fatal(err) + } + + if len(blocks) != len(decodedBlocks) { + t.Fatalf("expected decoded blocks (%d) == blocks (%d)", len(decodedBlocks), len(blocks)) + } + for i, decodedBlock := range decodedBlocks { + if blocks[i].Hash() != decodedBlock.Hash() { + t.Fatalf("Expected hatches to match at index %d, found decoded block hash: %s, actual hash: %s", i, decodedBlock.Hash(), blocks[i].Hash()) + } + } + + tempFile := path.Join(t.TempDir(), "blocks") + if err := WriteBlocksToFile(tempFile, blocks); err != nil { + t.Fatal(err) + } + + blocksFromFile, err := ReadBlocksFromFile(tempFile) + if err != nil { + t.Fatal(err) + } + if len(blocks) != len(blocksFromFile) { + t.Fatalf("expected blocks from file (%d) == blocks (%d)", len(blocksFromFile), len(blocks)) + } + for i, blockFromFile := range blocksFromFile { + if blocks[i].Hash() != blockFromFile.Hash() { + t.Fatalf("Expected hatches to match at index %d, found block from file hash: %s, actual hash: %s", i, blockFromFile.Hash(), blocks[i].Hash()) + } + } +} + // testHasher is the helper tool for transaction/receipt list hashing. // The original hasher is trie, in order to get rid of import cycle, // use the testing hasher instead.