Skip to content

Commit 2442639

Browse files
committed
blockmanager: add test for non-connected headers
1 parent f772956 commit 2442639

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

blockmanager_test.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@ import (
44
"encoding/binary"
55
"fmt"
66
"math/rand"
7+
"reflect"
78
"strings"
89
"testing"
910
"time"
1011

12+
"github.com/btcsuite/btcd/blockchain"
1113
"github.com/btcsuite/btcd/btcutil/gcs"
1214
"github.com/btcsuite/btcd/btcutil/gcs/builder"
1315
"github.com/btcsuite/btcd/chaincfg"
1416
"github.com/btcsuite/btcd/chaincfg/chainhash"
17+
"github.com/btcsuite/btcd/integration/rpctest"
1518
"github.com/btcsuite/btcd/peer"
1619
"github.com/btcsuite/btcd/txscript"
1720
"github.com/btcsuite/btcd/wire"
@@ -90,6 +93,7 @@ func setupBlockManager(t *testing.T) (*blockManager, headerfs.BlockHeaderStore,
9093
BlockHeaders: hdrStore,
9194
RegFilterHeaders: cfStore,
9295
QueryDispatcher: &mockDispatcher{},
96+
TimeSource: blockchain.NewMedianTime(),
9397
BanPeer: func(string, banman.Reason) error {
9498
return nil
9599
},
@@ -865,3 +869,79 @@ func TestBlockManagerDetectBadPeers(t *testing.T) {
865869
require.NoError(t, err)
866870
}
867871
}
872+
873+
// TestHandleHeaders checks that we handle headers correctly, and that we
874+
// disconnect peers that serve us bad headers (headers that don't connect to
875+
// each other properly).
876+
func TestHandleHeaders(t *testing.T) {
877+
t.Parallel()
878+
879+
// First, we set up a block manager and a fake peer that will act as the
880+
// test's remote peer.
881+
bm, _, _, err := setupBlockManager(t)
882+
require.NoError(t, err)
883+
884+
fakePeer, err := peer.NewOutboundPeer(&peer.Config{}, "fake:123")
885+
require.NoError(t, err)
886+
887+
assertPeerDisconnected := func(shouldBeDisconnected bool) {
888+
// This is quite hacky but works: We expect the peer to be
889+
// disconnected, which sets the unexported "disconnected" field
890+
// to 1.
891+
refValue := reflect.ValueOf(fakePeer).Elem()
892+
foo := refValue.FieldByName("disconnect").Int()
893+
894+
if shouldBeDisconnected {
895+
require.EqualValues(t, 1, foo)
896+
} else {
897+
require.EqualValues(t, 0, foo)
898+
}
899+
}
900+
901+
// We'll want to use actual, real blocks, so we take a miner harness
902+
// that we can use to generate some.
903+
harness, err := rpctest.New(
904+
&chaincfg.SimNetParams, nil, []string{"--txindex"}, "",
905+
)
906+
require.NoError(t, err)
907+
t.Cleanup(func() {
908+
require.NoError(t, harness.TearDown())
909+
})
910+
911+
err = harness.SetUp(false, 0)
912+
require.NoError(t, err)
913+
914+
// Generate 200 valid blocks that we then feed to the block manager.
915+
blockHashes, err := harness.Client.Generate(200)
916+
require.NoError(t, err)
917+
918+
hmsg := &headersMsg{
919+
headers: &wire.MsgHeaders{
920+
Headers: make([]*wire.BlockHeader, len(blockHashes)),
921+
},
922+
peer: &ServerPeer{
923+
Peer: fakePeer,
924+
},
925+
}
926+
927+
for i := range blockHashes {
928+
header, err := harness.Client.GetBlockHeader(blockHashes[i])
929+
require.NoError(t, err)
930+
931+
hmsg.headers.Headers[i] = header
932+
}
933+
934+
// Let's feed in the correct headers. This should work fine and the peer
935+
// should not be disconnected.
936+
bm.handleHeadersMsg(hmsg)
937+
assertPeerDisconnected(false)
938+
939+
// Now scramble the headers and feed them in again. This should cause
940+
// the peer to be disconnected.
941+
rand.Shuffle(len(hmsg.headers.Headers), func(i, j int) {
942+
hmsg.headers.Headers[i], hmsg.headers.Headers[j] =
943+
hmsg.headers.Headers[j], hmsg.headers.Headers[i]
944+
})
945+
bm.handleHeadersMsg(hmsg)
946+
assertPeerDisconnected(true)
947+
}

0 commit comments

Comments
 (0)