diff --git a/blockchain/reactor_test.go b/blockchain/reactor_test.go index a13c6aed8..492ea7a80 100644 --- a/blockchain/reactor_test.go +++ b/blockchain/reactor_test.go @@ -4,13 +4,15 @@ import ( "bytes" "testing" + wire "github.com/tendermint/go-wire" + cmn "github.com/tendermint/tmlibs/common" + "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" + cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/p2p" sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/db" - "github.com/tendermint/tmlibs/log" ) func newBlockchainReactor(logger log.Logger, maxBlockHeight int) *BlockchainReactor { @@ -23,7 +25,8 @@ func newBlockchainReactor(logger log.Logger, maxBlockHeight int) *BlockchainReac // Get State stateDB := db.NewDB("state", config.DBBackend, config.DBDir()) - state := sm.GetState(stateDB, config.GenesisFile()) + state, _ := sm.GetState(stateDB, config.GenesisFile()) + state.SetLogger(stateLogger) state.Save() @@ -39,21 +42,13 @@ func newBlockchainReactor(logger log.Logger, maxBlockHeight int) *BlockchainReac for blockHeight := 1; blockHeight <= maxBlockHeight; blockHeight++ { firstBlock := makeBlock(blockHeight, state) secondBlock := makeBlock(blockHeight+1, state) - firstParts := firstBlock.MakePartSet(types.DefaultBlockPartSize) + firstParts := firstBlock.MakePartSet(state.Params().BlockGossipParams.BlockPartSizeBytes) blockStore.SaveBlock(firstBlock, firstParts, secondBlock.LastCommit) } return bcReactor } -func newbcrTestPeer(key string) *bcrTestPeer { - return &bcrTestPeer{ - key: key, - kvm: make(map[byte]interface{}), - ch: make(chan *keyValue, 2), - } -} - func TestNoBlockMessageResponse(t *testing.T) { logBuf := new(bytes.Buffer) logger := log.NewTMLogger(logBuf) @@ -68,131 +63,78 @@ func TestNoBlockMessageResponse(t *testing.T) { bcr.AddPeer(peer) chID := byte(0x01) - - tests := [...]struct { + + tests := []struct { height int existent bool }{ - 0: { - height: maxBlockHeight + 2, - existent: false, - }, - 1: { - height: 10, - existent: true, // We should have this - }, - 2: { - height: 1, - existent: true, // We should have this - }, - 3: { - height: 100, - existent: false, - }, + {maxBlockHeight + 2, false}, + {10, true}, + {1, true}, + {100, false}, } - // Currently the repsonses take asynchronous paths so - // the results are skewed. However, we can ensure that - // the (expectedHeight, expectedExistence) all tally up. - heightTally := map[int]bool{} - var results []BlockchainMessage - - msgRequest := byte(0x10) for _, tt := range tests { - reqBlockBytes := []byte{msgRequest, 0x02, 0x00, byte(tt.height)} + reqBlockMsg := &bcBlockRequestMessage{tt.height} + reqBlockBytes := wire.BinaryBytes(struct{ BlockchainMessage }{reqBlockMsg}) bcr.Receive(chID, peer, reqBlockBytes) - heightTally[tt.height] = tt.existent - kv := peer.lastKeyValue() - results = append(results, kv.value.(struct{ BlockchainMessage }).BlockchainMessage) - } - - for i, res := range results { - if bcRM, ok := res.(*bcBlockResponseMessage); ok { - block := bcRM.Block - if block == nil { - t.Errorf("result: #%d: expecting a non-nil block", i) - continue - } - mustExist, foundHeight := heightTally[block.Height] - if !foundHeight { - t.Errorf("result: #%d, missing height %d", i, block.Height) - continue - } - if !mustExist { - t.Errorf("result: #%d mustExist", i) - } else { - delete(heightTally, block.Height) - } - } else if bcNBRSM, ok := res.(*bcNoBlockResponseMessage); ok { - mustExist, foundHeight := heightTally[bcNBRSM.Height] - if !foundHeight { - t.Errorf("result: #%d, missing height %d", i, bcNBRSM.Height) - continue - } - if mustExist { - t.Errorf("result: #%d mustNotExist", i) - } else { - // Passes, remove this height from the tally - delete(heightTally, bcNBRSM.Height) + value := peer.lastValue() + msg := value.(struct{ BlockchainMessage }).BlockchainMessage + + if tt.existent { + if blockMsg, ok := msg.(*bcBlockResponseMessage); !ok { + t.Fatalf("Expected to receive a block response for height %d", tt.height) + } else if blockMsg.Block.Height != tt.height { + t.Fatalf("Expected response to be for height %d, got %d", tt.height, blockMsg.Block.Height) } } else { - t.Errorf("result: #%d is an unexpected type: %T; data: %#v", i, res, res) + if noBlockMsg, ok := msg.(*bcNoBlockResponseMessage); !ok { + t.Fatalf("Expected to receive a no block response for height %d", tt.height) + } else if noBlockMsg.Height != tt.height { + t.Fatalf("Expected response to be for height %d, got %d", tt.height, noBlockMsg.Height) + } } } - - if len(heightTally) > 0 { - t.Errorf("Untallied heights: %#v\n", heightTally) - } } +//---------------------------------------------- +// utility funcs + func makeTxs(blockNumber int) (txs []types.Tx) { for i := 0; i < 10; i++ { - txs = append(txs, types.Tx([]byte{byte(blockNumber)})) + txs = append(txs, types.Tx([]byte{byte(blockNumber), byte(i)})) } return txs } -const testPartSize = 65536 - func makeBlock(blockNumber int, state *sm.State) *types.Block { prevHash := state.LastBlockID.Hash prevParts := types.PartSetHeader{} valHash := state.Validators.Hash() prevBlockID := types.BlockID{prevHash, prevParts} block, _ := types.MakeBlock(blockNumber, "test_chain", makeTxs(blockNumber), - new(types.Commit), prevBlockID, valHash, state.AppHash, testPartSize) + new(types.Commit), prevBlockID, valHash, state.AppHash, state.Params().BlockGossipParams.BlockPartSizeBytes) return block } // The Test peer type bcrTestPeer struct { + cmn.Service key string - ch chan *keyValue - kvm map[byte]interface{} -} - -type keyValue struct { - key interface{} - value interface{} + ch chan interface{} } var _ p2p.Peer = (*bcrTestPeer)(nil) -func (tp *bcrTestPeer) Key() string { return tp.key } -func (tp *bcrTestPeer) IsOutbound() bool { return false } -func (tp *bcrTestPeer) IsPersistent() bool { return true } -func (tp *bcrTestPeer) IsRunning() bool { return true } - -func (tp *bcrTestPeer) OnStop() {} - -func (tp *bcrTestPeer) OnReset() error { return nil } -func (tp *bcrTestPeer) Reset() (bool, error) { return false, nil } -func (tp *bcrTestPeer) OnStart() error { return nil } -func (tp *bcrTestPeer) SetLogger(l log.Logger) {} +func newbcrTestPeer(key string) *bcrTestPeer { + return &bcrTestPeer{ + Service: cmn.NewBaseService(nil, "bcrTestPeer", nil), + key: key, + ch: make(chan interface{}, 2), + } +} -func (tp *bcrTestPeer) Start() (bool, error) { return true, nil } -func (tp *bcrTestPeer) Stop() bool { return true } -func (tp *bcrTestPeer) String() string { return tp.key } +func (tp *bcrTestPeer) lastValue() interface{} { return <-tp.ch } func (tp *bcrTestPeer) TrySend(chID byte, value interface{}) bool { if _, ok := value.(struct{ BlockchainMessage }).BlockchainMessage.(*bcStatusResponseMessage); ok { @@ -201,18 +143,16 @@ func (tp *bcrTestPeer) TrySend(chID byte, value interface{}) bool { // + bcBlockResponseMessage // + bcNoBlockResponseMessage } else { - tp.ch <- &keyValue{key: chID, value: value} + tp.ch <- value } return true } -func (tp *bcrTestPeer) Send(chID byte, data interface{}) bool { - return tp.TrySend(chID, data) -} - -func (tp *bcrTestPeer) NodeInfo() *p2p.NodeInfo { return nil } -func (tp *bcrTestPeer) Status() p2p.ConnectionStatus { return p2p.ConnectionStatus{} } - -func (tp *bcrTestPeer) Get(s string) interface{} { return s } -func (tp *bcrTestPeer) Set(string, interface{}) {} -func (tp *bcrTestPeer) lastKeyValue() *keyValue { return <-tp.ch } +func (tp *bcrTestPeer) Send(chID byte, data interface{}) bool { return tp.TrySend(chID, data) } +func (tp *bcrTestPeer) NodeInfo() *p2p.NodeInfo { return nil } +func (tp *bcrTestPeer) Status() p2p.ConnectionStatus { return p2p.ConnectionStatus{} } +func (tp *bcrTestPeer) Key() string { return tp.key } +func (tp *bcrTestPeer) IsOutbound() bool { return false } +func (tp *bcrTestPeer) IsPersistent() bool { return true } +func (tp *bcrTestPeer) Get(s string) interface{} { return s } +func (tp *bcrTestPeer) Set(string, interface{}) {}