tendermint/blockchain/pool_test.go

649 lines
20 KiB
Go
Raw Normal View History

package blockchain
2015-03-22 12:46:53 -07:00
import (
"testing"
2015-03-22 19:20:54 -07:00
"time"
2015-03-22 12:46:53 -07:00
"github.com/stretchr/testify/assert"
2018-07-01 22:36:49 -04:00
"github.com/tendermint/tendermint/libs/log"
2018-01-03 11:29:19 +01:00
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/types"
2015-03-22 12:46:53 -07:00
)
2019-04-13 09:23:43 -04:00
type testPeer struct {
id p2p.ID
height int64
}
2019-04-13 09:23:43 -04:00
type testBcR struct {
logger log.Logger
}
2019-04-13 09:23:43 -04:00
type testValues struct {
numRequestsSent int
}
2019-04-13 09:23:43 -04:00
var testResults testValues
func resetPoolTestResults() {
testResults.numRequestsSent = 0
}
2019-04-13 09:23:43 -04:00
func (testR *testBcR) sendPeerError(err error, peerID p2p.ID) {
}
2019-04-13 09:23:43 -04:00
func (testR *testBcR) sendStatusRequest() {
}
2019-04-13 09:23:43 -04:00
func (testR *testBcR) sendBlockRequest(peerID p2p.ID, height int64) error {
testResults.numRequestsSent++
return nil
}
2019-04-14 22:53:24 -04:00
func (testR *testBcR) resetStateTimer(name string, timer **time.Timer, timeout time.Duration) {
2019-04-13 09:23:43 -04:00
}
func (testR *testBcR) switchToConsensus() {
}
2019-04-13 09:23:43 -04:00
func newTestBcR() *testBcR {
testBcR := &testBcR{logger: log.TestingLogger()}
return testBcR
}
type tPBlocks struct {
id p2p.ID
create bool
}
// Makes a block pool with specified current height, list of peers, block requests and block responses
2019-04-13 09:23:43 -04:00
func makeBlockPool(bcr *testBcR, height int64, peers []bpPeer, blocks map[int64]tPBlocks) *blockPool {
2019-06-02 19:03:51 +02:00
bPool := NewBlockPool(height, bcr)
bPool.SetLogger(bcr.logger)
2019-04-13 09:23:43 -04:00
txs := []types.Tx{types.Tx("foo"), types.Tx("bar")}
var maxH int64
for _, p := range peers {
if p.Height > maxH {
maxH = p.Height
2019-04-13 09:23:43 -04:00
}
bPool.peers[p.ID] = NewBPPeer(p.ID, p.Height, bcr.sendPeerError, nil)
bPool.peers[p.ID].SetLogger(bcr.logger)
2019-04-13 09:23:43 -04:00
2015-03-22 12:46:53 -07:00
}
bPool.MaxPeerHeight = maxH
2019-04-13 09:23:43 -04:00
for h, p := range blocks {
bPool.blocks[h] = p.id
bPool.peers[p.id].RequestSent(int64(h))
2019-04-13 09:23:43 -04:00
if p.create {
// simulate that a block at height h has been received
2019-06-06 18:13:59 +02:00
_ = bPool.peers[p.id].AddBlock(types.MakeBlock(int64(h), txs, nil, nil), 100)
2019-04-13 09:23:43 -04:00
}
}
return bPool
2015-03-22 12:46:53 -07:00
}
func assertPeerSetsEquivalent(t *testing.T, set1 map[p2p.ID]*bpPeer, set2 map[p2p.ID]*bpPeer) {
assert.Equal(t, len(set1), len(set2))
for peerID, peer1 := range set1 {
peer2 := set2[peerID]
assert.NotNil(t, peer2)
assert.Equal(t, peer1.NumPendingBlockRequests, peer2.NumPendingBlockRequests)
assert.Equal(t, peer1.Height, peer2.Height)
assert.Equal(t, len(peer1.blocks), len(peer2.blocks))
for h, block1 := range peer1.blocks {
block2 := peer2.blocks[h]
// block1 and block2 could be nil if a request was made but no block was received
assert.Equal(t, block1, block2)
}
2019-04-13 09:23:43 -04:00
}
}
2017-09-06 11:50:43 -04:00
func assertBlockPoolEquivalent(t *testing.T, poolWanted, pool *blockPool) {
assert.Equal(t, poolWanted.blocks, pool.blocks)
assertPeerSetsEquivalent(t, poolWanted.peers, pool.peers)
assert.Equal(t, poolWanted.MaxPeerHeight, pool.MaxPeerHeight)
assert.Equal(t, poolWanted.Height, pool.Height)
2019-04-13 09:23:43 -04:00
}
2017-09-06 11:50:43 -04:00
func TestBlockPoolUpdatePeer(t *testing.T) {
2019-04-13 09:23:43 -04:00
testBcR := newTestBcR()
tests := []struct {
name string
pool *blockPool
args testPeer
poolWanted *blockPool
errWanted error
2019-04-13 09:23:43 -04:00
}{
{
name: "add a first short peer",
pool: makeBlockPool(testBcR, 100, []bpPeer{}, map[int64]tPBlocks{}),
args: testPeer{"P1", 50},
errWanted: errPeerTooShort,
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{}, map[int64]tPBlocks{}),
},
{
name: "add a first good peer",
pool: makeBlockPool(testBcR, 100, []bpPeer{}, map[int64]tPBlocks{}),
args: testPeer{"P1", 101},
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 101}}, map[int64]tPBlocks{}),
2019-04-13 09:23:43 -04:00
},
{
name: "increase the height of P1 from 120 to 123",
pool: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 120}}, map[int64]tPBlocks{}),
args: testPeer{"P1", 123},
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 123}}, map[int64]tPBlocks{}),
2019-04-13 09:23:43 -04:00
},
{
name: "decrease the height of P1 from 120 to 110",
pool: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 120}}, map[int64]tPBlocks{}),
args: testPeer{"P1", 110},
errWanted: errPeerLowersItsHeight,
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{}, map[int64]tPBlocks{}),
2019-04-13 09:23:43 -04:00
},
{
name: "decrease the height of P1 from 105 to 102 with blocks",
pool: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 105}},
map[int64]tPBlocks{
100: {"P1", true}, 101: {"P1", true}, 102: {"P1", true}}),
args: testPeer{"P1", 102},
errWanted: errPeerLowersItsHeight,
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{},
map[int64]tPBlocks{}),
2019-04-13 09:23:43 -04:00
},
}
2015-03-22 12:46:53 -07:00
2019-04-13 09:23:43 -04:00
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
pool := tt.pool
2019-06-02 19:03:51 +02:00
err := pool.UpdatePeer(tt.args.id, tt.args.height)
assert.Equal(t, tt.errWanted, err)
assert.Equal(t, tt.poolWanted.blocks, tt.pool.blocks)
assertPeerSetsEquivalent(t, tt.poolWanted.peers, tt.pool.peers)
assert.Equal(t, tt.poolWanted.MaxPeerHeight, tt.pool.MaxPeerHeight)
2019-04-13 09:23:43 -04:00
})
2015-03-22 12:46:53 -07:00
}
2015-03-22 16:23:24 -07:00
}
func TestBlockPoolRemovePeer(t *testing.T) {
2019-04-13 09:23:43 -04:00
testBcR := newTestBcR()
type args struct {
peerID p2p.ID
err error
2017-09-06 11:50:43 -04:00
}
2015-03-22 16:23:24 -07:00
2019-04-13 09:23:43 -04:00
tests := []struct {
name string
pool *blockPool
args args
poolWanted *blockPool
2019-04-13 09:23:43 -04:00
}{
{
name: "attempt to delete non-existing peer",
pool: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 120}}, map[int64]tPBlocks{}),
args: args{"P99", nil},
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 120}}, map[int64]tPBlocks{}),
},
{
name: "delete the only peer without blocks",
pool: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 120}}, map[int64]tPBlocks{}),
args: args{"P1", nil},
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{}, map[int64]tPBlocks{}),
},
{
name: "delete the shortest of two peers without blocks",
pool: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 120}}, map[int64]tPBlocks{}),
args: args{"P1", nil},
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P2", Height: 120}}, map[int64]tPBlocks{}),
},
{
name: "delete the tallest of two peers without blocks",
pool: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 120}}, map[int64]tPBlocks{}),
args: args{"P2", nil},
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 100}}, map[int64]tPBlocks{}),
2019-04-13 09:23:43 -04:00
},
{
name: "delete the only peer with block requests sent and blocks received",
pool: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 120}},
map[int64]tPBlocks{100: {"P1", true}, 101: {"P1", false}}),
args: args{"P1", nil},
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{}, map[int64]tPBlocks{}),
2019-04-13 09:23:43 -04:00
},
{
name: "delete the shortest of two peers with block requests sent and blocks received",
pool: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 120}, {ID: "P2", Height: 200}},
map[int64]tPBlocks{100: {"P1", true}, 101: {"P1", false}}),
args: args{"P1", nil},
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P2", Height: 200}}, map[int64]tPBlocks{}),
2019-04-13 09:23:43 -04:00
},
{
name: "delete the tallest of two peers with block requests sent and blocks received",
pool: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 120}, {ID: "P2", Height: 110}},
map[int64]tPBlocks{100: {"P1", true}, 101: {"P1", false}}),
args: args{"P1", nil},
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P2", Height: 110}}, map[int64]tPBlocks{}),
2019-04-13 09:23:43 -04:00
},
2015-09-09 21:44:48 -07:00
}
2019-04-13 09:23:43 -04:00
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
2019-06-02 19:03:51 +02:00
tt.pool.RemovePeer(tt.args.peerID, tt.args.err)
assertBlockPoolEquivalent(t, tt.poolWanted, tt.pool)
2019-04-13 09:23:43 -04:00
})
}
}
func TestBlockPoolRemoveShortPeers(t *testing.T) {
2019-04-13 09:23:43 -04:00
testBcR := newTestBcR()
tests := []struct {
name string
pool *blockPool
poolWanted *blockPool
2019-04-13 09:23:43 -04:00
}{
{
name: "no short peers",
pool: makeBlockPool(testBcR, 100,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 110}, {ID: "P3", Height: 120}}, map[int64]tPBlocks{}),
poolWanted: makeBlockPool(testBcR, 100,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 110}, {ID: "P3", Height: 120}}, map[int64]tPBlocks{}),
2019-04-13 09:23:43 -04:00
},
2019-04-13 09:23:43 -04:00
{
name: "one short peer",
2019-04-13 09:23:43 -04:00
pool: makeBlockPool(testBcR, 100,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 90}, {ID: "P3", Height: 120}}, map[int64]tPBlocks{}),
poolWanted: makeBlockPool(testBcR, 100,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P3", Height: 120}}, map[int64]tPBlocks{}),
2019-04-13 09:23:43 -04:00
},
2019-04-13 09:23:43 -04:00
{
name: "all short peers",
pool: makeBlockPool(testBcR, 100,
[]bpPeer{{ID: "P1", Height: 90}, {ID: "P2", Height: 91}, {ID: "P3", Height: 92}}, map[int64]tPBlocks{}),
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{}, map[int64]tPBlocks{}),
2019-04-13 09:23:43 -04:00
},
}
2015-03-24 11:02:30 -07:00
2019-04-13 09:23:43 -04:00
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
pool := tt.pool
pool.removeShortPeers()
assertBlockPoolEquivalent(t, tt.poolWanted, tt.pool)
2019-04-13 09:23:43 -04:00
})
2015-03-22 16:23:24 -07:00
}
2015-03-22 12:46:53 -07:00
}
2019-04-13 09:23:43 -04:00
func TestBlockPoolSendRequestBatch(t *testing.T) {
type testPeerResult struct {
2019-06-02 19:03:51 +02:00
id p2p.ID
numPendingBlockRequests int
}
2019-04-13 09:23:43 -04:00
testBcR := newTestBcR()
2019-04-13 09:23:43 -04:00
tests := []struct {
2019-06-02 19:03:51 +02:00
name string
pool *blockPool
maxRequestsPerPeer int
2019-06-02 19:03:51 +02:00
expRequests map[int64]bool
expPeerResults []testPeerResult
expnumPendingBlockRequests int
2019-04-13 09:23:43 -04:00
}{
{
2019-06-02 19:03:51 +02:00
name: "one peer - send up to maxRequestsPerPeer block requests",
pool: makeBlockPool(testBcR, 10, []bpPeer{{ID: "P1", Height: 100}}, map[int64]tPBlocks{}),
2019-06-02 19:03:51 +02:00
maxRequestsPerPeer: 2,
expRequests: map[int64]bool{10: true, 11: true},
expPeerResults: []testPeerResult{{id: "P1", numPendingBlockRequests: 2}},
expnumPendingBlockRequests: 2,
2019-04-13 09:23:43 -04:00
},
{
name: "n peers - send n*maxRequestsPerPeer block requests",
pool: makeBlockPool(testBcR, 10, []bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 100}}, map[int64]tPBlocks{}),
2019-04-13 09:23:43 -04:00
maxRequestsPerPeer: 2,
expRequests: map[int64]bool{10: true, 11: true},
expPeerResults: []testPeerResult{
2019-06-02 19:03:51 +02:00
{id: "P1", numPendingBlockRequests: 2},
{id: "P2", numPendingBlockRequests: 2}},
expnumPendingBlockRequests: 4,
2019-04-13 09:23:43 -04:00
},
}
2019-04-13 09:23:43 -04:00
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
resetPoolTestResults()
2019-04-17 22:41:28 -04:00
var pool = tt.pool
maxRequestsPerPeer = tt.maxRequestsPerPeer
2019-06-02 19:03:51 +02:00
pool.MakeNextRequests(10)
assert.Equal(t, testResults.numRequestsSent, maxRequestsPerPeer*len(pool.peers))
2019-04-13 09:23:43 -04:00
for _, tPeer := range tt.expPeerResults {
2019-04-17 22:41:28 -04:00
var peer = pool.peers[tPeer.id]
2019-04-13 09:23:43 -04:00
assert.NotNil(t, peer)
assert.Equal(t, tPeer.numPendingBlockRequests, peer.NumPendingBlockRequests)
2019-04-13 09:23:43 -04:00
}
assert.Equal(t, testResults.numRequestsSent, maxRequestsPerPeer*len(pool.peers))
2019-04-13 09:23:43 -04:00
})
}
2019-04-13 09:23:43 -04:00
}
2019-04-13 09:23:43 -04:00
func TestBlockPoolAddBlock(t *testing.T) {
testBcR := newTestBcR()
txs := []types.Tx{types.Tx("foo"), types.Tx("bar")}
2019-04-13 09:23:43 -04:00
type args struct {
peerID p2p.ID
block *types.Block
blockSize int
}
tests := []struct {
name string
pool *blockPool
args args
poolWanted *blockPool
errWanted error
2019-04-13 09:23:43 -04:00
}{
{name: "block from unknown peer",
pool: makeBlockPool(testBcR, 10, []bpPeer{{ID: "P1", Height: 100}}, map[int64]tPBlocks{}),
2019-04-13 09:23:43 -04:00
args: args{
peerID: "P2",
block: types.MakeBlock(int64(10), txs, nil, nil),
blockSize: 100,
},
poolWanted: makeBlockPool(testBcR, 10, []bpPeer{{ID: "P1", Height: 100}}, map[int64]tPBlocks{}),
errWanted: errBadDataFromPeer,
2019-04-13 09:23:43 -04:00
},
{name: "unexpected block 11 from known peer - waiting for 10",
pool: makeBlockPool(testBcR, 10,
[]bpPeer{{ID: "P1", Height: 100}},
2019-04-13 09:23:43 -04:00
map[int64]tPBlocks{10: {"P1", false}}),
args: args{
peerID: "P1",
block: types.MakeBlock(int64(11), txs, nil, nil),
blockSize: 100,
},
poolWanted: makeBlockPool(testBcR, 10,
[]bpPeer{{ID: "P1", Height: 100}},
map[int64]tPBlocks{10: {"P1", false}}),
errWanted: errMissingRequest,
2019-04-13 09:23:43 -04:00
},
{name: "unexpected block 10 from known peer - already have 10",
pool: makeBlockPool(testBcR, 10,
[]bpPeer{{ID: "P1", Height: 100}},
map[int64]tPBlocks{10: {"P1", true}, 11: {"P1", false}}),
2019-04-13 09:23:43 -04:00
args: args{
peerID: "P1",
block: types.MakeBlock(int64(10), txs, nil, nil),
blockSize: 100,
},
poolWanted: makeBlockPool(testBcR, 10,
[]bpPeer{{ID: "P1", Height: 100}},
map[int64]tPBlocks{10: {"P1", true}, 11: {"P1", false}}),
errWanted: errDuplicateBlock,
},
{name: "unexpected block 10 from known peer P2 - expected 10 to come from P1",
pool: makeBlockPool(testBcR, 10,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 100}},
map[int64]tPBlocks{10: {"P1", false}}),
args: args{
peerID: "P2",
block: types.MakeBlock(int64(10), txs, nil, nil),
blockSize: 100,
},
poolWanted: makeBlockPool(testBcR, 10,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 100}},
map[int64]tPBlocks{10: {"P1", false}}),
errWanted: errBadDataFromPeer,
2019-04-13 09:23:43 -04:00
},
{name: "expected block from known peer",
pool: makeBlockPool(testBcR, 10,
[]bpPeer{{ID: "P1", Height: 100}},
2019-04-13 09:23:43 -04:00
map[int64]tPBlocks{10: {"P1", false}}),
args: args{
peerID: "P1",
block: types.MakeBlock(int64(10), txs, nil, nil),
blockSize: 100,
},
poolWanted: makeBlockPool(testBcR, 10,
[]bpPeer{{ID: "P1", Height: 100}},
map[int64]tPBlocks{10: {"P1", true}}),
errWanted: nil,
2019-04-13 09:23:43 -04:00
},
}
2019-04-13 09:23:43 -04:00
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
2019-06-02 19:03:51 +02:00
err := tt.pool.AddBlock(tt.args.peerID, tt.args.block, tt.args.blockSize)
assert.Equal(t, tt.errWanted, err)
assertBlockPoolEquivalent(t, tt.poolWanted, tt.pool)
2019-04-13 09:23:43 -04:00
})
}
2019-04-13 09:23:43 -04:00
}
2019-04-13 09:23:43 -04:00
func TestBlockPoolGetNextTwoBlocks(t *testing.T) {
testBcR := newTestBcR()
tests := []struct {
name string
pool *blockPool
firstWanted int64
secondWanted int64
errWanted error
2019-04-13 09:23:43 -04:00
}{
{
name: "both blocks missing",
pool: makeBlockPool(testBcR, 10,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 100}},
2019-04-13 09:23:43 -04:00
map[int64]tPBlocks{15: {"P1", true}, 16: {"P2", true}}),
2019-06-02 19:03:51 +02:00
errWanted: errMissingBlock,
2019-04-13 09:23:43 -04:00
},
{
name: "second block missing",
pool: makeBlockPool(testBcR, 15,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 100}},
2019-04-13 09:23:43 -04:00
map[int64]tPBlocks{15: {"P1", true}, 18: {"P2", true}}),
firstWanted: 15,
2019-06-02 19:03:51 +02:00
errWanted: errMissingBlock,
2019-04-13 09:23:43 -04:00
},
{
name: "first block missing",
pool: makeBlockPool(testBcR, 15,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 100}},
map[int64]tPBlocks{16: {"P2", true}, 18: {"P2", true}}),
2019-04-13 09:23:43 -04:00
secondWanted: 16,
2019-06-02 19:03:51 +02:00
errWanted: errMissingBlock,
2019-04-13 09:23:43 -04:00
},
{
name: "both blocks present",
pool: makeBlockPool(testBcR, 10,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 100}},
2019-04-13 09:23:43 -04:00
map[int64]tPBlocks{10: {"P1", true}, 11: {"P2", true}}),
firstWanted: 10,
secondWanted: 11,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
pool := tt.pool
2019-06-02 19:03:51 +02:00
gotFirst, gotSecond, err := pool.GetNextTwoBlocks()
assert.Equal(t, tt.errWanted, err)
2019-04-13 09:23:43 -04:00
if tt.firstWanted != 0 {
peer := pool.blocks[tt.firstWanted]
block := pool.peers[peer].blocks[tt.firstWanted]
assert.Equal(t, gotFirst.block, block,
"blockPool.getNextTwoBlocks() gotFirst = %v, want %v", gotFirst.block.Height, tt.firstWanted)
2019-04-13 09:23:43 -04:00
}
2019-04-13 09:23:43 -04:00
if tt.secondWanted != 0 {
peer := pool.blocks[tt.secondWanted]
block := pool.peers[peer].blocks[tt.secondWanted]
assert.Equal(t, gotSecond.block, block,
"blockPool.getNextTwoBlocks() gotFirst = %v, want %v", gotSecond.block.Height, tt.secondWanted)
2019-04-13 09:23:43 -04:00
}
})
}
}
func TestBlockPoolInvalidateFirstTwoBlocks(t *testing.T) {
testBcR := newTestBcR()
tests := []struct {
name string
pool *blockPool
poolWanted *blockPool
2019-04-13 09:23:43 -04:00
}{
{
name: "both blocks missing",
pool: makeBlockPool(testBcR, 10,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 100}},
2019-04-13 09:23:43 -04:00
map[int64]tPBlocks{15: {"P1", true}, 16: {"P2", true}}),
poolWanted: makeBlockPool(testBcR, 10,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 100}},
map[int64]tPBlocks{15: {"P1", true}, 16: {"P2", true}}),
2019-04-13 09:23:43 -04:00
},
{
name: "second block missing",
pool: makeBlockPool(testBcR, 15,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 100}},
2019-04-13 09:23:43 -04:00
map[int64]tPBlocks{15: {"P1", true}, 18: {"P2", true}}),
poolWanted: makeBlockPool(testBcR, 15,
[]bpPeer{{ID: "P2", Height: 100}},
map[int64]tPBlocks{18: {"P2", true}}),
2019-04-13 09:23:43 -04:00
},
{
name: "first block missing",
pool: makeBlockPool(testBcR, 15,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 100}},
2019-04-13 09:23:43 -04:00
map[int64]tPBlocks{18: {"P1", true}, 16: {"P2", true}}),
poolWanted: makeBlockPool(testBcR, 15,
[]bpPeer{{ID: "P1", Height: 100}},
map[int64]tPBlocks{18: {"P1", true}}),
2019-04-13 09:23:43 -04:00
},
{
name: "both blocks present",
pool: makeBlockPool(testBcR, 10,
[]bpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 100}},
2019-04-13 09:23:43 -04:00
map[int64]tPBlocks{10: {"P1", true}, 11: {"P2", true}}),
poolWanted: makeBlockPool(testBcR, 10,
[]bpPeer{},
map[int64]tPBlocks{}),
2019-04-13 09:23:43 -04:00
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
2019-06-02 19:03:51 +02:00
tt.pool.InvalidateFirstTwoBlocks(errNoPeerResponse)
assertBlockPoolEquivalent(t, tt.poolWanted, tt.pool)
})
}
}
2019-04-13 09:23:43 -04:00
func TestProcessedCurrentHeightBlock(t *testing.T) {
testBcR := newTestBcR()
tests := []struct {
name string
pool *blockPool
poolWanted *blockPool
}{
{
name: "one peer",
pool: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 120}},
map[int64]tPBlocks{100: {"P1", true}, 101: {"P1", true}}),
poolWanted: makeBlockPool(testBcR, 101, []bpPeer{{ID: "P1", Height: 120}},
map[int64]tPBlocks{101: {"P1", true}}),
},
{
name: "multiple peers",
pool: makeBlockPool(testBcR, 100,
[]bpPeer{{ID: "P1", Height: 120}, {ID: "P2", Height: 120}, {ID: "P3", Height: 130}},
map[int64]tPBlocks{
100: {"P1", true}, 104: {"P1", true}, 105: {"P1", false},
101: {"P2", true}, 103: {"P2", false},
102: {"P3", true}, 106: {"P3", true}}),
poolWanted: makeBlockPool(testBcR, 101,
[]bpPeer{{ID: "P1", Height: 120}, {ID: "P2", Height: 120}, {ID: "P3", Height: 130}},
map[int64]tPBlocks{
104: {"P1", true}, 105: {"P1", false},
101: {"P2", true}, 103: {"P2", false},
102: {"P3", true}, 106: {"P3", true}}),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
2019-06-02 19:03:51 +02:00
tt.pool.ProcessedCurrentHeightBlock()
assertBlockPoolEquivalent(t, tt.poolWanted, tt.pool)
})
}
}
func TestRemovePeerAtCurrentHeight(t *testing.T) {
testBcR := newTestBcR()
tests := []struct {
name string
pool *blockPool
poolWanted *blockPool
}{
{
name: "one peer, remove peer for block at H",
pool: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 120}},
map[int64]tPBlocks{100: {"P1", false}, 101: {"P1", true}}),
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{}, map[int64]tPBlocks{}),
},
{
name: "one peer, remove peer for block at H+1",
pool: makeBlockPool(testBcR, 100, []bpPeer{{ID: "P1", Height: 120}},
map[int64]tPBlocks{100: {"P1", true}, 101: {"P1", false}}),
poolWanted: makeBlockPool(testBcR, 100, []bpPeer{}, map[int64]tPBlocks{}),
},
{
name: "multiple peers, remove peer for block at H",
pool: makeBlockPool(testBcR, 100,
[]bpPeer{{ID: "P1", Height: 120}, {ID: "P2", Height: 120}, {ID: "P3", Height: 130}},
map[int64]tPBlocks{
100: {"P1", false}, 104: {"P1", true}, 105: {"P1", false},
101: {"P2", true}, 103: {"P2", false},
102: {"P3", true}, 106: {"P3", true}}),
poolWanted: makeBlockPool(testBcR, 100,
[]bpPeer{{ID: "P2", Height: 120}, {ID: "P3", Height: 130}},
map[int64]tPBlocks{
101: {"P2", true}, 103: {"P2", false},
102: {"P3", true}, 106: {"P3", true}}),
},
{
name: "multiple peers, remove peer for block at H+1",
pool: makeBlockPool(testBcR, 100,
[]bpPeer{{ID: "P1", Height: 120}, {ID: "P2", Height: 120}, {ID: "P3", Height: 130}},
map[int64]tPBlocks{
100: {"P1", true}, 104: {"P1", true}, 105: {"P1", false},
101: {"P2", false}, 103: {"P2", false},
102: {"P3", true}, 106: {"P3", true}}),
poolWanted: makeBlockPool(testBcR, 100,
[]bpPeer{{ID: "P1", Height: 120}, {ID: "P3", Height: 130}},
map[int64]tPBlocks{
100: {"P1", true}, 104: {"P1", true}, 105: {"P1", false},
102: {"P3", true}, 106: {"P3", true}}),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
2019-06-02 19:03:51 +02:00
tt.pool.RemovePeerAtCurrentHeights(errNoPeerResponse)
assertBlockPoolEquivalent(t, tt.poolWanted, tt.pool)
2019-04-13 09:23:43 -04:00
})
}
}