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.
This commit is contained in:
parent
c298148a7f
commit
b5b83db450
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user