Send peers the hash of the virtual selected parent once connection is established (#1519)

* Send peers the hash of the virtual selected parent once connection is established.

* Add a log to SendVirtualSelectedParentInv.

* Fix TestIBDWithPruning.

* Fix TestIBDWithPruning better and signal from the IBD syncer to the IBD syncee that the DAG is split amongst them.

* Fix TestVirtualSelectedParentChain.

* Add comments.
This commit is contained in:
stasatdaglabs 2021-02-10 18:09:25 +02:00 committed by GitHub
parent 1222a555f2
commit 94cdc77481
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 805 additions and 623 deletions

View File

@ -59,6 +59,7 @@ const (
CmdPruningPointHash
CmdIBDBlockLocator
CmdIBDBlockLocatorHighestHash
CmdIBDBlockLocatorHighestHashNotFound
CmdBlockHeaders
CmdRequestNextPruningPointUTXOSetChunk
CmdDonePruningPointUTXOSetChunks
@ -162,6 +163,7 @@ var ProtocolMessageCommandToString = map[MessageCommand]string{
CmdPruningPointHash: "PruningPointHash",
CmdIBDBlockLocator: "IBDBlockLocator",
CmdIBDBlockLocatorHighestHash: "IBDBlockLocatorHighestHash",
CmdIBDBlockLocatorHighestHashNotFound: "IBDBlockLocatorHighestHashNotFound",
CmdBlockHeaders: "BlockHeaders",
CmdRequestNextPruningPointUTXOSetChunk: "RequestNextPruningPointUTXOSetChunk",
CmdDonePruningPointUTXOSetChunks: "DonePruningPointUTXOSetChunks",

View File

@ -0,0 +1,16 @@
package appmessage
// MsgIBDBlockLocatorHighestHashNotFound represents a kaspa BlockLocatorHighestHashNotFound message
type MsgIBDBlockLocatorHighestHashNotFound struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *MsgIBDBlockLocatorHighestHashNotFound) Command() MessageCommand {
return CmdIBDBlockLocatorHighestHashNotFound
}
// NewMsgIBDBlockLocatorHighestHashNotFound returns a new IBDBlockLocatorHighestHashNotFound message
func NewMsgIBDBlockLocatorHighestHashNotFound() *MsgIBDBlockLocatorHighestHashNotFound {
return &MsgIBDBlockLocatorHighestHashNotFound{}
}

View File

@ -70,8 +70,14 @@ func HandleIBDBlockLocator(context HandleIBDBlockLocatorContext, incomingRoute *
}
if !foundHighestHashInTheSelectedParentChainOfTargetHash {
return protocolerrors.Errorf(true, "no hash was found in the blockLocator "+
log.Warnf("no hash was found in the blockLocator "+
"that was in the selected parent chain of targetHash %s", targetHash)
ibdBlockLocatorHighestHashNotFoundMessage := appmessage.NewMsgIBDBlockLocatorHighestHashNotFound()
err = outgoingRoute.Enqueue(ibdBlockLocatorHighestHashNotFoundMessage)
if err != nil {
return err
}
}
}
}

View File

@ -28,10 +28,14 @@ func (flow *handleRelayInvsFlow) runIBDIfNotRunning(highHash *externalapi.Domain
log.Debugf("IBD started with peer %s and highHash %s", flow.peer, highHash)
log.Debugf("Syncing headers up to %s", highHash)
err := flow.syncHeaders(highHash)
headersSynced, err := flow.syncHeaders(highHash)
if err != nil {
return err
}
if !headersSynced {
log.Debugf("Aborting IBD because the headers failed to sync")
return nil
}
log.Debugf("Finished syncing headers up to %s", highHash)
log.Debugf("Syncing the current pruning point UTXO set")
@ -55,47 +59,61 @@ func (flow *handleRelayInvsFlow) runIBDIfNotRunning(highHash *externalapi.Domain
return nil
}
func (flow *handleRelayInvsFlow) syncHeaders(highHash *externalapi.DomainHash) error {
// syncHeaders attempts to sync headers from the peer. This method may fail
// because the peer and us have conflicting pruning points. In that case we
// return (false, nil) so that we may stop IBD gracefully.
func (flow *handleRelayInvsFlow) syncHeaders(highHash *externalapi.DomainHash) (bool, error) {
log.Debugf("Trying to find highest shared chain block with peer %s with high hash %s", flow.peer, highHash)
highestSharedBlockHash, err := flow.findHighestSharedBlockHash(highHash)
highestSharedBlockHash, highestSharedBlockFound, err := flow.findHighestSharedBlockHash(highHash)
if err != nil {
return err
return false, err
}
if !highestSharedBlockFound {
return false, nil
}
log.Debugf("Found highest shared chain block %s with peer %s", highestSharedBlockHash, flow.peer)
err = flow.downloadHeaders(highestSharedBlockHash, highHash)
if err != nil {
return err
return false, err
}
// If the highHash has not been received, the peer is misbehaving
highHashBlockInfo, err := flow.Domain().Consensus().GetBlockInfo(highHash)
if err != nil {
return err
return false, err
}
if !highHashBlockInfo.Exists {
return protocolerrors.Errorf(true, "did not receive "+
return false, protocolerrors.Errorf(true, "did not receive "+
"highHash header %s from peer %s during header download", highHash, flow.peer)
}
log.Debugf("Headers downloaded from peer %s", flow.peer)
return nil
return true, nil
}
func (flow *handleRelayInvsFlow) findHighestSharedBlockHash(targetHash *externalapi.DomainHash) (*externalapi.DomainHash, error) {
// findHighestSharedBlock attempts to find the highest shared block between the peer
// and this node. This method may fail because the peer and us have conflicting pruning
// points. In that case we return (nil, false, nil) so that we may stop IBD gracefully.
func (flow *handleRelayInvsFlow) findHighestSharedBlockHash(
targetHash *externalapi.DomainHash) (*externalapi.DomainHash, bool, error) {
log.Debugf("Sending a blockLocator to %s between pruning point and headers selected tip", flow.peer)
blockLocator, err := flow.Domain().Consensus().CreateFullHeadersSelectedChainBlockLocator()
if err != nil {
return nil, err
return nil, false, err
}
for {
highestHash, err := flow.fetchHighestHash(targetHash, blockLocator)
highestHash, highestHashFound, err := flow.fetchHighestHash(targetHash, blockLocator)
if err != nil {
return nil, err
return nil, false, err
}
if !highestHashFound {
return nil, false, nil
}
highestHashIndex, err := flow.findHighestHashIndex(highestHash, blockLocator)
if err != nil {
return nil, err
return nil, false, err
}
if highestHashIndex == 0 ||
@ -104,7 +122,7 @@ func (flow *handleRelayInvsFlow) findHighestSharedBlockHash(targetHash *external
// an endless loop, we explicitly stop the loop in such situation.
(len(blockLocator) == 2 && highestHashIndex == 1) {
return highestHash, nil
return highestHash, true, nil
}
locatorHashAboveHighestHash := highestHash
@ -114,7 +132,7 @@ func (flow *handleRelayInvsFlow) findHighestSharedBlockHash(targetHash *external
blockLocator, err = flow.nextBlockLocator(highestHash, locatorHashAboveHighestHash)
if err != nil {
return nil, err
return nil, false, err
}
}
}
@ -159,27 +177,35 @@ func (flow *handleRelayInvsFlow) findHighestHashIndex(
return highestHashIndex, nil
}
// fetchHighestHash attempts to fetch the highest hash the peer knows amongst the given
// blockLocator. This method may fail because the peer and us have conflicting pruning
// points. In that case we return (nil, false, nil) so that we may stop IBD gracefully.
func (flow *handleRelayInvsFlow) fetchHighestHash(
targetHash *externalapi.DomainHash, blockLocator externalapi.BlockLocator) (*externalapi.DomainHash, error) {
targetHash *externalapi.DomainHash, blockLocator externalapi.BlockLocator) (*externalapi.DomainHash, bool, error) {
ibdBlockLocatorMessage := appmessage.NewMsgIBDBlockLocator(targetHash, blockLocator)
err := flow.outgoingRoute.Enqueue(ibdBlockLocatorMessage)
if err != nil {
return nil, err
return nil, false, err
}
message, err := flow.dequeueIncomingMessageAndSkipInvs(common.DefaultTimeout)
if err != nil {
return nil, err
return nil, false, err
}
ibdBlockLocatorHighestHashMessage, ok := message.(*appmessage.MsgIBDBlockLocatorHighestHash)
if !ok {
return nil, protocolerrors.Errorf(true, "received unexpected message type. "+
switch message := message.(type) {
case *appmessage.MsgIBDBlockLocatorHighestHash:
highestHash := message.HighestHash
log.Debugf("The highest hash the peer %s knows is %s", flow.peer, highestHash)
return highestHash, true, nil
case *appmessage.MsgIBDBlockLocatorHighestHashNotFound:
log.Debugf("Peer %s does not know any block within our blockLocator. "+
"This should only happen if there's a DAG split deeper than the pruning point.", flow.peer)
return nil, false, nil
default:
return nil, false, protocolerrors.Errorf(true, "received unexpected message type. "+
"expected: %s, got: %s", appmessage.CmdIBDBlockLocatorHighestHash, message.Command())
}
highestHash := ibdBlockLocatorHighestHashMessage.HighestHash
log.Debugf("The highest hash the peer %s knows is %s", flow.peer, highestHash)
return highestHash, nil
}
func (flow *handleRelayInvsFlow) downloadHeaders(highestSharedBlockHash *externalapi.DomainHash,

View File

@ -0,0 +1,28 @@
package blockrelay
import (
"github.com/kaspanet/kaspad/app/appmessage"
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
"github.com/kaspanet/kaspad/domain"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
)
// SendVirtualSelectedParentInvContext is the interface for the context needed for the SendVirtualSelectedParentInv flow.
type SendVirtualSelectedParentInvContext interface {
Domain() domain.Domain
}
// SendVirtualSelectedParentInv sends a peer the selected parent hash of the virtual
func SendVirtualSelectedParentInv(context SendVirtualSelectedParentInvContext,
outgoingRoute *router.Route, peer *peerpkg.Peer) error {
virtualSelectedParent, err := context.Domain().Consensus().GetVirtualSelectedParent()
if err != nil {
return err
}
log.Debugf("Sending virtual selected parent hash %s to peer %s", virtualSelectedParent, peer)
virtualSelectedParentInv := appmessage.NewMsgInvBlock(virtualSelectedParent)
return outgoingRoute.Enqueue(virtualSelectedParentInv)
}

View File

@ -136,11 +136,16 @@ func (m *Manager) registerBlockRelayFlows(router *routerpkg.Router, isStopping *
outgoingRoute := router.OutgoingRoute()
return []*flow{
m.registerOneTimeFlow("SendVirtualSelectedParentInv", router, []appmessage.MessageCommand{},
isStopping, errChan, func(route *routerpkg.Route, peer *peerpkg.Peer) error {
return blockrelay.SendVirtualSelectedParentInv(m.context, outgoingRoute, peer)
}),
m.registerFlow("HandleRelayInvs", router, []appmessage.MessageCommand{
appmessage.CmdInvRelayBlock, appmessage.CmdBlock, appmessage.CmdBlockLocator, appmessage.CmdIBDBlock,
appmessage.CmdDoneHeaders, appmessage.CmdUnexpectedPruningPoint, appmessage.CmdPruningPointUTXOSetChunk,
appmessage.CmdBlockHeaders, appmessage.CmdPruningPointHash, appmessage.CmdIBDBlockLocatorHighestHash,
appmessage.CmdDonePruningPointUTXOSetChunks},
appmessage.CmdIBDBlockLocatorHighestHashNotFound, appmessage.CmdDonePruningPointUTXOSetChunks},
isStopping, errChan, func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return blockrelay.HandleRelayInvs(m.context, incomingRoute,
outgoingRoute, peer)

View File

@ -39,6 +39,7 @@ message KaspadMessage {
BlockHeadersMessage blockHeaders = 32;
RequestNextPruningPointUtxoSetChunkMessage requestNextPruningPointUtxoSetChunk = 33;
DonePruningPointUtxoSetChunksMessage donePruningPointUtxoSetChunks = 34;
IbdBlockLocatorHighestHashNotFoundMessage ibdBlockLocatorHighestHashNotFound = 35;
GetCurrentNetworkRequestMessage getCurrentNetworkRequest = 1001;
GetCurrentNetworkResponseMessage getCurrentNetworkResponse = 1002;

View File

@ -2162,6 +2162,44 @@ func (x *IbdBlockLocatorHighestHashMessage) GetHighestHash() *Hash {
return nil
}
type IbdBlockLocatorHighestHashNotFoundMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *IbdBlockLocatorHighestHashNotFoundMessage) Reset() {
*x = IbdBlockLocatorHighestHashNotFoundMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[40]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *IbdBlockLocatorHighestHashNotFoundMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*IbdBlockLocatorHighestHashNotFoundMessage) ProtoMessage() {}
func (x *IbdBlockLocatorHighestHashNotFoundMessage) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[40]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use IbdBlockLocatorHighestHashNotFoundMessage.ProtoReflect.Descriptor instead.
func (*IbdBlockLocatorHighestHashNotFoundMessage) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{40}
}
type BlockHeadersMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -2173,7 +2211,7 @@ type BlockHeadersMessage struct {
func (x *BlockHeadersMessage) Reset() {
*x = BlockHeadersMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[40]
mi := &file_p2p_proto_msgTypes[41]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2186,7 +2224,7 @@ func (x *BlockHeadersMessage) String() string {
func (*BlockHeadersMessage) ProtoMessage() {}
func (x *BlockHeadersMessage) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[40]
mi := &file_p2p_proto_msgTypes[41]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2199,7 +2237,7 @@ func (x *BlockHeadersMessage) ProtoReflect() protoreflect.Message {
// Deprecated: Use BlockHeadersMessage.ProtoReflect.Descriptor instead.
func (*BlockHeadersMessage) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{40}
return file_p2p_proto_rawDescGZIP(), []int{41}
}
func (x *BlockHeadersMessage) GetBlockHeaders() []*BlockHeaderMessage {
@ -2461,15 +2499,18 @@ var file_p2p_proto_rawDesc = []byte{
0x0b, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x48,
0x61, 0x73, 0x68, 0x52, 0x0b, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x48, 0x61, 0x73, 0x68,
0x22, 0x58, 0x0a, 0x13, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48,
0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0c, 0x62, 0x6c,
0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x42, 0x26, 0x5a, 0x24, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x6e, 0x65,
0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69,
0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x22, 0x2b, 0x0a, 0x29, 0x49, 0x62, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4c, 0x6f, 0x63, 0x61,
0x74, 0x6f, 0x72, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x48, 0x61, 0x73, 0x68, 0x4e, 0x6f,
0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x58, 0x0a,
0x13, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61,
0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64,
0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x42, 0x26, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x6b,
0x61, 0x73, 0x70, 0x61, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -2484,7 +2525,7 @@ func file_p2p_proto_rawDescGZIP() []byte {
return file_p2p_proto_rawDescData
}
var file_p2p_proto_msgTypes = make([]protoimpl.MessageInfo, 41)
var file_p2p_proto_msgTypes = make([]protoimpl.MessageInfo, 42)
var file_p2p_proto_goTypes = []interface{}{
(*RequestAddressesMessage)(nil), // 0: protowire.RequestAddressesMessage
(*AddressesMessage)(nil), // 1: protowire.AddressesMessage
@ -2526,7 +2567,8 @@ var file_p2p_proto_goTypes = []interface{}{
(*PruningPointHashMessage)(nil), // 37: protowire.PruningPointHashMessage
(*IbdBlockLocatorMessage)(nil), // 38: protowire.IbdBlockLocatorMessage
(*IbdBlockLocatorHighestHashMessage)(nil), // 39: protowire.IbdBlockLocatorHighestHashMessage
(*BlockHeadersMessage)(nil), // 40: protowire.BlockHeadersMessage
(*IbdBlockLocatorHighestHashNotFoundMessage)(nil), // 40: protowire.IbdBlockLocatorHighestHashNotFoundMessage
(*BlockHeadersMessage)(nil), // 41: protowire.BlockHeadersMessage
}
var file_p2p_proto_depIdxs = []int32{
3, // 0: protowire.RequestAddressesMessage.subnetworkId:type_name -> protowire.SubnetworkId
@ -3061,6 +3103,18 @@ func file_p2p_proto_init() {
}
}
file_p2p_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IbdBlockLocatorHighestHashNotFoundMessage); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_p2p_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BlockHeadersMessage); i {
case 0:
return &v.state
@ -3079,7 +3133,7 @@ func file_p2p_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_p2p_proto_rawDesc,
NumEnums: 0,
NumMessages: 41,
NumMessages: 42,
NumExtensions: 0,
NumServices: 0,
},

View File

@ -195,6 +195,9 @@ message IbdBlockLocatorHighestHashMessage {
Hash highestHash = 1;
}
message IbdBlockLocatorHighestHashNotFoundMessage {
}
message BlockHeadersMessage {
repeated BlockHeaderMessage blockHeaders = 1;
}

View File

@ -0,0 +1,12 @@
package protowire
import "github.com/kaspanet/kaspad/app/appmessage"
func (x *KaspadMessage_IbdBlockLocatorHighestHashNotFound) toAppMessage() (appmessage.Message, error) {
return &appmessage.MsgIBDBlockLocatorHighestHashNotFound{}, nil
}
func (x *KaspadMessage_IbdBlockLocatorHighestHashNotFound) fromAppMessage(message *appmessage.MsgIBDBlockLocatorHighestHashNotFound) error {
x.IbdBlockLocatorHighestHashNotFound = &IbdBlockLocatorHighestHashNotFoundMessage{}
return nil
}

View File

@ -251,6 +251,13 @@ func toP2PPayload(message appmessage.Message) (isKaspadMessage_Payload, error) {
return nil, err
}
return payload, nil
case *appmessage.MsgIBDBlockLocatorHighestHashNotFound:
payload := new(KaspadMessage_IbdBlockLocatorHighestHashNotFound)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.BlockHeadersMessage:
payload := new(KaspadMessage_BlockHeaders)
err := payload.fromAppMessage(message)

View File

@ -16,7 +16,7 @@ func TestIBD(t *testing.T) {
syncer, syncee, _, teardown := standardSetup(t)
defer teardown()
for i := 0; i < numBlocks-1; i++ {
for i := 0; i < numBlocks; i++ {
mineNextBlock(t, syncer)
}
@ -28,10 +28,8 @@ func TestIBD(t *testing.T) {
blockAddedWG.Done()
})
connect(t, syncer, syncee)
// We expect this to trigger IBD
mineNextBlock(t, syncer)
connect(t, syncer, syncee)
select {
case <-time.After(defaultTimeout):
@ -97,10 +95,8 @@ func TestIBDWithPruning(t *testing.T) {
mineNextBlock(t, syncer)
}
connect(t, syncer, syncee)
// We expect this to trigger IBD
mineNextBlock(t, syncer)
connect(t, syncer, syncee)
syncerBlockCountResponse, err := syncer.rpcClient.GetBlockCount()
if err != nil {

View File

@ -1,6 +1,7 @@
package integration
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"testing"
"github.com/kaspanet/kaspad/app/appmessage"
@ -48,18 +49,17 @@ func TestVirtualSelectedParentChain(t *testing.T) {
chain1TipHashString = minedBlockHashString
}
// In kaspad2, mine a different chain of `blockAmountToMine`
// In kaspad2, mine a different chain of `blockAmountToMine` + 1
// blocks over the genesis
for i := 0; i < blockAmountToMine; i++ {
mineNextBlock(t, kaspad2)
var chain2Tip *externalapi.DomainBlock
for i := 0; i < blockAmountToMine+1; i++ {
chain2Tip = mineNextBlock(t, kaspad2)
}
// Connect the two kaspads
// Connect the two kaspads. This should trigger sync
// between the two nodes
connect(t, kaspad1, kaspad2)
// In kaspad2, mine another block. This should trigger sync
// between the two nodes
chain2Tip := mineNextBlock(t, kaspad2)
chain2TipHash := consensushashing.BlockHash(chain2Tip)
chain2TipHashString := chain2TipHash.String()