consensus: fix makeBlockchainFromWAL
This commit is contained in:
parent
5ecae52bf1
commit
e0296d6c3c
|
@ -44,13 +44,6 @@ func init() {
|
|||
// the `Handshake Tests` are for failures in applying the block.
|
||||
// With the help of the WAL, we can recover from it all!
|
||||
|
||||
// NOTE: Files in this dir are generated by running the `build.sh` therein.
|
||||
// It's a simple way to generate wals for a single block, or multiple blocks, with random transactions,
|
||||
// and different part sizes. The output is not deterministic.
|
||||
// It should only have to be re-run if there is some breaking change to the consensus data structures (eg. blocks, votes)
|
||||
// or to the behaviour of the app (eg. computes app hash differently)
|
||||
var data_dir = path.Join(cmn.GoPath(), "src/github.com/tendermint/tendermint/consensus", "test_data")
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// WAL Tests
|
||||
|
||||
|
@ -496,10 +489,13 @@ func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) {
|
|||
|
||||
// log.Notice("Build a blockchain by reading from the WAL")
|
||||
|
||||
var blockParts *types.PartSet
|
||||
var blocks []*types.Block
|
||||
var commits []*types.Commit
|
||||
|
||||
var thisBlockParts *types.PartSet
|
||||
var thisBlockCommit *types.Commit
|
||||
var height int64
|
||||
|
||||
dec := NewWALDecoder(gr)
|
||||
for {
|
||||
msg, err := dec.Decode()
|
||||
|
@ -515,42 +511,60 @@ func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) {
|
|||
}
|
||||
|
||||
switch p := piece.(type) {
|
||||
case *types.PartSetHeader:
|
||||
case EndHeightMessage:
|
||||
// if its not the first one, we have a full block
|
||||
if blockParts != nil {
|
||||
if thisBlockParts != nil {
|
||||
var n int
|
||||
block := wire.ReadBinary(&types.Block{}, blockParts.GetReader(), 0, &n, &err).(*types.Block)
|
||||
block := wire.ReadBinary(&types.Block{}, thisBlockParts.GetReader(), 0, &n, &err).(*types.Block)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if block.Height != height+1 {
|
||||
panic(cmn.Fmt("read bad block from wal. got height %d, expected %d", block.Height, height+1))
|
||||
}
|
||||
commitHeight := thisBlockCommit.Precommits[0].Height
|
||||
if commitHeight != height+1 {
|
||||
panic(cmn.Fmt("commit doesnt match. got height %d, expected %d", commitHeight, height+1))
|
||||
}
|
||||
blocks = append(blocks, block)
|
||||
commits = append(commits, thisBlockCommit)
|
||||
height += 1
|
||||
}
|
||||
blockParts = types.NewPartSetFromHeader(*p)
|
||||
case *types.PartSetHeader:
|
||||
thisBlockParts = types.NewPartSetFromHeader(*p)
|
||||
case *types.Part:
|
||||
_, err := blockParts.AddPart(p, false)
|
||||
_, err := thisBlockParts.AddPart(p, false)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
case *types.Vote:
|
||||
if p.Type == types.VoteTypePrecommit {
|
||||
commit := &types.Commit{
|
||||
thisBlockCommit = &types.Commit{
|
||||
BlockID: p.BlockID,
|
||||
Precommits: []*types.Vote{p},
|
||||
}
|
||||
commits = append(commits, commit)
|
||||
}
|
||||
}
|
||||
}
|
||||
// grab the last block too
|
||||
var n int
|
||||
block := wire.ReadBinary(&types.Block{}, blockParts.GetReader(), 0, &n, &err).(*types.Block)
|
||||
block := wire.ReadBinary(&types.Block{}, thisBlockParts.GetReader(), 0, &n, &err).(*types.Block)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if block.Height != height+1 {
|
||||
panic(cmn.Fmt("read bad block from wal. got height %d, expected %d", block.Height, height+1))
|
||||
}
|
||||
commitHeight := thisBlockCommit.Precommits[0].Height
|
||||
if commitHeight != height+1 {
|
||||
panic(cmn.Fmt("commit doesnt match. got height %d, expected %d", commitHeight, height+1))
|
||||
}
|
||||
blocks = append(blocks, block)
|
||||
commits = append(commits, thisBlockCommit)
|
||||
return blocks, commits, nil
|
||||
}
|
||||
|
||||
func readPieceFromWAL(msg *TimedWALMessage) interface{} {
|
||||
// skip meta messages
|
||||
if _, ok := msg.Msg.(EndHeightMessage); ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
// for logging
|
||||
switch m := msg.Msg.(type) {
|
||||
case msgInfo:
|
||||
|
@ -562,6 +576,8 @@ func readPieceFromWAL(msg *TimedWALMessage) interface{} {
|
|||
case *VoteMessage:
|
||||
return msg.Vote
|
||||
}
|
||||
case EndHeightMessage:
|
||||
return m
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -77,7 +77,7 @@ func WALWithNBlocks(numBlocks int) (data []byte, err error) {
|
|||
var b bytes.Buffer
|
||||
wr := bufio.NewWriter(&b)
|
||||
numBlocksWritten := make(chan struct{})
|
||||
wal := &byteBufferWAL{enc: NewWALEncoder(wr), heightToStop: int64(numBlocks), signalWhenStopsTo: numBlocksWritten}
|
||||
wal := newByteBufferWAL(NewWALEncoder(wr), int64(numBlocks), numBlocksWritten)
|
||||
// see wal.go#103
|
||||
wal.Save(EndHeightMessage{0})
|
||||
consensusState.wal = wal
|
||||
|
@ -147,6 +147,14 @@ type byteBufferWAL struct {
|
|||
// needed for determinism
|
||||
var fixedTime, _ = time.Parse(time.RFC3339, "2017-01-02T15:04:05Z")
|
||||
|
||||
func newByteBufferWAL(enc *WALEncoder, nBlocks int64, signalStop chan struct{}) *byteBufferWAL {
|
||||
return &byteBufferWAL{
|
||||
enc: enc,
|
||||
heightToStop: nBlocks,
|
||||
signalWhenStopsTo: signalStop,
|
||||
}
|
||||
}
|
||||
|
||||
// Save writes message to the internal buffer except when heightToStop is
|
||||
// reached, in which case it will signal the caller via signalWhenStopsTo and
|
||||
// skip writing.
|
||||
|
|
Loading…
Reference in New Issue