|
|
@ -5,10 +5,9 @@ import ( |
|
|
|
"encoding/binary" |
|
|
|
"encoding/json" |
|
|
|
|
|
|
|
"github.com/syndtr/goleveldb/leveldb" |
|
|
|
"github.com/syndtr/goleveldb/leveldb/opt" |
|
|
|
. "github.com/tendermint/tendermint/binary" |
|
|
|
. "github.com/tendermint/tendermint/common" |
|
|
|
db_ "github.com/tendermint/tendermint/db" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
@ -21,26 +20,23 @@ type BlockStoreJSON struct { |
|
|
|
Height uint32 |
|
|
|
} |
|
|
|
|
|
|
|
func (bsj BlockStoreJSON) Save(db *leveldb.DB) { |
|
|
|
func (bsj BlockStoreJSON) Save(db db_.DB) { |
|
|
|
bytes, err := json.Marshal(bsj) |
|
|
|
if err != nil { |
|
|
|
Panicf("Could not marshal state bytes: %v", err) |
|
|
|
} |
|
|
|
db.Put(blockStoreKey, bytes, nil) |
|
|
|
db.Set(blockStoreKey, bytes) |
|
|
|
} |
|
|
|
|
|
|
|
func LoadBlockStoreJSON(db *leveldb.DB) BlockStoreJSON { |
|
|
|
bytes, err := db.Get(blockStoreKey, nil) |
|
|
|
if err != nil { |
|
|
|
Panicf("Could not load BlockStoreJSON from db: %v", err) |
|
|
|
} |
|
|
|
func LoadBlockStoreJSON(db db_.DB) BlockStoreJSON { |
|
|
|
bytes := db.Get(blockStoreKey) |
|
|
|
if bytes == nil { |
|
|
|
return BlockStoreJSON{ |
|
|
|
Height: 0, |
|
|
|
} |
|
|
|
} |
|
|
|
bsj := BlockStoreJSON{} |
|
|
|
err = json.Unmarshal(bytes, &bsj) |
|
|
|
err := json.Unmarshal(bytes, &bsj) |
|
|
|
if err != nil { |
|
|
|
Panicf("Could not unmarshal bytes: %X", bytes) |
|
|
|
} |
|
|
@ -54,10 +50,10 @@ Simple low level store for blocks, which is actually stored as separte parts (wi |
|
|
|
*/ |
|
|
|
type BlockStore struct { |
|
|
|
height uint32 |
|
|
|
db *leveldb.DB |
|
|
|
db db_.DB |
|
|
|
} |
|
|
|
|
|
|
|
func NewBlockStore(db *leveldb.DB) *BlockStore { |
|
|
|
func NewBlockStore(db db_.DB) *BlockStore { |
|
|
|
bsjson := LoadBlockStoreJSON(db) |
|
|
|
return &BlockStore{ |
|
|
|
height: bsjson.Height, |
|
|
@ -71,29 +67,30 @@ func (bs *BlockStore) Height() uint32 { |
|
|
|
} |
|
|
|
|
|
|
|
func (bs *BlockStore) LoadBlock(height uint32) *Block { |
|
|
|
blockBytes, err := bs.db.Get(calcBlockKey(height), nil) |
|
|
|
if err != nil { |
|
|
|
Panicf("Could not load block: %v", err) |
|
|
|
} |
|
|
|
blockBytes := bs.db.Get(calcBlockKey(height)) |
|
|
|
if blockBytes == nil { |
|
|
|
return nil |
|
|
|
} |
|
|
|
var n int64 |
|
|
|
return ReadBlock(bytes.NewReader(blockBytes), &n, &err) |
|
|
|
var err error |
|
|
|
block := ReadBlock(bytes.NewReader(blockBytes), &n, &err) |
|
|
|
if err != nil { |
|
|
|
Panicf("Error reading block: %v", err) |
|
|
|
} |
|
|
|
return block |
|
|
|
} |
|
|
|
|
|
|
|
// Writes are synchronous and atomic.
|
|
|
|
func (bs *BlockStore) SaveBlock(block *Block) error { |
|
|
|
func (bs *BlockStore) SaveBlock(block *Block) { |
|
|
|
height := block.Height |
|
|
|
if height != bs.height+1 { |
|
|
|
return Errorf("BlockStore can only save contiguous blocks. Wanted %v, got %v", bs.height+1, height) |
|
|
|
Panicf("BlockStore can only save contiguous blocks. Wanted %v, got %v", bs.height+1, height) |
|
|
|
} |
|
|
|
// Save block
|
|
|
|
blockBytes := BinaryBytes(block) |
|
|
|
err := bs.db.Put(calcBlockKey(height), blockBytes, &opt.WriteOptions{Sync: true}) |
|
|
|
bs.db.Set(calcBlockKey(height), blockBytes) |
|
|
|
// Save new BlockStoreJSON descriptor
|
|
|
|
BlockStoreJSON{Height: height}.Save(bs.db) |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|