mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-03 20:56:42 +00:00
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:
parent
1222a555f2
commit
94cdc77481
@ -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",
|
||||
|
16
app/appmessage/p2p_msgibdblocklocatorhighesthashnotfound.go
Normal file
16
app/appmessage/p2p_msgibdblocklocatorhighesthashnotfound.go
Normal 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{}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
@ -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)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -39,6 +39,7 @@ message KaspadMessage {
|
||||
BlockHeadersMessage blockHeaders = 32;
|
||||
RequestNextPruningPointUtxoSetChunkMessage requestNextPruningPointUtxoSetChunk = 33;
|
||||
DonePruningPointUtxoSetChunksMessage donePruningPointUtxoSetChunks = 34;
|
||||
IbdBlockLocatorHighestHashNotFoundMessage ibdBlockLocatorHighestHashNotFound = 35;
|
||||
|
||||
GetCurrentNetworkRequestMessage getCurrentNetworkRequest = 1001;
|
||||
GetCurrentNetworkResponseMessage getCurrentNetworkResponse = 1002;
|
||||
|
@ -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,
|
||||
},
|
||||
|
@ -195,6 +195,9 @@ message IbdBlockLocatorHighestHashMessage {
|
||||
Hash highestHash = 1;
|
||||
}
|
||||
|
||||
message IbdBlockLocatorHighestHashNotFoundMessage {
|
||||
}
|
||||
|
||||
message BlockHeadersMessage {
|
||||
repeated BlockHeaderMessage blockHeaders = 1;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user