mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-11-28 08:11:08 +00:00
Just some name changes, put in a stand in emission amount, and started copying the algo from Karlsen. Not release worthy yet. Therefore Dev branch exists now. Also, for now this is for research purposes only. I got no clue what to build on top of Kaspa yet. Help would be appreciated for ideas and implementations.
96 lines
3.3 KiB
Go
96 lines
3.3 KiB
Go
package blockrelay
|
|
|
|
import (
|
|
"github.com/zoomy-network/zoomyd/app/appmessage"
|
|
"github.com/zoomy-network/zoomyd/app/protocol/peer"
|
|
"github.com/zoomy-network/zoomyd/app/protocol/protocolerrors"
|
|
"github.com/zoomy-network/zoomyd/domain"
|
|
"github.com/zoomy-network/zoomyd/domain/consensus/model/externalapi"
|
|
"github.com/zoomy-network/zoomyd/infrastructure/config"
|
|
"github.com/zoomy-network/zoomyd/infrastructure/network/netadapter/router"
|
|
"sort"
|
|
)
|
|
|
|
// RequestAnticoneContext is the interface for the context needed for the HandleRequestHeaders flow.
|
|
type RequestAnticoneContext interface {
|
|
Domain() domain.Domain
|
|
Config() *config.Config
|
|
}
|
|
|
|
type handleRequestAnticoneFlow struct {
|
|
RequestAnticoneContext
|
|
incomingRoute, outgoingRoute *router.Route
|
|
peer *peer.Peer
|
|
}
|
|
|
|
// HandleRequestAnticone handles RequestAnticone messages
|
|
func HandleRequestAnticone(context RequestAnticoneContext, incomingRoute *router.Route,
|
|
outgoingRoute *router.Route, peer *peer.Peer) error {
|
|
|
|
flow := &handleRequestAnticoneFlow{
|
|
RequestAnticoneContext: context,
|
|
incomingRoute: incomingRoute,
|
|
outgoingRoute: outgoingRoute,
|
|
peer: peer,
|
|
}
|
|
return flow.start()
|
|
}
|
|
|
|
func (flow *handleRequestAnticoneFlow) start() error {
|
|
for {
|
|
blockHash, contextHash, err := receiveRequestAnticone(flow.incomingRoute)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Debugf("Received requestAnticone with blockHash: %s, contextHash: %s", blockHash, contextHash)
|
|
log.Debugf("Getting past(%s) cap anticone(%s) for peer %s", contextHash, blockHash, flow.peer)
|
|
|
|
// GetAnticone is expected to be called by the syncee for getting the anticone of the header selected tip
|
|
// intersected by past of relayed block, and is thus expected to be bounded by mergeset limit since
|
|
// we relay blocks only if they enter virtual's mergeset. We add a 2 factor for possible sync gaps.
|
|
blockHashes, err := flow.Domain().Consensus().GetAnticone(blockHash, contextHash,
|
|
flow.Config().ActiveNetParams.MergeSetSizeLimit*2)
|
|
if err != nil {
|
|
return protocolerrors.Wrap(true, err, "Failed querying anticone")
|
|
}
|
|
log.Debugf("Got %d header hashes in past(%s) cap anticone(%s)", len(blockHashes), contextHash, blockHash)
|
|
|
|
blockHeaders := make([]*appmessage.MsgBlockHeader, len(blockHashes))
|
|
for i, blockHash := range blockHashes {
|
|
blockHeader, err := flow.Domain().Consensus().GetBlockHeader(blockHash)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
blockHeaders[i] = appmessage.DomainBlockHeaderToBlockHeader(blockHeader)
|
|
}
|
|
|
|
// We sort the headers in bottom-up topological order before sending
|
|
sort.Slice(blockHeaders, func(i, j int) bool {
|
|
return blockHeaders[i].BlueWork.Cmp(blockHeaders[j].BlueWork) < 0
|
|
})
|
|
|
|
blockHeadersMessage := appmessage.NewBlockHeadersMessage(blockHeaders)
|
|
err = flow.outgoingRoute.Enqueue(blockHeadersMessage)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgDoneHeaders())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
func receiveRequestAnticone(incomingRoute *router.Route) (blockHash *externalapi.DomainHash,
|
|
contextHash *externalapi.DomainHash, err error) {
|
|
|
|
message, err := incomingRoute.Dequeue()
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
msgRequestAnticone := message.(*appmessage.MsgRequestAnticone)
|
|
|
|
return msgRequestAnticone.BlockHash, msgRequestAnticone.ContextHash, nil
|
|
}
|