aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2015-03-18 20:36:48 +0800
committerFelix Lange <fjl@twurst.com>2015-03-18 20:36:48 +0800
commitb5b83db450974f70f4bc25f280cc6ec9193f8e19 (patch)
tree88127007dcf407a6b991562e455a1be6accd04a0
parentc298148a7f0890cd5ed62d2a91cc81431b2731f1 (diff)
downloadgo-tangerine-b5b83db450974f70f4bc25f280cc6ec9193f8e19.tar
go-tangerine-b5b83db450974f70f4bc25f280cc6ec9193f8e19.tar.gz
go-tangerine-b5b83db450974f70f4bc25f280cc6ec9193f8e19.tar.bz2
go-tangerine-b5b83db450974f70f4bc25f280cc6ec9193f8e19.tar.lz
go-tangerine-b5b83db450974f70f4bc25f280cc6ec9193f8e19.tar.xz
go-tangerine-b5b83db450974f70f4bc25f280cc6ec9193f8e19.tar.zst
go-tangerine-b5b83db450974f70f4bc25f280cc6ec9193f8e19.zip
core: use package rlp to encode blocks
This also changes the chain export format so there is no enclosing list around the blocks, which enables streaming export.
-rw-r--r--cmd/utils/cmd.go37
-rw-r--r--core/chain_manager.go27
2 files changed, 34 insertions, 30 deletions
diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go
index 74fd5334e..66e89abef 100644
--- a/cmd/utils/cmd.go
+++ b/cmd/utils/cmd.go
@@ -23,14 +23,15 @@ package utils
import (
"fmt"
+ "io"
"os"
"os/signal"
"regexp"
+ "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/rlp"
)
@@ -152,29 +153,35 @@ func ImportChain(chainmgr *core.ChainManager, fn string) error {
}
defer fh.Close()
- var blocks types.Blocks
- if err := rlp.Decode(fh, &blocks); err != nil {
- return err
- }
-
chainmgr.Reset()
- if err := chainmgr.InsertChain(blocks); err != nil {
- return err
+ stream := rlp.NewStream(fh)
+ var i int
+ for ; ; i++ {
+ var b types.Block
+ err := stream.Decode(&b)
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ return fmt.Errorf("at block %d: %v", i, err)
+ }
+ if err := chainmgr.InsertChain(types.Blocks{b}); err != nil {
+ return fmt.Errorf("invalid block %d: %v", i, err)
+ }
}
- fmt.Printf("imported %d blocks\n", len(blocks))
-
+ fmt.Printf("imported %d blocks\n", i)
return nil
}
func ExportChain(chainmgr *core.ChainManager, fn string) error {
fmt.Printf("exporting blockchain '%s'\n", fn)
-
- data := chainmgr.Export()
-
- if err := common.WriteFile(fn, data); err != nil {
+ fh, err := os.OpenFile(fn, os.O_WRONLY|os.O_TRUNC, os.ModePerm)
+ if err != nil {
+ return err
+ }
+ defer fh.Close()
+ if err := chainmgr.Export(fh); err != nil {
return err
}
fmt.Printf("exported blockchain\n")
-
return nil
}
diff --git a/core/chain_manager.go b/core/chain_manager.go
index 5316a3423..060805428 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -3,6 +3,7 @@ package core
import (
"bytes"
"fmt"
+ "io"
"math/big"
"sync"
@@ -254,22 +255,20 @@ func (bc *ChainManager) ResetWithGenesisBlock(gb *types.Block) {
bc.currentBlock = bc.genesisBlock
}
-func (self *ChainManager) Export() []byte {
+// Export writes the active chain to the given writer.
+func (self *ChainManager) Export(w io.Writer) error {
self.mu.RLock()
defer self.mu.RUnlock()
-
chainlogger.Infof("exporting %v blocks...\n", self.currentBlock.Header().Number)
-
- blocks := make([]*types.Block, int(self.currentBlock.NumberU64())+1)
for block := self.currentBlock; block != nil; block = self.GetBlock(block.Header().ParentHash) {
- blocks[block.NumberU64()] = block
+ if err := block.EncodeRLP(w); err != nil {
+ return err
+ }
}
-
- return common.Encode(blocks)
+ return nil
}
func (bc *ChainManager) insert(block *types.Block) {
- //encodedBlock := common.Encode(block)
bc.blockDb.Put([]byte("LastBlock"), block.Hash().Bytes())
bc.currentBlock = block
bc.lastBlockHash = block.Hash()
@@ -279,10 +278,9 @@ func (bc *ChainManager) insert(block *types.Block) {
}
func (bc *ChainManager) write(block *types.Block) {
- encodedBlock := common.Encode(block.RlpDataForStorage())
-
+ enc, _ := rlp.EncodeToBytes((*types.StorageBlock)(block))
key := append(blockHashPre, block.Hash().Bytes()...)
- bc.blockDb.Put(key, encodedBlock)
+ bc.blockDb.Put(key, enc)
}
// Accessors
@@ -324,13 +322,12 @@ func (self *ChainManager) GetBlock(hash common.Hash) *types.Block {
if len(data) == 0 {
return nil
}
- var block types.Block
+ var block types.StorageBlock
if err := rlp.Decode(bytes.NewReader(data), &block); err != nil {
- fmt.Println(err)
+ chainlogger.Errorf("invalid block RLP for hash %x: %v", hash, err)
return nil
}
-
- return &block
+ return (*types.Block)(&block)
}
func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {