Skip to content

Commit

Permalink
blockmanager: add test for non-connected headers
Browse files Browse the repository at this point in the history
  • Loading branch information
guggero committed Aug 4, 2023
1 parent f772956 commit 2442639
Showing 1 changed file with 80 additions and 0 deletions.
80 changes: 80 additions & 0 deletions blockmanager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ import (
"encoding/binary"
"fmt"
"math/rand"
"reflect"
"strings"
"testing"
"time"

"github.com/btcsuite/btcd/blockchain"
"github.com/btcsuite/btcd/btcutil/gcs"
"github.com/btcsuite/btcd/btcutil/gcs/builder"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/integration/rpctest"
"github.com/btcsuite/btcd/peer"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
Expand Down Expand Up @@ -90,6 +93,7 @@ func setupBlockManager(t *testing.T) (*blockManager, headerfs.BlockHeaderStore,
BlockHeaders: hdrStore,
RegFilterHeaders: cfStore,
QueryDispatcher: &mockDispatcher{},
TimeSource: blockchain.NewMedianTime(),
BanPeer: func(string, banman.Reason) error {
return nil
},
Expand Down Expand Up @@ -865,3 +869,79 @@ func TestBlockManagerDetectBadPeers(t *testing.T) {
require.NoError(t, err)
}
}

// TestHandleHeaders checks that we handle headers correctly, and that we
// disconnect peers that serve us bad headers (headers that don't connect to
// each other properly).
func TestHandleHeaders(t *testing.T) {
t.Parallel()

// First, we set up a block manager and a fake peer that will act as the
// test's remote peer.
bm, _, _, err := setupBlockManager(t)
require.NoError(t, err)

fakePeer, err := peer.NewOutboundPeer(&peer.Config{}, "fake:123")
require.NoError(t, err)

assertPeerDisconnected := func(shouldBeDisconnected bool) {
// This is quite hacky but works: We expect the peer to be
// disconnected, which sets the unexported "disconnected" field
// to 1.
refValue := reflect.ValueOf(fakePeer).Elem()
foo := refValue.FieldByName("disconnect").Int()

if shouldBeDisconnected {
require.EqualValues(t, 1, foo)
} else {
require.EqualValues(t, 0, foo)
}
}

// We'll want to use actual, real blocks, so we take a miner harness
// that we can use to generate some.
harness, err := rpctest.New(
&chaincfg.SimNetParams, nil, []string{"--txindex"}, "",
)
require.NoError(t, err)
t.Cleanup(func() {
require.NoError(t, harness.TearDown())
})

err = harness.SetUp(false, 0)
require.NoError(t, err)

// Generate 200 valid blocks that we then feed to the block manager.
blockHashes, err := harness.Client.Generate(200)
require.NoError(t, err)

hmsg := &headersMsg{
headers: &wire.MsgHeaders{
Headers: make([]*wire.BlockHeader, len(blockHashes)),
},
peer: &ServerPeer{
Peer: fakePeer,
},
}

for i := range blockHashes {
header, err := harness.Client.GetBlockHeader(blockHashes[i])
require.NoError(t, err)

hmsg.headers.Headers[i] = header
}

// Let's feed in the correct headers. This should work fine and the peer
// should not be disconnected.
bm.handleHeadersMsg(hmsg)
assertPeerDisconnected(false)

// Now scramble the headers and feed them in again. This should cause
// the peer to be disconnected.
rand.Shuffle(len(hmsg.headers.Headers), func(i, j int) {
hmsg.headers.Headers[i], hmsg.headers.Headers[j] =
hmsg.headers.Headers[j], hmsg.headers.Headers[i]
})
bm.handleHeadersMsg(hmsg)
assertPeerDisconnected(true)
}

0 comments on commit 2442639

Please sign in to comment.