mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-08 15:16:41 +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
|
CmdPruningPointHash
|
||||||
CmdIBDBlockLocator
|
CmdIBDBlockLocator
|
||||||
CmdIBDBlockLocatorHighestHash
|
CmdIBDBlockLocatorHighestHash
|
||||||
|
CmdIBDBlockLocatorHighestHashNotFound
|
||||||
CmdBlockHeaders
|
CmdBlockHeaders
|
||||||
CmdRequestNextPruningPointUTXOSetChunk
|
CmdRequestNextPruningPointUTXOSetChunk
|
||||||
CmdDonePruningPointUTXOSetChunks
|
CmdDonePruningPointUTXOSetChunks
|
||||||
@ -162,6 +163,7 @@ var ProtocolMessageCommandToString = map[MessageCommand]string{
|
|||||||
CmdPruningPointHash: "PruningPointHash",
|
CmdPruningPointHash: "PruningPointHash",
|
||||||
CmdIBDBlockLocator: "IBDBlockLocator",
|
CmdIBDBlockLocator: "IBDBlockLocator",
|
||||||
CmdIBDBlockLocatorHighestHash: "IBDBlockLocatorHighestHash",
|
CmdIBDBlockLocatorHighestHash: "IBDBlockLocatorHighestHash",
|
||||||
|
CmdIBDBlockLocatorHighestHashNotFound: "IBDBlockLocatorHighestHashNotFound",
|
||||||
CmdBlockHeaders: "BlockHeaders",
|
CmdBlockHeaders: "BlockHeaders",
|
||||||
CmdRequestNextPruningPointUTXOSetChunk: "RequestNextPruningPointUTXOSetChunk",
|
CmdRequestNextPruningPointUTXOSetChunk: "RequestNextPruningPointUTXOSetChunk",
|
||||||
CmdDonePruningPointUTXOSetChunks: "DonePruningPointUTXOSetChunks",
|
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 {
|
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)
|
"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("IBD started with peer %s and highHash %s", flow.peer, highHash)
|
||||||
|
|
||||||
log.Debugf("Syncing headers up to %s", highHash)
|
log.Debugf("Syncing headers up to %s", highHash)
|
||||||
err := flow.syncHeaders(highHash)
|
headersSynced, err := flow.syncHeaders(highHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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("Finished syncing headers up to %s", highHash)
|
||||||
|
|
||||||
log.Debugf("Syncing the current pruning point UTXO set")
|
log.Debugf("Syncing the current pruning point UTXO set")
|
||||||
@ -55,47 +59,61 @@ func (flow *handleRelayInvsFlow) runIBDIfNotRunning(highHash *externalapi.Domain
|
|||||||
return nil
|
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)
|
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 {
|
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)
|
log.Debugf("Found highest shared chain block %s with peer %s", highestSharedBlockHash, flow.peer)
|
||||||
|
|
||||||
err = flow.downloadHeaders(highestSharedBlockHash, highHash)
|
err = flow.downloadHeaders(highestSharedBlockHash, highHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the highHash has not been received, the peer is misbehaving
|
// If the highHash has not been received, the peer is misbehaving
|
||||||
highHashBlockInfo, err := flow.Domain().Consensus().GetBlockInfo(highHash)
|
highHashBlockInfo, err := flow.Domain().Consensus().GetBlockInfo(highHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
if !highHashBlockInfo.Exists {
|
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)
|
"highHash header %s from peer %s during header download", highHash, flow.peer)
|
||||||
}
|
}
|
||||||
log.Debugf("Headers downloaded from peer %s", 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)
|
log.Debugf("Sending a blockLocator to %s between pruning point and headers selected tip", flow.peer)
|
||||||
blockLocator, err := flow.Domain().Consensus().CreateFullHeadersSelectedChainBlockLocator()
|
blockLocator, err := flow.Domain().Consensus().CreateFullHeadersSelectedChainBlockLocator()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
highestHash, err := flow.fetchHighestHash(targetHash, blockLocator)
|
highestHash, highestHashFound, err := flow.fetchHighestHash(targetHash, blockLocator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, false, err
|
||||||
|
}
|
||||||
|
if !highestHashFound {
|
||||||
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
highestHashIndex, err := flow.findHighestHashIndex(highestHash, blockLocator)
|
highestHashIndex, err := flow.findHighestHashIndex(highestHash, blockLocator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if highestHashIndex == 0 ||
|
if highestHashIndex == 0 ||
|
||||||
@ -104,7 +122,7 @@ func (flow *handleRelayInvsFlow) findHighestSharedBlockHash(targetHash *external
|
|||||||
// an endless loop, we explicitly stop the loop in such situation.
|
// an endless loop, we explicitly stop the loop in such situation.
|
||||||
(len(blockLocator) == 2 && highestHashIndex == 1) {
|
(len(blockLocator) == 2 && highestHashIndex == 1) {
|
||||||
|
|
||||||
return highestHash, nil
|
return highestHash, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
locatorHashAboveHighestHash := highestHash
|
locatorHashAboveHighestHash := highestHash
|
||||||
@ -114,7 +132,7 @@ func (flow *handleRelayInvsFlow) findHighestSharedBlockHash(targetHash *external
|
|||||||
|
|
||||||
blockLocator, err = flow.nextBlockLocator(highestHash, locatorHashAboveHighestHash)
|
blockLocator, err = flow.nextBlockLocator(highestHash, locatorHashAboveHighestHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,27 +177,35 @@ func (flow *handleRelayInvsFlow) findHighestHashIndex(
|
|||||||
return highestHashIndex, nil
|
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(
|
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)
|
ibdBlockLocatorMessage := appmessage.NewMsgIBDBlockLocator(targetHash, blockLocator)
|
||||||
err := flow.outgoingRoute.Enqueue(ibdBlockLocatorMessage)
|
err := flow.outgoingRoute.Enqueue(ibdBlockLocatorMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
message, err := flow.dequeueIncomingMessageAndSkipInvs(common.DefaultTimeout)
|
message, err := flow.dequeueIncomingMessageAndSkipInvs(common.DefaultTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
ibdBlockLocatorHighestHashMessage, ok := message.(*appmessage.MsgIBDBlockLocatorHighestHash)
|
switch message := message.(type) {
|
||||||
if !ok {
|
case *appmessage.MsgIBDBlockLocatorHighestHash:
|
||||||
return nil, protocolerrors.Errorf(true, "received unexpected message type. "+
|
highestHash := message.HighestHash
|
||||||
"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)
|
log.Debugf("The highest hash the peer %s knows is %s", flow.peer, highestHash)
|
||||||
|
|
||||||
return highestHash, nil
|
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())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (flow *handleRelayInvsFlow) downloadHeaders(highestSharedBlockHash *externalapi.DomainHash,
|
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()
|
outgoingRoute := router.OutgoingRoute()
|
||||||
|
|
||||||
return []*flow{
|
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{
|
m.registerFlow("HandleRelayInvs", router, []appmessage.MessageCommand{
|
||||||
appmessage.CmdInvRelayBlock, appmessage.CmdBlock, appmessage.CmdBlockLocator, appmessage.CmdIBDBlock,
|
appmessage.CmdInvRelayBlock, appmessage.CmdBlock, appmessage.CmdBlockLocator, appmessage.CmdIBDBlock,
|
||||||
appmessage.CmdDoneHeaders, appmessage.CmdUnexpectedPruningPoint, appmessage.CmdPruningPointUTXOSetChunk,
|
appmessage.CmdDoneHeaders, appmessage.CmdUnexpectedPruningPoint, appmessage.CmdPruningPointUTXOSetChunk,
|
||||||
appmessage.CmdBlockHeaders, appmessage.CmdPruningPointHash, appmessage.CmdIBDBlockLocatorHighestHash,
|
appmessage.CmdBlockHeaders, appmessage.CmdPruningPointHash, appmessage.CmdIBDBlockLocatorHighestHash,
|
||||||
appmessage.CmdDonePruningPointUTXOSetChunks},
|
appmessage.CmdIBDBlockLocatorHighestHashNotFound, appmessage.CmdDonePruningPointUTXOSetChunks},
|
||||||
isStopping, errChan, func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
isStopping, errChan, func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
||||||
return blockrelay.HandleRelayInvs(m.context, incomingRoute,
|
return blockrelay.HandleRelayInvs(m.context, incomingRoute,
|
||||||
outgoingRoute, peer)
|
outgoingRoute, peer)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -39,6 +39,7 @@ message KaspadMessage {
|
|||||||
BlockHeadersMessage blockHeaders = 32;
|
BlockHeadersMessage blockHeaders = 32;
|
||||||
RequestNextPruningPointUtxoSetChunkMessage requestNextPruningPointUtxoSetChunk = 33;
|
RequestNextPruningPointUtxoSetChunkMessage requestNextPruningPointUtxoSetChunk = 33;
|
||||||
DonePruningPointUtxoSetChunksMessage donePruningPointUtxoSetChunks = 34;
|
DonePruningPointUtxoSetChunksMessage donePruningPointUtxoSetChunks = 34;
|
||||||
|
IbdBlockLocatorHighestHashNotFoundMessage ibdBlockLocatorHighestHashNotFound = 35;
|
||||||
|
|
||||||
GetCurrentNetworkRequestMessage getCurrentNetworkRequest = 1001;
|
GetCurrentNetworkRequestMessage getCurrentNetworkRequest = 1001;
|
||||||
GetCurrentNetworkResponseMessage getCurrentNetworkResponse = 1002;
|
GetCurrentNetworkResponseMessage getCurrentNetworkResponse = 1002;
|
||||||
|
@ -2162,6 +2162,44 @@ func (x *IbdBlockLocatorHighestHashMessage) GetHighestHash() *Hash {
|
|||||||
return nil
|
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 {
|
type BlockHeadersMessage struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
@ -2173,7 +2211,7 @@ type BlockHeadersMessage struct {
|
|||||||
func (x *BlockHeadersMessage) Reset() {
|
func (x *BlockHeadersMessage) Reset() {
|
||||||
*x = BlockHeadersMessage{}
|
*x = BlockHeadersMessage{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_p2p_proto_msgTypes[40]
|
mi := &file_p2p_proto_msgTypes[41]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -2186,7 +2224,7 @@ func (x *BlockHeadersMessage) String() string {
|
|||||||
func (*BlockHeadersMessage) ProtoMessage() {}
|
func (*BlockHeadersMessage) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *BlockHeadersMessage) ProtoReflect() protoreflect.Message {
|
func (x *BlockHeadersMessage) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_p2p_proto_msgTypes[40]
|
mi := &file_p2p_proto_msgTypes[41]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -2199,7 +2237,7 @@ func (x *BlockHeadersMessage) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use BlockHeadersMessage.ProtoReflect.Descriptor instead.
|
// Deprecated: Use BlockHeadersMessage.ProtoReflect.Descriptor instead.
|
||||||
func (*BlockHeadersMessage) Descriptor() ([]byte, []int) {
|
func (*BlockHeadersMessage) Descriptor() ([]byte, []int) {
|
||||||
return file_p2p_proto_rawDescGZIP(), []int{40}
|
return file_p2p_proto_rawDescGZIP(), []int{41}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *BlockHeadersMessage) GetBlockHeaders() []*BlockHeaderMessage {
|
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,
|
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,
|
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,
|
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,
|
0x22, 0x2b, 0x0a, 0x29, 0x49, 0x62, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4c, 0x6f, 0x63, 0x61,
|
||||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
|
0x74, 0x6f, 0x72, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x48, 0x61, 0x73, 0x68, 0x4e, 0x6f,
|
||||||
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e,
|
0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x58, 0x0a,
|
||||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48,
|
0x13, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x4d, 0x65, 0x73,
|
||||||
0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0c, 0x62, 0x6c,
|
0x73, 0x61, 0x67, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61,
|
||||||
0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x42, 0x26, 0x5a, 0x24, 0x67, 0x69,
|
0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f,
|
||||||
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x6e, 0x65,
|
0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64,
|
||||||
0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69,
|
0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
|
||||||
0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
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 (
|
var (
|
||||||
@ -2484,7 +2525,7 @@ func file_p2p_proto_rawDescGZIP() []byte {
|
|||||||
return file_p2p_proto_rawDescData
|
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{}{
|
var file_p2p_proto_goTypes = []interface{}{
|
||||||
(*RequestAddressesMessage)(nil), // 0: protowire.RequestAddressesMessage
|
(*RequestAddressesMessage)(nil), // 0: protowire.RequestAddressesMessage
|
||||||
(*AddressesMessage)(nil), // 1: protowire.AddressesMessage
|
(*AddressesMessage)(nil), // 1: protowire.AddressesMessage
|
||||||
@ -2526,7 +2567,8 @@ var file_p2p_proto_goTypes = []interface{}{
|
|||||||
(*PruningPointHashMessage)(nil), // 37: protowire.PruningPointHashMessage
|
(*PruningPointHashMessage)(nil), // 37: protowire.PruningPointHashMessage
|
||||||
(*IbdBlockLocatorMessage)(nil), // 38: protowire.IbdBlockLocatorMessage
|
(*IbdBlockLocatorMessage)(nil), // 38: protowire.IbdBlockLocatorMessage
|
||||||
(*IbdBlockLocatorHighestHashMessage)(nil), // 39: protowire.IbdBlockLocatorHighestHashMessage
|
(*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{
|
var file_p2p_proto_depIdxs = []int32{
|
||||||
3, // 0: protowire.RequestAddressesMessage.subnetworkId:type_name -> protowire.SubnetworkId
|
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{} {
|
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 {
|
switch v := v.(*BlockHeadersMessage); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
@ -3079,7 +3133,7 @@ func file_p2p_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_p2p_proto_rawDesc,
|
RawDescriptor: file_p2p_proto_rawDesc,
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 41,
|
NumMessages: 42,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 0,
|
NumServices: 0,
|
||||||
},
|
},
|
||||||
|
@ -195,6 +195,9 @@ message IbdBlockLocatorHighestHashMessage {
|
|||||||
Hash highestHash = 1;
|
Hash highestHash = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message IbdBlockLocatorHighestHashNotFoundMessage {
|
||||||
|
}
|
||||||
|
|
||||||
message BlockHeadersMessage {
|
message BlockHeadersMessage {
|
||||||
repeated BlockHeaderMessage blockHeaders = 1;
|
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 nil, err
|
||||||
}
|
}
|
||||||
return payload, nil
|
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:
|
case *appmessage.BlockHeadersMessage:
|
||||||
payload := new(KaspadMessage_BlockHeaders)
|
payload := new(KaspadMessage_BlockHeaders)
|
||||||
err := payload.fromAppMessage(message)
|
err := payload.fromAppMessage(message)
|
||||||
|
@ -16,7 +16,7 @@ func TestIBD(t *testing.T) {
|
|||||||
syncer, syncee, _, teardown := standardSetup(t)
|
syncer, syncee, _, teardown := standardSetup(t)
|
||||||
defer teardown()
|
defer teardown()
|
||||||
|
|
||||||
for i := 0; i < numBlocks-1; i++ {
|
for i := 0; i < numBlocks; i++ {
|
||||||
mineNextBlock(t, syncer)
|
mineNextBlock(t, syncer)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,10 +28,8 @@ func TestIBD(t *testing.T) {
|
|||||||
blockAddedWG.Done()
|
blockAddedWG.Done()
|
||||||
})
|
})
|
||||||
|
|
||||||
connect(t, syncer, syncee)
|
|
||||||
|
|
||||||
// We expect this to trigger IBD
|
// We expect this to trigger IBD
|
||||||
mineNextBlock(t, syncer)
|
connect(t, syncer, syncee)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-time.After(defaultTimeout):
|
case <-time.After(defaultTimeout):
|
||||||
@ -97,10 +95,8 @@ func TestIBDWithPruning(t *testing.T) {
|
|||||||
mineNextBlock(t, syncer)
|
mineNextBlock(t, syncer)
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(t, syncer, syncee)
|
|
||||||
|
|
||||||
// We expect this to trigger IBD
|
// We expect this to trigger IBD
|
||||||
mineNextBlock(t, syncer)
|
connect(t, syncer, syncee)
|
||||||
|
|
||||||
syncerBlockCountResponse, err := syncer.rpcClient.GetBlockCount()
|
syncerBlockCountResponse, err := syncer.rpcClient.GetBlockCount()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package integration
|
package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/app/appmessage"
|
"github.com/kaspanet/kaspad/app/appmessage"
|
||||||
@ -48,18 +49,17 @@ func TestVirtualSelectedParentChain(t *testing.T) {
|
|||||||
chain1TipHashString = minedBlockHashString
|
chain1TipHashString = minedBlockHashString
|
||||||
}
|
}
|
||||||
|
|
||||||
// In kaspad2, mine a different chain of `blockAmountToMine`
|
// In kaspad2, mine a different chain of `blockAmountToMine` + 1
|
||||||
// blocks over the genesis
|
// blocks over the genesis
|
||||||
for i := 0; i < blockAmountToMine; i++ {
|
var chain2Tip *externalapi.DomainBlock
|
||||||
mineNextBlock(t, kaspad2)
|
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)
|
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)
|
chain2TipHash := consensushashing.BlockHash(chain2Tip)
|
||||||
chain2TipHashString := chain2TipHash.String()
|
chain2TipHashString := chain2TipHash.String()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user