mirror of
https://github.com/tendermint/tendermint.git
synced 2026-01-07 13:55:17 +00:00
light: implement light block (#5298)
This commit is contained in:
@@ -6,7 +6,6 @@ import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
tmsync "github.com/tendermint/tendermint/libs/sync"
|
||||
@@ -40,30 +39,22 @@ func New(db dbm.DB, prefix string) store.Store {
|
||||
return &dbs{db: db, prefix: prefix, size: size}
|
||||
}
|
||||
|
||||
// SaveSignedHeaderAndValidatorSet persists SignedHeader and ValidatorSet to
|
||||
// the db.
|
||||
// SaveLightBlock persists LightBlock to the db.
|
||||
//
|
||||
// Safe for concurrent use by multiple goroutines.
|
||||
func (s *dbs) SaveSignedHeaderAndValidatorSet(sh *types.SignedHeader, valSet *types.ValidatorSet) error {
|
||||
if sh.Height <= 0 {
|
||||
func (s *dbs) SaveLightBlock(lb *types.LightBlock) error {
|
||||
if lb.Height <= 0 {
|
||||
panic("negative or zero height")
|
||||
}
|
||||
|
||||
pbsh := sh.ToProto()
|
||||
|
||||
shBz, err := proto.Marshal(pbsh)
|
||||
lbpb, err := lb.ToProto()
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshalling SignedHeader: %w", err)
|
||||
return fmt.Errorf("unable to convert light block to protobuf: %w", err)
|
||||
}
|
||||
|
||||
pbvs, err := valSet.ToProto()
|
||||
lbBz, err := lbpb.Marshal()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to transition validator set to protobuf: %w", err)
|
||||
}
|
||||
|
||||
valSetBz, err := proto.Marshal(pbvs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshalling validator set: %w", err)
|
||||
return fmt.Errorf("marshalling LightBlock: %w", err)
|
||||
}
|
||||
|
||||
s.mtx.Lock()
|
||||
@@ -71,10 +62,7 @@ func (s *dbs) SaveSignedHeaderAndValidatorSet(sh *types.SignedHeader, valSet *ty
|
||||
|
||||
b := s.db.NewBatch()
|
||||
defer b.Close()
|
||||
if err = b.Set(s.shKey(sh.Height), shBz); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = b.Set(s.vsKey(sh.Height), valSetBz); err != nil {
|
||||
if err = b.Set(s.lbKey(lb.Height), lbBz); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = b.Set(sizeKey, marshalSize(s.size+1)); err != nil {
|
||||
@@ -88,11 +76,11 @@ func (s *dbs) SaveSignedHeaderAndValidatorSet(sh *types.SignedHeader, valSet *ty
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteSignedHeaderAndValidatorSet deletes SignedHeader and ValidatorSet from
|
||||
// DeleteLightBlockAndValidatorSet deletes the LightBlock from
|
||||
// the db.
|
||||
//
|
||||
// Safe for concurrent use by multiple goroutines.
|
||||
func (s *dbs) DeleteSignedHeaderAndValidatorSet(height int64) error {
|
||||
func (s *dbs) DeleteLightBlock(height int64) error {
|
||||
if height <= 0 {
|
||||
panic("negative or zero height")
|
||||
}
|
||||
@@ -102,10 +90,7 @@ func (s *dbs) DeleteSignedHeaderAndValidatorSet(height int64) error {
|
||||
|
||||
b := s.db.NewBatch()
|
||||
defer b.Close()
|
||||
if err := b.Delete(s.shKey(height)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := b.Delete(s.vsKey(height)); err != nil {
|
||||
if err := b.Delete(s.lbKey(height)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := b.Set(sizeKey, marshalSize(s.size-1)); err != nil {
|
||||
@@ -119,73 +104,43 @@ func (s *dbs) DeleteSignedHeaderAndValidatorSet(height int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SignedHeader loads SignedHeader at the given height.
|
||||
// LightBlock retrieves the LightBlock at the given height.
|
||||
//
|
||||
// Safe for concurrent use by multiple goroutines.
|
||||
func (s *dbs) SignedHeader(height int64) (*types.SignedHeader, error) {
|
||||
func (s *dbs) LightBlock(height int64) (*types.LightBlock, error) {
|
||||
if height <= 0 {
|
||||
panic("negative or zero height")
|
||||
}
|
||||
|
||||
bz, err := s.db.Get(s.shKey(height))
|
||||
bz, err := s.db.Get(s.lbKey(height))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if len(bz) == 0 {
|
||||
return nil, store.ErrSignedHeaderNotFound
|
||||
return nil, store.ErrLightBlockNotFound
|
||||
}
|
||||
|
||||
var pbsh tmproto.SignedHeader
|
||||
err = proto.Unmarshal(bz, &pbsh)
|
||||
var lbpb tmproto.LightBlock
|
||||
err = lbpb.Unmarshal(bz)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("unmarshal error: %w", err)
|
||||
}
|
||||
|
||||
signedHeader, err := types.SignedHeaderFromProto(&pbsh)
|
||||
lightBlock, err := types.LightBlockFromProto(&lbpb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("proto conversion error: %w", err)
|
||||
}
|
||||
|
||||
return signedHeader, err
|
||||
return lightBlock, err
|
||||
}
|
||||
|
||||
// ValidatorSet loads ValidatorSet at the given height.
|
||||
// LastLightBlockHeight returns the last LightBlock height stored.
|
||||
//
|
||||
// Safe for concurrent use by multiple goroutines.
|
||||
func (s *dbs) ValidatorSet(height int64) (*types.ValidatorSet, error) {
|
||||
if height <= 0 {
|
||||
panic("negative or zero height")
|
||||
}
|
||||
|
||||
bz, err := s.db.Get(s.vsKey(height))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if len(bz) == 0 {
|
||||
return nil, store.ErrValidatorSetNotFound
|
||||
}
|
||||
|
||||
var pbvs tmproto.ValidatorSet
|
||||
err = proto.Unmarshal(bz, &pbvs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
valSet, err := types.ValidatorSetFromProto(&pbvs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return valSet, err
|
||||
}
|
||||
|
||||
// LastSignedHeaderHeight returns the last SignedHeader height stored.
|
||||
//
|
||||
// Safe for concurrent use by multiple goroutines.
|
||||
func (s *dbs) LastSignedHeaderHeight() (int64, error) {
|
||||
func (s *dbs) LastLightBlockHeight() (int64, error) {
|
||||
itr, err := s.db.ReverseIterator(
|
||||
s.shKey(1),
|
||||
append(s.shKey(1<<63-1), byte(0x00)),
|
||||
s.lbKey(1),
|
||||
append(s.lbKey(1<<63-1), byte(0x00)),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -194,7 +149,7 @@ func (s *dbs) LastSignedHeaderHeight() (int64, error) {
|
||||
|
||||
for itr.Valid() {
|
||||
key := itr.Key()
|
||||
_, height, ok := parseShKey(key)
|
||||
_, height, ok := parseLbKey(key)
|
||||
if ok {
|
||||
return height, nil
|
||||
}
|
||||
@@ -204,13 +159,13 @@ func (s *dbs) LastSignedHeaderHeight() (int64, error) {
|
||||
return -1, itr.Error()
|
||||
}
|
||||
|
||||
// FirstSignedHeaderHeight returns the first SignedHeader height stored.
|
||||
// FirstLightBlockHeight returns the first LightBlock height stored.
|
||||
//
|
||||
// Safe for concurrent use by multiple goroutines.
|
||||
func (s *dbs) FirstSignedHeaderHeight() (int64, error) {
|
||||
func (s *dbs) FirstLightBlockHeight() (int64, error) {
|
||||
itr, err := s.db.Iterator(
|
||||
s.shKey(1),
|
||||
append(s.shKey(1<<63-1), byte(0x00)),
|
||||
s.lbKey(1),
|
||||
append(s.lbKey(1<<63-1), byte(0x00)),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -219,7 +174,7 @@ func (s *dbs) FirstSignedHeaderHeight() (int64, error) {
|
||||
|
||||
for itr.Valid() {
|
||||
key := itr.Key()
|
||||
_, height, ok := parseShKey(key)
|
||||
_, height, ok := parseLbKey(key)
|
||||
if ok {
|
||||
return height, nil
|
||||
}
|
||||
@@ -229,18 +184,18 @@ func (s *dbs) FirstSignedHeaderHeight() (int64, error) {
|
||||
return -1, itr.Error()
|
||||
}
|
||||
|
||||
// SignedHeaderBefore iterates over headers until it finds a header before
|
||||
// the given height. It returns ErrSignedHeaderNotFound if no such header exists.
|
||||
// LightBlockBefore iterates over light blocks until it finds a block before
|
||||
// the given height. It returns ErrLightBlockNotFound if no such block exists.
|
||||
//
|
||||
// Safe for concurrent use by multiple goroutines.
|
||||
func (s *dbs) SignedHeaderBefore(height int64) (*types.SignedHeader, error) {
|
||||
func (s *dbs) LightBlockBefore(height int64) (*types.LightBlock, error) {
|
||||
if height <= 0 {
|
||||
panic("negative or zero height")
|
||||
}
|
||||
|
||||
itr, err := s.db.ReverseIterator(
|
||||
s.shKey(1),
|
||||
s.shKey(height),
|
||||
s.lbKey(1),
|
||||
s.lbKey(height),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -249,9 +204,9 @@ func (s *dbs) SignedHeaderBefore(height int64) (*types.SignedHeader, error) {
|
||||
|
||||
for itr.Valid() {
|
||||
key := itr.Key()
|
||||
_, existingHeight, ok := parseShKey(key)
|
||||
_, existingHeight, ok := parseLbKey(key)
|
||||
if ok {
|
||||
return s.SignedHeader(existingHeight)
|
||||
return s.LightBlock(existingHeight)
|
||||
}
|
||||
itr.Next()
|
||||
}
|
||||
@@ -259,7 +214,7 @@ func (s *dbs) SignedHeaderBefore(height int64) (*types.SignedHeader, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, store.ErrSignedHeaderNotFound
|
||||
return nil, store.ErrLightBlockNotFound
|
||||
}
|
||||
|
||||
// Prune prunes header & validator set pairs until there are only size pairs
|
||||
@@ -279,8 +234,8 @@ func (s *dbs) Prune(size uint16) error {
|
||||
|
||||
// 2) Iterate over headers and perform a batch operation.
|
||||
itr, err := s.db.Iterator(
|
||||
s.shKey(1),
|
||||
append(s.shKey(1<<63-1), byte(0x00)),
|
||||
s.lbKey(1),
|
||||
append(s.lbKey(1<<63-1), byte(0x00)),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -293,12 +248,9 @@ func (s *dbs) Prune(size uint16) error {
|
||||
pruned := 0
|
||||
for itr.Valid() && numToPrune > 0 {
|
||||
key := itr.Key()
|
||||
_, height, ok := parseShKey(key)
|
||||
_, height, ok := parseLbKey(key)
|
||||
if ok {
|
||||
if err = b.Delete(s.shKey(height)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = b.Delete(s.vsKey(height)); err != nil {
|
||||
if err = b.Delete(s.lbKey(height)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -337,15 +289,11 @@ func (s *dbs) Size() uint16 {
|
||||
return s.size
|
||||
}
|
||||
|
||||
func (s *dbs) shKey(height int64) []byte {
|
||||
return []byte(fmt.Sprintf("sh/%s/%020d", s.prefix, height))
|
||||
func (s *dbs) lbKey(height int64) []byte {
|
||||
return []byte(fmt.Sprintf("lb/%s/%020d", s.prefix, height))
|
||||
}
|
||||
|
||||
func (s *dbs) vsKey(height int64) []byte {
|
||||
return []byte(fmt.Sprintf("vs/%s/%020d", s.prefix, height))
|
||||
}
|
||||
|
||||
var keyPattern = regexp.MustCompile(`^(sh|vs)/([^/]*)/([0-9]+)$`)
|
||||
var keyPattern = regexp.MustCompile(`^(lb)/([^/]*)/([0-9]+)$`)
|
||||
|
||||
func parseKey(key []byte) (part string, prefix string, height int64, ok bool) {
|
||||
submatch := keyPattern.FindSubmatch(key)
|
||||
@@ -362,10 +310,10 @@ func parseKey(key []byte) (part string, prefix string, height int64, ok bool) {
|
||||
return
|
||||
}
|
||||
|
||||
func parseShKey(key []byte) (prefix string, height int64, ok bool) {
|
||||
func parseLbKey(key []byte) (prefix string, height int64, ok bool) {
|
||||
var part string
|
||||
part, prefix, height, ok = parseKey(key)
|
||||
if part != "sh" {
|
||||
if part != "lb" {
|
||||
return "", 0, false
|
||||
}
|
||||
return
|
||||
|
||||
@@ -3,6 +3,7 @@ package db
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -10,91 +11,78 @@ import (
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/tmhash"
|
||||
tmrand "github.com/tendermint/tendermint/libs/rand"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
func TestLast_FirstSignedHeaderHeight(t *testing.T) {
|
||||
dbStore := New(dbm.NewMemDB(), "TestLast_FirstSignedHeaderHeight")
|
||||
vals, _ := types.RandValidatorSet(10, 100)
|
||||
func TestLast_FirstLightBlockHeight(t *testing.T) {
|
||||
dbStore := New(dbm.NewMemDB(), "TestLast_FirstLightBlockHeight")
|
||||
|
||||
// Empty store
|
||||
height, err := dbStore.LastSignedHeaderHeight()
|
||||
height, err := dbStore.LastLightBlockHeight()
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, -1, height)
|
||||
|
||||
height, err = dbStore.FirstSignedHeaderHeight()
|
||||
height, err = dbStore.FirstLightBlockHeight()
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, -1, height)
|
||||
|
||||
// 1 key
|
||||
err = dbStore.SaveSignedHeaderAndValidatorSet(
|
||||
&types.SignedHeader{Header: &types.Header{Height: 1}}, vals)
|
||||
err = dbStore.SaveLightBlock(randLightBlock(int64(1)))
|
||||
require.NoError(t, err)
|
||||
|
||||
height, err = dbStore.LastSignedHeaderHeight()
|
||||
height, err = dbStore.LastLightBlockHeight()
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, 1, height)
|
||||
|
||||
height, err = dbStore.FirstSignedHeaderHeight()
|
||||
height, err = dbStore.FirstLightBlockHeight()
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, 1, height)
|
||||
}
|
||||
|
||||
func Test_SaveSignedHeaderAndValidatorSet(t *testing.T) {
|
||||
dbStore := New(dbm.NewMemDB(), "Test_SaveSignedHeaderAndValidatorSet")
|
||||
vals, _ := types.RandValidatorSet(10, 100)
|
||||
func Test_SaveLightBlock(t *testing.T) {
|
||||
dbStore := New(dbm.NewMemDB(), "Test_SaveLightBlockAndValidatorSet")
|
||||
|
||||
// Empty store
|
||||
h, err := dbStore.SignedHeader(1)
|
||||
h, err := dbStore.LightBlock(1)
|
||||
require.Error(t, err)
|
||||
assert.Nil(t, h)
|
||||
|
||||
valSet, err := dbStore.ValidatorSet(1)
|
||||
require.Error(t, err)
|
||||
assert.Nil(t, valSet)
|
||||
|
||||
// 1 key
|
||||
pa := vals.Validators[0].Address
|
||||
err = dbStore.SaveSignedHeaderAndValidatorSet(
|
||||
&types.SignedHeader{Header: &types.Header{Height: 1, ProposerAddress: pa}}, vals)
|
||||
err = dbStore.SaveLightBlock(randLightBlock(1))
|
||||
require.NoError(t, err)
|
||||
|
||||
h, err = dbStore.SignedHeader(1)
|
||||
size := dbStore.Size()
|
||||
assert.Equal(t, uint16(1), size)
|
||||
t.Log(size)
|
||||
|
||||
h, err = dbStore.LightBlock(1)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, h)
|
||||
|
||||
valSet, err = dbStore.ValidatorSet(1)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, valSet)
|
||||
|
||||
// Empty store
|
||||
err = dbStore.DeleteSignedHeaderAndValidatorSet(1)
|
||||
err = dbStore.DeleteLightBlock(1)
|
||||
require.NoError(t, err)
|
||||
|
||||
h, err = dbStore.SignedHeader(1)
|
||||
h, err = dbStore.LightBlock(1)
|
||||
require.Error(t, err)
|
||||
assert.Nil(t, h)
|
||||
|
||||
valSet, err = dbStore.ValidatorSet(1)
|
||||
require.Error(t, err)
|
||||
assert.Nil(t, valSet)
|
||||
}
|
||||
|
||||
func Test_SignedHeaderBefore(t *testing.T) {
|
||||
dbStore := New(dbm.NewMemDB(), "Test_SignedHeaderBefore")
|
||||
valSet, _ := types.RandValidatorSet(10, 100)
|
||||
pa := valSet.Proposer.Address
|
||||
func Test_LightBlockBefore(t *testing.T) {
|
||||
dbStore := New(dbm.NewMemDB(), "Test_LightBlockBefore")
|
||||
|
||||
assert.Panics(t, func() {
|
||||
_, _ = dbStore.SignedHeaderBefore(0)
|
||||
_, _ = dbStore.SignedHeaderBefore(100)
|
||||
_, _ = dbStore.LightBlockBefore(0)
|
||||
_, _ = dbStore.LightBlockBefore(100)
|
||||
})
|
||||
|
||||
err := dbStore.SaveSignedHeaderAndValidatorSet(
|
||||
&types.SignedHeader{Header: &types.Header{Height: 2, ProposerAddress: pa}}, valSet)
|
||||
err := dbStore.SaveLightBlock(randLightBlock(int64(2)))
|
||||
require.NoError(t, err)
|
||||
|
||||
h, err := dbStore.SignedHeaderBefore(3)
|
||||
h, err := dbStore.LightBlockBefore(3)
|
||||
require.NoError(t, err)
|
||||
if assert.NotNil(t, h) {
|
||||
assert.EqualValues(t, 2, h.Height)
|
||||
@@ -103,7 +91,6 @@ func Test_SignedHeaderBefore(t *testing.T) {
|
||||
|
||||
func Test_Prune(t *testing.T) {
|
||||
dbStore := New(dbm.NewMemDB(), "Test_Prune")
|
||||
valSet, _ := types.RandValidatorSet(10, 100)
|
||||
|
||||
// Empty store
|
||||
assert.EqualValues(t, 0, dbStore.Size())
|
||||
@@ -111,8 +98,7 @@ func Test_Prune(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// One header
|
||||
err = dbStore.SaveSignedHeaderAndValidatorSet(
|
||||
&types.SignedHeader{Header: &types.Header{Height: 2}}, valSet)
|
||||
err = dbStore.SaveLightBlock(randLightBlock(2))
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.EqualValues(t, 1, dbStore.Size())
|
||||
@@ -127,8 +113,7 @@ func Test_Prune(t *testing.T) {
|
||||
|
||||
// Multiple headers
|
||||
for i := 1; i <= 10; i++ {
|
||||
err = dbStore.SaveSignedHeaderAndValidatorSet(
|
||||
&types.SignedHeader{Header: &types.Header{Height: int64(i)}}, valSet)
|
||||
err = dbStore.SaveLightBlock(randLightBlock(int64(i)))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -143,7 +128,6 @@ func Test_Prune(t *testing.T) {
|
||||
|
||||
func Test_Concurrency(t *testing.T) {
|
||||
dbStore := New(dbm.NewMemDB(), "Test_Prune")
|
||||
vals, _ := types.RandValidatorSet(10, 100)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for i := 1; i <= 100; i++ {
|
||||
@@ -151,24 +135,19 @@ func Test_Concurrency(t *testing.T) {
|
||||
go func(i int64) {
|
||||
defer wg.Done()
|
||||
|
||||
err := dbStore.SaveSignedHeaderAndValidatorSet(
|
||||
&types.SignedHeader{Header: &types.Header{Height: i,
|
||||
ProposerAddress: tmrand.Bytes(crypto.AddressSize)}}, vals)
|
||||
err := dbStore.SaveLightBlock(randLightBlock(i))
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = dbStore.SignedHeader(i)
|
||||
_, err = dbStore.LightBlock(i)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
_, err = dbStore.ValidatorSet(i)
|
||||
if err != nil {
|
||||
t.Log(err) // could not find validator set
|
||||
}
|
||||
_, err = dbStore.LastSignedHeaderHeight()
|
||||
|
||||
_, err = dbStore.LastLightBlockHeight()
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
_, err = dbStore.FirstSignedHeaderHeight()
|
||||
_, err = dbStore.FirstLightBlockHeight()
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
@@ -179,7 +158,7 @@ func Test_Concurrency(t *testing.T) {
|
||||
}
|
||||
_ = dbStore.Size()
|
||||
|
||||
err = dbStore.DeleteSignedHeaderAndValidatorSet(1)
|
||||
err = dbStore.DeleteLightBlock(1)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
@@ -188,3 +167,28 @@ func Test_Concurrency(t *testing.T) {
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func randLightBlock(height int64) *types.LightBlock {
|
||||
vals, _ := types.RandValidatorSet(2, 1)
|
||||
return &types.LightBlock{
|
||||
SignedHeader: &types.SignedHeader{
|
||||
Header: &types.Header{
|
||||
ChainID: tmrand.Str(12),
|
||||
Height: height,
|
||||
Time: time.Now(),
|
||||
LastBlockID: types.BlockID{},
|
||||
LastCommitHash: crypto.CRandBytes(tmhash.Size),
|
||||
DataHash: crypto.CRandBytes(tmhash.Size),
|
||||
ValidatorsHash: crypto.CRandBytes(tmhash.Size),
|
||||
NextValidatorsHash: crypto.CRandBytes(tmhash.Size),
|
||||
ConsensusHash: crypto.CRandBytes(tmhash.Size),
|
||||
AppHash: crypto.CRandBytes(tmhash.Size),
|
||||
LastResultsHash: crypto.CRandBytes(tmhash.Size),
|
||||
EvidenceHash: crypto.CRandBytes(tmhash.Size),
|
||||
ProposerAddress: crypto.CRandBytes(crypto.AddressSize),
|
||||
},
|
||||
Commit: &types.Commit{},
|
||||
},
|
||||
ValidatorSet: vals,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,7 @@ package store
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
// ErrSignedHeaderNotFound is returned when a store does not have the
|
||||
// ErrLightBlockNotFound is returned when a store does not have the
|
||||
// requested header.
|
||||
ErrSignedHeaderNotFound = errors.New("signed header not found")
|
||||
|
||||
// ErrValidatorSetNotFound is returned when a store does not have the
|
||||
// requested validator set.
|
||||
ErrValidatorSetNotFound = errors.New("validator set not found")
|
||||
ErrLightBlockNotFound = errors.New("light block not found")
|
||||
)
|
||||
|
||||
@@ -8,43 +8,36 @@ type Store interface {
|
||||
// ValidatorSet (h: sh.Height).
|
||||
//
|
||||
// height must be > 0.
|
||||
SaveSignedHeaderAndValidatorSet(sh *types.SignedHeader, valSet *types.ValidatorSet) error
|
||||
SaveLightBlock(lb *types.LightBlock) error
|
||||
|
||||
// DeleteSignedHeaderAndValidatorSet deletes SignedHeader (h: height) and
|
||||
// ValidatorSet (h: height).
|
||||
//
|
||||
// height must be > 0.
|
||||
DeleteSignedHeaderAndValidatorSet(height int64) error
|
||||
DeleteLightBlock(height int64) error
|
||||
|
||||
// SignedHeader returns the SignedHeader that corresponds to the given
|
||||
// LightBlock returns the LightBlock that corresponds to the given
|
||||
// height.
|
||||
//
|
||||
// height must be > 0.
|
||||
//
|
||||
// If SignedHeader is not found, ErrSignedHeaderNotFound is returned.
|
||||
SignedHeader(height int64) (*types.SignedHeader, error)
|
||||
// If LightBlock is not found, ErrLightBlockNotFound is returned.
|
||||
LightBlock(height int64) (*types.LightBlock, error)
|
||||
|
||||
// ValidatorSet returns the ValidatorSet that corresponds to height.
|
||||
//
|
||||
// height must be > 0.
|
||||
//
|
||||
// If ValidatorSet is not found, ErrValidatorSetNotFound is returned.
|
||||
ValidatorSet(height int64) (*types.ValidatorSet, error)
|
||||
|
||||
// LastSignedHeaderHeight returns the last (newest) SignedHeader height.
|
||||
// LastLightBlockHeight returns the last (newest) LightBlock height.
|
||||
//
|
||||
// If the store is empty, -1 and nil error are returned.
|
||||
LastSignedHeaderHeight() (int64, error)
|
||||
LastLightBlockHeight() (int64, error)
|
||||
|
||||
// FirstSignedHeaderHeight returns the first (oldest) SignedHeader height.
|
||||
// FirstLightBlockHeight returns the first (oldest) LightBlock height.
|
||||
//
|
||||
// If the store is empty, -1 and nil error are returned.
|
||||
FirstSignedHeaderHeight() (int64, error)
|
||||
FirstLightBlockHeight() (int64, error)
|
||||
|
||||
// SignedHeaderBefore returns the SignedHeader before a certain height.
|
||||
// LightBlockBefore returns the LightBlock before a certain height.
|
||||
//
|
||||
// height must be > 0 && <= LastSignedHeaderHeight.
|
||||
SignedHeaderBefore(height int64) (*types.SignedHeader, error)
|
||||
// height must be > 0 && <= LastLightBlockHeight.
|
||||
LightBlockBefore(height int64) (*types.LightBlock, error)
|
||||
|
||||
// Prune removes headers & the associated validator sets when Store reaches a
|
||||
// defined size (number of header & validator set pairs).
|
||||
|
||||
Reference in New Issue
Block a user