mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
[NOD-1525] Implement headers first ibd (#1017)
* [NOD-1525] Implement headers first IBD * [NOD-1525] Fix proto translators * [NOD-1525] Register missing flows * [NOD-1525] Rename SyncStateNormal->SyncStateRelay, simplifiy IBD peer selection code and get rid of panic in FinishIBD * [NOD-1525] Remove redundant methods from interface
This commit is contained in:
parent
31c5264430
commit
23c1ea6c31
@ -17,9 +17,9 @@ func DomainBlockToMsgBlock(domainBlock *externalapi.DomainBlock) *MsgBlock {
|
||||
}
|
||||
}
|
||||
|
||||
// DomainBlockHeaderToBlockHeader converts an externalapi.DomainBlockHeader to BlockHeader
|
||||
func DomainBlockHeaderToBlockHeader(domainBlockHeader *externalapi.DomainBlockHeader) *BlockHeader {
|
||||
return &BlockHeader{
|
||||
// DomainBlockHeaderToBlockHeader converts an externalapi.DomainBlockHeader to MsgBlockHeader
|
||||
func DomainBlockHeaderToBlockHeader(domainBlockHeader *externalapi.DomainBlockHeader) *MsgBlockHeader {
|
||||
return &MsgBlockHeader{
|
||||
Version: domainBlockHeader.Version,
|
||||
ParentHashes: domainBlockHeader.ParentHashes,
|
||||
HashMerkleRoot: &domainBlockHeader.HashMerkleRoot,
|
||||
@ -44,8 +44,8 @@ func MsgBlockToDomainBlock(msgBlock *MsgBlock) *externalapi.DomainBlock {
|
||||
}
|
||||
}
|
||||
|
||||
// BlockHeaderToDomainBlockHeader converts a BlockHeader to externalapi.DomainBlockHeader
|
||||
func BlockHeaderToDomainBlockHeader(blockHeader *BlockHeader) *externalapi.DomainBlockHeader {
|
||||
// BlockHeaderToDomainBlockHeader converts a MsgBlockHeader to externalapi.DomainBlockHeader
|
||||
func BlockHeaderToDomainBlockHeader(blockHeader *MsgBlockHeader) *externalapi.DomainBlockHeader {
|
||||
return &externalapi.DomainBlockHeader{
|
||||
Version: blockHeader.Version,
|
||||
ParentHashes: blockHeader.ParentHashes,
|
||||
|
@ -34,7 +34,7 @@ const (
|
||||
CmdVerAck
|
||||
CmdRequestAddresses
|
||||
CmdAddresses
|
||||
CmdRequestIBDBlocks
|
||||
CmdRequestHeaders
|
||||
CmdBlock
|
||||
CmdTx
|
||||
CmdPing
|
||||
@ -48,10 +48,15 @@ const (
|
||||
CmdInvTransaction
|
||||
CmdRequestTransactions
|
||||
CmdIBDBlock
|
||||
CmdRequestNextIBDBlocks
|
||||
CmdDoneIBDBlocks
|
||||
CmdDoneHeaders
|
||||
CmdTransactionNotFound
|
||||
CmdReject
|
||||
CmdHeader
|
||||
CmdRequestNextHeaders
|
||||
CmdRequestIBDRootUTXOSetAndBlock
|
||||
CmdIBDRootUTXOSetAndBlock
|
||||
CmdRequestIBDBlocks
|
||||
CmdIBDRootNotFound
|
||||
|
||||
// rpc
|
||||
CmdGetCurrentNetworkRequestMessage
|
||||
@ -107,28 +112,32 @@ const (
|
||||
|
||||
// ProtocolMessageCommandToString maps all MessageCommands to their string representation
|
||||
var ProtocolMessageCommandToString = map[MessageCommand]string{
|
||||
CmdVersion: "Version",
|
||||
CmdVerAck: "VerAck",
|
||||
CmdRequestAddresses: "RequestAddresses",
|
||||
CmdAddresses: "Addresses",
|
||||
CmdRequestIBDBlocks: "RequestBlocks",
|
||||
CmdBlock: "Block",
|
||||
CmdTx: "Tx",
|
||||
CmdPing: "Ping",
|
||||
CmdPong: "Pong",
|
||||
CmdRequestBlockLocator: "RequestBlockLocator",
|
||||
CmdBlockLocator: "BlockLocator",
|
||||
CmdSelectedTip: "SelectedTip",
|
||||
CmdRequestSelectedTip: "RequestSelectedTip",
|
||||
CmdInvRelayBlock: "InvRelayBlock",
|
||||
CmdRequestRelayBlocks: "RequestRelayBlocks",
|
||||
CmdInvTransaction: "InvTransaction",
|
||||
CmdRequestTransactions: "RequestTransactions",
|
||||
CmdIBDBlock: "IBDBlock",
|
||||
CmdRequestNextIBDBlocks: "RequestNextIBDBlocks",
|
||||
CmdDoneIBDBlocks: "DoneIBDBlocks",
|
||||
CmdTransactionNotFound: "TransactionNotFound",
|
||||
CmdReject: "Reject",
|
||||
CmdVersion: "Version",
|
||||
CmdVerAck: "VerAck",
|
||||
CmdRequestAddresses: "RequestAddresses",
|
||||
CmdAddresses: "Addresses",
|
||||
CmdRequestHeaders: "RequestBlocks",
|
||||
CmdBlock: "Block",
|
||||
CmdTx: "Tx",
|
||||
CmdPing: "Ping",
|
||||
CmdPong: "Pong",
|
||||
CmdRequestBlockLocator: "RequestBlockLocator",
|
||||
CmdBlockLocator: "BlockLocator",
|
||||
CmdSelectedTip: "SelectedTip",
|
||||
CmdRequestSelectedTip: "RequestSelectedTip",
|
||||
CmdInvRelayBlock: "InvRelayBlock",
|
||||
CmdRequestRelayBlocks: "RequestRelayBlocks",
|
||||
CmdInvTransaction: "InvTransaction",
|
||||
CmdRequestTransactions: "RequestTransactions",
|
||||
CmdIBDBlock: "IBDBlock",
|
||||
CmdDoneHeaders: "DoneIBDBlocks",
|
||||
CmdTransactionNotFound: "TransactionNotFound",
|
||||
CmdReject: "Reject",
|
||||
CmdHeader: "Header",
|
||||
CmdRequestNextHeaders: "RequestNextHeaders",
|
||||
CmdRequestIBDRootUTXOSetAndBlock: "RequestPruningUTXOSetAndBlock",
|
||||
CmdIBDRootUTXOSetAndBlock: "IBDRootUTXOSetAndBlock",
|
||||
CmdIBDRootNotFound: "IBDRootNotFound",
|
||||
}
|
||||
|
||||
// RPCMessageCommandToString maps all MessageCommands to their string representation
|
||||
|
22
app/appmessage/p2p_ibdrootnotfound.go
Normal file
22
app/appmessage/p2p_ibdrootnotfound.go
Normal file
@ -0,0 +1,22 @@
|
||||
package appmessage
|
||||
|
||||
// MsgIBDRootNotFound implements the Message interface and represents a kaspa
|
||||
// IBDRootNotFound message. It is used to notify the IBD root that was requested
|
||||
// by other peer was not found.
|
||||
//
|
||||
// This message has no payload.
|
||||
type MsgIBDRootNotFound struct {
|
||||
baseMessage
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
// of the Message interface implementation.
|
||||
func (msg *MsgIBDRootNotFound) Command() MessageCommand {
|
||||
return CmdDoneHeaders
|
||||
}
|
||||
|
||||
// NewMsgIBDRootNotFound returns a new kaspa IBDRootNotFound message that conforms to the
|
||||
// Message interface.
|
||||
func NewMsgIBDRootNotFound() *MsgDoneHeaders {
|
||||
return &MsgDoneHeaders{}
|
||||
}
|
@ -40,7 +40,7 @@ type TxLoc struct {
|
||||
// response to a getdata message (MsgGetData) for a given block hash.
|
||||
type MsgBlock struct {
|
||||
baseMessage
|
||||
Header BlockHeader
|
||||
Header MsgBlockHeader
|
||||
Transactions []*MsgTx
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ func (msg *MsgBlock) ConvertToPartial(subnetworkID *externalapi.DomainSubnetwork
|
||||
|
||||
// NewMsgBlock returns a new kaspa block message that conforms to the
|
||||
// Message interface. See MsgBlock for details.
|
||||
func NewMsgBlock(blockHeader *BlockHeader) *MsgBlock {
|
||||
func NewMsgBlock(blockHeader *MsgBlockHeader) *MsgBlock {
|
||||
return &MsgBlock{
|
||||
Header: *blockHeader,
|
||||
Transactions: make([]*MsgTx, 0, defaultTransactionAlloc),
|
||||
|
@ -129,7 +129,7 @@ func TestConvertToPartial(t *testing.T) {
|
||||
|
||||
// blockOne is the first block in the mainnet block DAG.
|
||||
var blockOne = MsgBlock{
|
||||
Header: BlockHeader{
|
||||
Header: MsgBlockHeader{
|
||||
Version: 1,
|
||||
ParentHashes: []*externalapi.DomainHash{mainnetGenesisHash, simnetGenesisHash},
|
||||
HashMerkleRoot: mainnetGenesisMerkleRoot,
|
||||
|
@ -31,9 +31,11 @@ const MaxNumParentBlocks = 255
|
||||
// BaseBlockHeaderPayload + up to MaxNumParentBlocks hashes of parent blocks
|
||||
const MaxBlockHeaderPayload = BaseBlockHeaderPayload + (MaxNumParentBlocks * externalapi.DomainHashSize)
|
||||
|
||||
// BlockHeader defines information about a block and is used in the kaspa
|
||||
// MsgBlockHeader defines information about a block and is used in the kaspa
|
||||
// block (MsgBlock) and headers (MsgHeader) messages.
|
||||
type BlockHeader struct {
|
||||
type MsgBlockHeader struct {
|
||||
baseMessage
|
||||
|
||||
// Version of the block. This is not the same as the protocol version.
|
||||
Version int32
|
||||
|
||||
@ -61,7 +63,7 @@ type BlockHeader struct {
|
||||
}
|
||||
|
||||
// NumParentBlocks return the number of entries in ParentHashes
|
||||
func (h *BlockHeader) NumParentBlocks() byte {
|
||||
func (h *MsgBlockHeader) NumParentBlocks() byte {
|
||||
numParents := len(h.ParentHashes)
|
||||
if numParents > math.MaxUint8 {
|
||||
panic(errors.Errorf("number of parents is %d, which is more than one byte can fit", numParents))
|
||||
@ -70,24 +72,30 @@ func (h *BlockHeader) NumParentBlocks() byte {
|
||||
}
|
||||
|
||||
// BlockHash computes the block identifier hash for the given block header.
|
||||
func (h *BlockHeader) BlockHash() *externalapi.DomainHash {
|
||||
func (h *MsgBlockHeader) BlockHash() *externalapi.DomainHash {
|
||||
return consensusserialization.HeaderHash(BlockHeaderToDomainBlockHeader(h))
|
||||
}
|
||||
|
||||
// IsGenesis returns true iff this block is a genesis block
|
||||
func (h *BlockHeader) IsGenesis() bool {
|
||||
func (h *MsgBlockHeader) IsGenesis() bool {
|
||||
return h.NumParentBlocks() == 0
|
||||
}
|
||||
|
||||
// NewBlockHeader returns a new BlockHeader using the provided version, previous
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
// of the Message interface implementation.
|
||||
func (h *MsgBlockHeader) Command() MessageCommand {
|
||||
return CmdHeader
|
||||
}
|
||||
|
||||
// NewBlockHeader returns a new MsgBlockHeader using the provided version, previous
|
||||
// block hash, hash merkle root, accepted ID merkle root, difficulty bits, and nonce used to generate the
|
||||
// block with defaults or calclulated values for the remaining fields.
|
||||
func NewBlockHeader(version int32, parentHashes []*externalapi.DomainHash, hashMerkleRoot *externalapi.DomainHash,
|
||||
acceptedIDMerkleRoot *externalapi.DomainHash, utxoCommitment *externalapi.DomainHash, bits uint32, nonce uint64) *BlockHeader {
|
||||
acceptedIDMerkleRoot *externalapi.DomainHash, utxoCommitment *externalapi.DomainHash, bits uint32, nonce uint64) *MsgBlockHeader {
|
||||
|
||||
// Limit the timestamp to one millisecond precision since the protocol
|
||||
// doesn't support better.
|
||||
return &BlockHeader{
|
||||
return &MsgBlockHeader{
|
||||
Version: version,
|
||||
ParentHashes: parentHashes,
|
||||
HashMerkleRoot: hashMerkleRoot,
|
@ -14,7 +14,7 @@ import (
|
||||
"github.com/kaspanet/kaspad/util/random"
|
||||
)
|
||||
|
||||
// TestBlockHeader tests the BlockHeader API.
|
||||
// TestBlockHeader tests the MsgBlockHeader API.
|
||||
func TestBlockHeader(t *testing.T) {
|
||||
nonce, err := random.Uint64()
|
||||
if err != nil {
|
||||
@ -52,7 +52,7 @@ func TestIsGenesis(t *testing.T) {
|
||||
bits := uint32(0x1d00ffff)
|
||||
timestamp := mstime.UnixMilliseconds(0x495fab29000)
|
||||
|
||||
baseBlockHdr := &BlockHeader{
|
||||
baseBlockHdr := &MsgBlockHeader{
|
||||
Version: 1,
|
||||
ParentHashes: []*externalapi.DomainHash{mainnetGenesisHash, simnetGenesisHash},
|
||||
HashMerkleRoot: mainnetGenesisMerkleRoot,
|
||||
@ -60,7 +60,7 @@ func TestIsGenesis(t *testing.T) {
|
||||
Bits: bits,
|
||||
Nonce: nonce,
|
||||
}
|
||||
genesisBlockHdr := &BlockHeader{
|
||||
genesisBlockHdr := &MsgBlockHeader{
|
||||
Version: 1,
|
||||
ParentHashes: []*externalapi.DomainHash{},
|
||||
HashMerkleRoot: mainnetGenesisMerkleRoot,
|
||||
@ -70,8 +70,8 @@ func TestIsGenesis(t *testing.T) {
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in *BlockHeader // Block header to encode
|
||||
isGenesis bool // Expected result for call of .IsGenesis
|
||||
in *MsgBlockHeader // Block header to encode
|
||||
isGenesis bool // Expected result for call of .IsGenesis
|
||||
}{
|
||||
{genesisBlockHdr, true},
|
||||
{baseBlockHdr, false},
|
||||
@ -81,7 +81,7 @@ func TestIsGenesis(t *testing.T) {
|
||||
for i, test := range tests {
|
||||
isGenesis := test.in.IsGenesis()
|
||||
if isGenesis != test.isGenesis {
|
||||
t.Errorf("BlockHeader.IsGenesis: #%d got: %t, want: %t",
|
||||
t.Errorf("MsgBlockHeader.IsGenesis: #%d got: %t, want: %t",
|
||||
i, isGenesis, test.isGenesis)
|
||||
}
|
||||
}
|
22
app/appmessage/p2p_msgdoneheaders.go
Normal file
22
app/appmessage/p2p_msgdoneheaders.go
Normal file
@ -0,0 +1,22 @@
|
||||
package appmessage
|
||||
|
||||
// MsgDoneHeaders implements the Message interface and represents a kaspa
|
||||
// DoneHeaders message. It is used to notify the IBD syncing peer that the
|
||||
// syncer sent all the requested headers.
|
||||
//
|
||||
// This message has no payload.
|
||||
type MsgDoneHeaders struct {
|
||||
baseMessage
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
// of the Message interface implementation.
|
||||
func (msg *MsgDoneHeaders) Command() MessageCommand {
|
||||
return CmdDoneHeaders
|
||||
}
|
||||
|
||||
// NewMsgDoneHeaders returns a new kaspa DoneIBDBlocks message that conforms to the
|
||||
// Message interface.
|
||||
func NewMsgDoneHeaders() *MsgDoneHeaders {
|
||||
return &MsgDoneHeaders{}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package appmessage
|
||||
|
||||
// MsgDoneIBDBlocks implements the Message interface and represents a kaspa
|
||||
// DoneIBDBlocks message. It is used to notify the IBD syncing peer that the
|
||||
// syncer sent all the requested blocks.
|
||||
//
|
||||
// This message has no payload.
|
||||
type MsgDoneIBDBlocks struct {
|
||||
baseMessage
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
// of the Message interface implementation.
|
||||
func (msg *MsgDoneIBDBlocks) Command() MessageCommand {
|
||||
return CmdDoneIBDBlocks
|
||||
}
|
||||
|
||||
// NewMsgDoneIBDBlocks returns a new kaspa DoneIBDBlocks message that conforms to the
|
||||
// Message interface.
|
||||
func NewMsgDoneIBDBlocks() *MsgDoneIBDBlocks {
|
||||
return &MsgDoneIBDBlocks{}
|
||||
}
|
23
app/appmessage/p2p_msgibdrootutxosetandblock.go
Normal file
23
app/appmessage/p2p_msgibdrootutxosetandblock.go
Normal file
@ -0,0 +1,23 @@
|
||||
package appmessage
|
||||
|
||||
// MsgIBDRootUTXOSetAndBlock implements the Message interface and represents a kaspa
|
||||
// IBDRootUTXOSetAndBlock message. It is used to answer RequestIBDRootUTXOSetAndBlock messages.
|
||||
type MsgIBDRootUTXOSetAndBlock struct {
|
||||
baseMessage
|
||||
UTXOSet []byte
|
||||
Block *MsgBlock
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
// of the Message interface implementation.
|
||||
func (msg *MsgIBDRootUTXOSetAndBlock) Command() MessageCommand {
|
||||
return CmdRequestIBDRootUTXOSetAndBlock
|
||||
}
|
||||
|
||||
// NewMsgIBDRootUTXOSetAndBlock returns a new MsgIBDRootUTXOSetAndBlock.
|
||||
func NewMsgIBDRootUTXOSetAndBlock(utxoSet []byte, block *MsgBlock) *MsgIBDRootUTXOSetAndBlock {
|
||||
return &MsgIBDRootUTXOSetAndBlock{
|
||||
UTXOSet: utxoSet,
|
||||
Block: block,
|
||||
}
|
||||
}
|
34
app/appmessage/p2p_msgrequestheaders.go
Normal file
34
app/appmessage/p2p_msgrequestheaders.go
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2013-2016 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package appmessage
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
// MsgRequestHeaders implements the Message interface and represents a kaspa
|
||||
// RequestHeaders message. It is used to request a list of blocks starting after the
|
||||
// low hash and until the high hash.
|
||||
type MsgRequestHeaders struct {
|
||||
baseMessage
|
||||
LowHash *externalapi.DomainHash
|
||||
HighHash *externalapi.DomainHash
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
// of the Message interface implementation.
|
||||
func (msg *MsgRequestHeaders) Command() MessageCommand {
|
||||
return CmdRequestHeaders
|
||||
}
|
||||
|
||||
// NewMsgRequstHeaders returns a new kaspa RequestHeaders message that conforms to the
|
||||
// Message interface using the passed parameters and defaults for the remaining
|
||||
// fields.
|
||||
func NewMsgRequstHeaders(lowHash, highHash *externalapi.DomainHash) *MsgRequestHeaders {
|
||||
return &MsgRequestHeaders{
|
||||
LowHash: lowHash,
|
||||
HighHash: highHash,
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
|
||||
)
|
||||
|
||||
// TestRequstIBDBlocks tests the MsgRequestIBDBlocks API.
|
||||
// TestRequstIBDBlocks tests the MsgRequestHeaders API.
|
||||
func TestRequstIBDBlocks(t *testing.T) {
|
||||
hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
|
||||
lowHash, err := hashes.FromString(hashStr)
|
||||
@ -25,16 +25,16 @@ func TestRequstIBDBlocks(t *testing.T) {
|
||||
}
|
||||
|
||||
// Ensure we get the same data back out.
|
||||
msg := NewMsgRequstIBDBlocks(lowHash, highHash)
|
||||
msg := NewMsgRequstHeaders(lowHash, highHash)
|
||||
if *msg.HighHash != *highHash {
|
||||
t.Errorf("NewMsgRequstIBDBlocks: wrong high hash - got %v, want %v",
|
||||
t.Errorf("NewMsgRequstHeaders: wrong high hash - got %v, want %v",
|
||||
msg.HighHash, highHash)
|
||||
}
|
||||
|
||||
// Ensure the command is expected value.
|
||||
wantCmd := MessageCommand(4)
|
||||
if cmd := msg.Command(); cmd != wantCmd {
|
||||
t.Errorf("NewMsgRequstIBDBlocks: wrong command - got %v want %v",
|
||||
t.Errorf("NewMsgRequstHeaders: wrong command - got %v want %v",
|
||||
cmd, wantCmd)
|
||||
}
|
||||
}
|
@ -1,20 +1,19 @@
|
||||
// Copyright (c) 2013-2016 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package appmessage
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
// MaxRequestIBDBlocksHashes is the maximum number of hashes that can
|
||||
// be in a single RequestIBDBlocks message.
|
||||
const MaxRequestIBDBlocksHashes = MaxInvPerMsg
|
||||
|
||||
// MsgRequestIBDBlocks implements the Message interface and represents a kaspa
|
||||
// RequestIBDBlocks message. It is used to request a list of blocks starting after the
|
||||
// low hash and until the high hash.
|
||||
// RequestIBDBlocks message. It is used to request blocks as part of the IBD
|
||||
// protocol.
|
||||
type MsgRequestIBDBlocks struct {
|
||||
baseMessage
|
||||
LowHash *externalapi.DomainHash
|
||||
HighHash *externalapi.DomainHash
|
||||
Hashes []*externalapi.DomainHash
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
@ -23,12 +22,9 @@ func (msg *MsgRequestIBDBlocks) Command() MessageCommand {
|
||||
return CmdRequestIBDBlocks
|
||||
}
|
||||
|
||||
// NewMsgRequstIBDBlocks returns a new kaspa RequestIBDBlocks message that conforms to the
|
||||
// Message interface using the passed parameters and defaults for the remaining
|
||||
// fields.
|
||||
func NewMsgRequstIBDBlocks(lowHash, highHash *externalapi.DomainHash) *MsgRequestIBDBlocks {
|
||||
// NewMsgRequestIBDBlocks returns a new MsgRequestIBDBlocks.
|
||||
func NewMsgRequestIBDBlocks(hashes []*externalapi.DomainHash) *MsgRequestIBDBlocks {
|
||||
return &MsgRequestIBDBlocks{
|
||||
LowHash: lowHash,
|
||||
HighHash: highHash,
|
||||
Hashes: hashes,
|
||||
}
|
||||
}
|
||||
|
26
app/appmessage/p2p_msgrequestibdrootutxosetandblock.go
Normal file
26
app/appmessage/p2p_msgrequestibdrootutxosetandblock.go
Normal file
@ -0,0 +1,26 @@
|
||||
package appmessage
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
// MsgRequestIBDRootUTXOSetAndBlock implements the Message interface and represents a kaspa
|
||||
// RequestIBDRootUTXOSetAndBlock message. It is used to request the UTXO set and block body
|
||||
// of the IBD root block.
|
||||
type MsgRequestIBDRootUTXOSetAndBlock struct {
|
||||
baseMessage
|
||||
IBDRoot *externalapi.DomainHash
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
// of the Message interface implementation.
|
||||
func (msg *MsgRequestIBDRootUTXOSetAndBlock) Command() MessageCommand {
|
||||
return CmdRequestIBDRootUTXOSetAndBlock
|
||||
}
|
||||
|
||||
// NewMsgRequestIBDRootUTXOSetAndBlock returns a new MsgRequestIBDRootUTXOSetAndBlock.
|
||||
func NewMsgRequestIBDRootUTXOSetAndBlock(ibdRoot *externalapi.DomainHash) *MsgRequestIBDRootUTXOSetAndBlock {
|
||||
return &MsgRequestIBDRootUTXOSetAndBlock{
|
||||
IBDRoot: ibdRoot,
|
||||
}
|
||||
}
|
22
app/appmessage/p2p_msgrequestnextheaders.go
Normal file
22
app/appmessage/p2p_msgrequestnextheaders.go
Normal file
@ -0,0 +1,22 @@
|
||||
package appmessage
|
||||
|
||||
// MsgRequestNextHeaders implements the Message interface and represents a kaspa
|
||||
// RequestNextHeaders message. It is used to notify the IBD syncer peer to send
|
||||
// more headers.
|
||||
//
|
||||
// This message has no payload.
|
||||
type MsgRequestNextHeaders struct {
|
||||
baseMessage
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
// of the Message interface implementation.
|
||||
func (msg *MsgRequestNextHeaders) Command() MessageCommand {
|
||||
return CmdRequestNextHeaders
|
||||
}
|
||||
|
||||
// NewMsgRequestNextHeaders returns a new kaspa RequestNextHeaders message that conforms to the
|
||||
// Message interface.
|
||||
func NewMsgRequestNextHeaders() *MsgRequestNextHeaders {
|
||||
return &MsgRequestNextHeaders{}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package appmessage
|
||||
|
||||
// MsgRequestNextIBDBlocks implements the Message interface and represents a kaspa
|
||||
// RequestNextIBDBlocks message. It is used to notify the IBD syncer peer to send
|
||||
// more blocks.
|
||||
//
|
||||
// This message has no payload.
|
||||
type MsgRequestNextIBDBlocks struct {
|
||||
baseMessage
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
// of the Message interface implementation.
|
||||
func (msg *MsgRequestNextIBDBlocks) Command() MessageCommand {
|
||||
return CmdRequestNextIBDBlocks
|
||||
}
|
||||
|
||||
// NewMsgRequestNextIBDBlocks returns a new kaspa RequestNextIBDBlocks message that conforms to the
|
||||
// Message interface.
|
||||
func NewMsgRequestNextIBDBlocks() *MsgRequestNextIBDBlocks {
|
||||
return &MsgRequestNextIBDBlocks{}
|
||||
}
|
@ -4,9 +4,9 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
// MsgRequestRelayBlocksHashes is the maximum number of hashes that can
|
||||
// MaxRequestRelayBlocksHashes is the maximum number of hashes that can
|
||||
// be in a single RequestRelayBlocks message.
|
||||
const MsgRequestRelayBlocksHashes = MaxInvPerMsg
|
||||
const MaxRequestRelayBlocksHashes = MaxInvPerMsg
|
||||
|
||||
// MsgRequestRelayBlocks implements the Message interface and represents a kaspa
|
||||
// RequestRelayBlocks message. It is used to request blocks as part of the block
|
||||
|
@ -1,6 +1,7 @@
|
||||
package flowcontext
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
@ -19,7 +20,16 @@ func (f *FlowContext) StartIBDIfRequired() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
peer, err := f.selectPeerForIBD()
|
||||
syncInfo, err := f.domain.Consensus().GetSyncInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if syncInfo.State == externalapi.SyncStateRelay {
|
||||
return nil
|
||||
}
|
||||
|
||||
peer, err := f.selectPeerForIBD(syncInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -42,20 +52,32 @@ func (f *FlowContext) IsInIBD() bool {
|
||||
|
||||
// selectPeerForIBD returns the first peer whose selected tip
|
||||
// hash is not in our DAG
|
||||
func (f *FlowContext) selectPeerForIBD() (*peerpkg.Peer, error) {
|
||||
func (f *FlowContext) selectPeerForIBD(syncInfo *externalapi.SyncInfo) (*peerpkg.Peer, error) {
|
||||
f.peersMutex.RLock()
|
||||
defer f.peersMutex.RUnlock()
|
||||
|
||||
for _, peer := range f.peers {
|
||||
peerSelectedTipHash := peer.SelectedTipHash()
|
||||
blockInfo, err := f.domain.Consensus().GetBlockInfo(peerSelectedTipHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !blockInfo.Exists {
|
||||
return peer, nil
|
||||
if syncInfo.State == externalapi.SyncStateHeadersFirst {
|
||||
for _, peer := range f.peers {
|
||||
peerSelectedTipHash := peer.SelectedTipHash()
|
||||
blockInfo, err := f.domain.Consensus().GetBlockInfo(peerSelectedTipHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if syncInfo.State == externalapi.SyncStateHeadersFirst {
|
||||
if !blockInfo.Exists {
|
||||
return peer, nil
|
||||
}
|
||||
} else {
|
||||
if blockInfo.Exists && blockInfo.BlockStatus == externalapi.StatusHeaderOnly &&
|
||||
blockInfo.IsBlockInHeaderPruningPointFuture {
|
||||
return peer, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ func (flow *handleRelayInvsFlow) readInv() (*appmessage.MsgInvRelayBlock, error)
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) requestBlocks(requestQueue *hashesQueueSet) error {
|
||||
numHashesToRequest := mathUtil.MinInt(appmessage.MsgRequestRelayBlocksHashes, requestQueue.len())
|
||||
numHashesToRequest := mathUtil.MinInt(appmessage.MaxRequestRelayBlocksHashes, requestQueue.len())
|
||||
hashesToRequest := requestQueue.dequeue(numHashesToRequest)
|
||||
|
||||
pendingBlocks := map[externalapi.DomainHash]struct{}{}
|
||||
|
49
app/protocol/flows/ibd/handle_ibd_block_requests.go
Normal file
49
app/protocol/flows/ibd/handle_ibd_block_requests.go
Normal file
@ -0,0 +1,49 @@
|
||||
package ibd
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
|
||||
"github.com/kaspanet/kaspad/domain"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// HandleIBDBlockRequestsContext is the interface for the context needed for the HandleIBDBlockRequests flow.
|
||||
type HandleIBDBlockRequestsContext interface {
|
||||
Domain() domain.Domain
|
||||
}
|
||||
|
||||
// HandleIBDBlockRequests listens to appmessage.MsgRequestRelayBlocks messages and sends
|
||||
// their corresponding blocks to the requesting peer.
|
||||
func HandleIBDBlockRequests(context HandleIBDBlockRequestsContext, incomingRoute *router.Route,
|
||||
outgoingRoute *router.Route) error {
|
||||
|
||||
for {
|
||||
message, err := incomingRoute.Dequeue()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msgRequestIBDBlocks := message.(*appmessage.MsgRequestIBDBlocks)
|
||||
for _, hash := range msgRequestIBDBlocks.Hashes {
|
||||
// Fetch the block from the database.
|
||||
blockInfo, err := context.Domain().Consensus().GetBlockInfo(hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !blockInfo.Exists {
|
||||
return protocolerrors.Errorf(true, "block %s not found", hash)
|
||||
}
|
||||
block, err := context.Domain().Consensus().GetBlock(hash)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to fetch requested block hash %s", hash)
|
||||
}
|
||||
|
||||
// TODO (Partial nodes): Convert block to partial block if needed
|
||||
|
||||
err = outgoingRoute.Enqueue(appmessage.DomainBlockToMsgBlock(block))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ import (
|
||||
|
||||
const ibdBatchSize = router.DefaultMaxMessages
|
||||
|
||||
// RequestIBDBlocksContext is the interface for the context needed for the HandleRequestIBDBlocks flow.
|
||||
// RequestIBDBlocksContext is the interface for the context needed for the HandleRequestHeaders flow.
|
||||
type RequestIBDBlocksContext interface {
|
||||
Domain() domain.Domain
|
||||
}
|
||||
@ -21,8 +21,8 @@ type handleRequestBlocksFlow struct {
|
||||
incomingRoute, outgoingRoute *router.Route
|
||||
}
|
||||
|
||||
// HandleRequestIBDBlocks handles getBlocks messages
|
||||
func HandleRequestIBDBlocks(context RequestIBDBlocksContext, incomingRoute *router.Route, outgoingRoute *router.Route) error {
|
||||
// HandleRequestHeaders handles RequestHeaders messages
|
||||
func HandleRequestHeaders(context RequestIBDBlocksContext, incomingRoute *router.Route, outgoingRoute *router.Route) error {
|
||||
flow := &handleRequestBlocksFlow{
|
||||
RequestIBDBlocksContext: context,
|
||||
incomingRoute: incomingRoute,
|
||||
@ -33,24 +33,24 @@ func HandleRequestIBDBlocks(context RequestIBDBlocksContext, incomingRoute *rout
|
||||
|
||||
func (flow *handleRequestBlocksFlow) start() error {
|
||||
for {
|
||||
lowHash, highHash, err := receiveRequestIBDBlocks(flow.incomingRoute)
|
||||
lowHash, highHash, err := receiveRequestHeaders(flow.incomingRoute)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgIBDBlocks, err := flow.buildMsgIBDBlocks(lowHash, highHash)
|
||||
msgHeaders, err := flow.buildMsgBlockHeaders(lowHash, highHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for offset := 0; offset < len(msgIBDBlocks); offset += ibdBatchSize {
|
||||
for offset := 0; offset < len(msgHeaders); offset += ibdBatchSize {
|
||||
end := offset + ibdBatchSize
|
||||
if end > len(msgIBDBlocks) {
|
||||
end = len(msgIBDBlocks)
|
||||
if end > len(msgHeaders) {
|
||||
end = len(msgHeaders)
|
||||
}
|
||||
|
||||
blocksToSend := msgIBDBlocks[offset:end]
|
||||
err = flow.sendMsgIBDBlocks(blocksToSend)
|
||||
blocksToSend := msgHeaders[offset:end]
|
||||
err = flow.sendHeaders(blocksToSend)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -66,56 +66,56 @@ func (flow *handleRequestBlocksFlow) start() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := message.(*appmessage.MsgRequestNextIBDBlocks); !ok {
|
||||
if _, ok := message.(*appmessage.MsgRequestNextHeaders); !ok {
|
||||
return protocolerrors.Errorf(true, "received unexpected message type. "+
|
||||
"expected: %s, got: %s", appmessage.CmdRequestNextIBDBlocks, message.Command())
|
||||
"expected: %s, got: %s", appmessage.CmdRequestNextHeaders, message.Command())
|
||||
}
|
||||
}
|
||||
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgDoneIBDBlocks())
|
||||
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgDoneHeaders())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func receiveRequestIBDBlocks(incomingRoute *router.Route) (lowHash *externalapi.DomainHash,
|
||||
func receiveRequestHeaders(incomingRoute *router.Route) (lowHash *externalapi.DomainHash,
|
||||
highHash *externalapi.DomainHash, err error) {
|
||||
|
||||
message, err := incomingRoute.Dequeue()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
msgRequestIBDBlocks := message.(*appmessage.MsgRequestIBDBlocks)
|
||||
msgRequestIBDBlocks := message.(*appmessage.MsgRequestHeaders)
|
||||
|
||||
return msgRequestIBDBlocks.LowHash, msgRequestIBDBlocks.HighHash, nil
|
||||
}
|
||||
|
||||
func (flow *handleRequestBlocksFlow) buildMsgIBDBlocks(lowHash *externalapi.DomainHash,
|
||||
highHash *externalapi.DomainHash) ([]*appmessage.MsgIBDBlock, error) {
|
||||
func (flow *handleRequestBlocksFlow) buildMsgBlockHeaders(lowHash *externalapi.DomainHash,
|
||||
highHash *externalapi.DomainHash) ([]*appmessage.MsgBlockHeader, error) {
|
||||
|
||||
blockHashes, err := flow.Domain().Consensus().GetHashesBetween(lowHash, highHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
const maxHashesInMsgIBDBlocks = appmessage.MaxInvPerMsg
|
||||
if len(blockHashes) > maxHashesInMsgIBDBlocks {
|
||||
blockHashes = blockHashes[:maxHashesInMsgIBDBlocks]
|
||||
const maxHeaders = appmessage.MaxInvPerMsg
|
||||
if len(blockHashes) > maxHeaders {
|
||||
blockHashes = blockHashes[:maxHeaders]
|
||||
}
|
||||
|
||||
msgIBDBlocks := make([]*appmessage.MsgIBDBlock, len(blockHashes))
|
||||
msgBlockHeaders := make([]*appmessage.MsgBlockHeader, len(blockHashes))
|
||||
for i, blockHash := range blockHashes {
|
||||
block, err := flow.Domain().Consensus().GetBlock(blockHash)
|
||||
header, err := flow.Domain().Consensus().GetBlockHeader(blockHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msgIBDBlocks[i] = appmessage.NewMsgIBDBlock(appmessage.DomainBlockToMsgBlock(block))
|
||||
msgBlockHeaders[i] = appmessage.DomainBlockHeaderToBlockHeader(header)
|
||||
}
|
||||
|
||||
return msgIBDBlocks, nil
|
||||
return msgBlockHeaders, nil
|
||||
}
|
||||
|
||||
func (flow *handleRequestBlocksFlow) sendMsgIBDBlocks(msgIBDBlocks []*appmessage.MsgIBDBlock) error {
|
||||
for _, msgIBDBlock := range msgIBDBlocks {
|
||||
func (flow *handleRequestBlocksFlow) sendHeaders(headers []*appmessage.MsgBlockHeader) error {
|
||||
for _, msgIBDBlock := range headers {
|
||||
err := flow.outgoingRoute.Enqueue(msgIBDBlock)
|
||||
if err != nil {
|
||||
return err
|
@ -0,0 +1,65 @@
|
||||
package ibd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/domain"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
)
|
||||
|
||||
// HandleRequestIBDRootUTXOSetAndBlockContext is the interface for the context needed for the HandleRequestIBDRootUTXOSetAndBlock flow.
|
||||
type HandleRequestIBDRootUTXOSetAndBlockContext interface {
|
||||
Domain() domain.Domain
|
||||
}
|
||||
|
||||
type handleRequestIBDRootUTXOSetAndBlockFlow struct {
|
||||
HandleRequestIBDRootUTXOSetAndBlockContext
|
||||
incomingRoute, outgoingRoute *router.Route
|
||||
}
|
||||
|
||||
// HandleRequestIBDRootUTXOSetAndBlock listens to appmessage.MsgRequestIBDRootUTXOSetAndBlock messages and sends
|
||||
// the IBD root UTXO set and block body.
|
||||
func HandleRequestIBDRootUTXOSetAndBlock(context HandleRequestIBDRootUTXOSetAndBlockContext, incomingRoute,
|
||||
outgoingRoute *router.Route) error {
|
||||
flow := &handleRequestIBDRootUTXOSetAndBlockFlow{
|
||||
HandleRequestIBDRootUTXOSetAndBlockContext: context,
|
||||
incomingRoute: incomingRoute,
|
||||
outgoingRoute: outgoingRoute,
|
||||
}
|
||||
|
||||
return flow.start()
|
||||
}
|
||||
|
||||
func (flow *handleRequestIBDRootUTXOSetAndBlockFlow) start() error {
|
||||
for {
|
||||
message, err := flow.incomingRoute.Dequeue()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msgRequestIBDRootUTXOSetAndBlock := message.(*appmessage.MsgRequestIBDRootUTXOSetAndBlock)
|
||||
|
||||
utxoSet, err := flow.Domain().Consensus().GetPruningPointUTXOSet(msgRequestIBDRootUTXOSetAndBlock.IBDRoot)
|
||||
if err != nil {
|
||||
if errors.Is(err, ruleerrors.ErrWrongPruningPointHash) {
|
||||
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgIBDRootNotFound())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
block, err := flow.Domain().Consensus().GetBlock(msgRequestIBDRootUTXOSetAndBlock.IBDRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgIBDRootUTXOSetAndBlock(utxoSet,
|
||||
appmessage.DomainBlockToMsgBlock(block)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
@ -53,8 +53,53 @@ func (flow *handleIBDFlow) start() error {
|
||||
|
||||
func (flow *handleIBDFlow) runIBD() error {
|
||||
flow.peer.WaitForIBDStart()
|
||||
defer flow.FinishIBD()
|
||||
err := flow.ibdLoop()
|
||||
if err != nil {
|
||||
finishIBDErr := flow.FinishIBD()
|
||||
if finishIBDErr != nil {
|
||||
return finishIBDErr
|
||||
}
|
||||
return err
|
||||
}
|
||||
return flow.FinishIBD()
|
||||
}
|
||||
|
||||
func (flow *handleIBDFlow) ibdLoop() error {
|
||||
for {
|
||||
syncInfo, err := flow.Domain().Consensus().GetSyncInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch syncInfo.State {
|
||||
case externalapi.SyncStateHeadersFirst:
|
||||
err := flow.syncHeaders()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case externalapi.SyncStateMissingUTXOSet:
|
||||
found, err := flow.fetchMissingUTXOSet(syncInfo.IBDRootUTXOBlockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !found {
|
||||
return nil
|
||||
}
|
||||
case externalapi.SyncStateMissingBlockBodies:
|
||||
err := flow.syncMissingBlockBodies()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case externalapi.SyncStateRelay:
|
||||
return nil
|
||||
default:
|
||||
return errors.Errorf("unexpected state %s", syncInfo.State)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (flow *handleIBDFlow) syncHeaders() error {
|
||||
peerSelectedTipHash := flow.peer.SelectedTipHash()
|
||||
log.Debugf("Trying to find highest shared chain block with peer %s with selected tip %s", flow.peer, peerSelectedTipHash)
|
||||
highestSharedBlockHash, err := flow.findHighestSharedBlockHash(peerSelectedTipHash)
|
||||
@ -64,7 +109,104 @@ func (flow *handleIBDFlow) runIBD() error {
|
||||
|
||||
log.Debugf("Found highest shared chain block %s with peer %s", highestSharedBlockHash, flow.peer)
|
||||
|
||||
return flow.downloadBlocks(highestSharedBlockHash, peerSelectedTipHash)
|
||||
return flow.downloadHeaders(highestSharedBlockHash, peerSelectedTipHash)
|
||||
}
|
||||
|
||||
func (flow *handleIBDFlow) syncMissingBlockBodies() error {
|
||||
hashes, err := flow.Domain().Consensus().GetMissingBlockBodyHashes(flow.peer.SelectedTipHash())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for offset := 0; offset < len(hashes); offset += appmessage.MaxRequestIBDBlocksHashes {
|
||||
var hashesToRequest []*externalapi.DomainHash
|
||||
if offset+appmessage.MaxRequestIBDBlocksHashes < len(hashes) {
|
||||
hashesToRequest = hashes[offset : offset+appmessage.MaxRequestIBDBlocksHashes]
|
||||
} else {
|
||||
hashesToRequest = hashes[offset:]
|
||||
}
|
||||
|
||||
err := flow.outgoingRoute.Enqueue(appmessage.NewMsgRequestIBDBlocks(hashesToRequest))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, expectedHash := range hashesToRequest {
|
||||
message, err := flow.incomingRoute.DequeueWithTimeout(common.DefaultTimeout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgIBDBlock, ok := message.(*appmessage.MsgIBDBlock)
|
||||
if !ok {
|
||||
return protocolerrors.Errorf(true, "received unexpected message type. "+
|
||||
"expected: %s, got: %s", appmessage.CmdIBDBlock, message.Command())
|
||||
}
|
||||
|
||||
block := appmessage.MsgBlockToDomainBlock(msgIBDBlock.MsgBlock)
|
||||
blockHash := consensusserialization.BlockHash(block)
|
||||
if *expectedHash != *blockHash {
|
||||
return protocolerrors.Errorf(true, "expected block %s but got %s", expectedHash, blockHash)
|
||||
}
|
||||
|
||||
err = flow.Domain().Consensus().ValidateAndInsertBlock(block)
|
||||
if err != nil {
|
||||
return protocolerrors.ConvertToBanningProtocolErrorIfRuleError(err, "invalid block %s", blockHash)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (flow *handleIBDFlow) fetchMissingUTXOSet(ibdRootHash *externalapi.DomainHash) (bool, error) {
|
||||
err := flow.outgoingRoute.Enqueue(appmessage.NewMsgRequestIBDRootUTXOSetAndBlock(ibdRootHash))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
utxoSet, block, found, err := flow.receiveIBDRootUTXOSetAndBlock()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !found {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
err = flow.Domain().Consensus().ValidateAndInsertBlock(block)
|
||||
if err != nil {
|
||||
blockHash := consensusserialization.BlockHash(block)
|
||||
return false, protocolerrors.ConvertToBanningProtocolErrorIfRuleError(err, "got invalid block %s during IBD", blockHash)
|
||||
}
|
||||
|
||||
err = flow.Domain().Consensus().SetPruningPointUTXOSet(utxoSet)
|
||||
if err != nil {
|
||||
return false, protocolerrors.ConvertToBanningProtocolErrorIfRuleError(err, "error with IBD root UTXO set")
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (flow *handleIBDFlow) receiveIBDRootUTXOSetAndBlock() ([]byte, *externalapi.DomainBlock, bool, error) {
|
||||
message, err := flow.incomingRoute.DequeueWithTimeout(common.DefaultTimeout)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
|
||||
switch message := message.(type) {
|
||||
case *appmessage.MsgIBDRootUTXOSetAndBlock:
|
||||
return message.UTXOSet,
|
||||
appmessage.MsgBlockToDomainBlock(message.Block), true, nil
|
||||
case *appmessage.MsgIBDRootNotFound:
|
||||
return nil, nil, false, nil
|
||||
default:
|
||||
return nil, nil, false,
|
||||
protocolerrors.Errorf(true, "received unexpected message type. "+
|
||||
"expected: %s or %s, got: %s",
|
||||
appmessage.CmdIBDRootUTXOSetAndBlock, appmessage.CmdIBDRootNotFound, message.Command(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func (flow *handleIBDFlow) findHighestSharedBlockHash(peerSelectedTipHash *externalapi.DomainHash) (lowHash *externalapi.DomainHash,
|
||||
@ -123,17 +265,17 @@ func (flow *handleIBDFlow) receiveBlockLocator() (blockLocatorHashes []*external
|
||||
return msgBlockLocator.BlockLocatorHashes, nil
|
||||
}
|
||||
|
||||
func (flow *handleIBDFlow) downloadBlocks(highestSharedBlockHash *externalapi.DomainHash,
|
||||
func (flow *handleIBDFlow) downloadHeaders(highestSharedBlockHash *externalapi.DomainHash,
|
||||
peerSelectedTipHash *externalapi.DomainHash) error {
|
||||
|
||||
err := flow.sendGetBlocks(highestSharedBlockHash, peerSelectedTipHash)
|
||||
err := flow.sendRequestHeaders(highestSharedBlockHash, peerSelectedTipHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
blocksReceived := 0
|
||||
for {
|
||||
msgIBDBlock, doneIBD, err := flow.receiveIBDBlock()
|
||||
msgBlockHeader, doneIBD, err := flow.receiveHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -142,14 +284,14 @@ func (flow *handleIBDFlow) downloadBlocks(highestSharedBlockHash *externalapi.Do
|
||||
return nil
|
||||
}
|
||||
|
||||
err = flow.processIBDBlock(msgIBDBlock)
|
||||
err = flow.processHeader(msgBlockHeader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
blocksReceived++
|
||||
if blocksReceived%ibdBatchSize == 0 {
|
||||
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgRequestNextIBDBlocks())
|
||||
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgRequestNextHeaders())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -157,47 +299,52 @@ func (flow *handleIBDFlow) downloadBlocks(highestSharedBlockHash *externalapi.Do
|
||||
}
|
||||
}
|
||||
|
||||
func (flow *handleIBDFlow) sendGetBlocks(highestSharedBlockHash *externalapi.DomainHash,
|
||||
func (flow *handleIBDFlow) sendRequestHeaders(highestSharedBlockHash *externalapi.DomainHash,
|
||||
peerSelectedTipHash *externalapi.DomainHash) error {
|
||||
|
||||
msgGetBlockInvs := appmessage.NewMsgRequstIBDBlocks(highestSharedBlockHash, peerSelectedTipHash)
|
||||
msgGetBlockInvs := appmessage.NewMsgRequstHeaders(highestSharedBlockHash, peerSelectedTipHash)
|
||||
return flow.outgoingRoute.Enqueue(msgGetBlockInvs)
|
||||
}
|
||||
|
||||
func (flow *handleIBDFlow) receiveIBDBlock() (msgIBDBlock *appmessage.MsgIBDBlock, doneIBD bool, err error) {
|
||||
func (flow *handleIBDFlow) receiveHeader() (msgIBDBlock *appmessage.MsgBlockHeader, doneIBD bool, err error) {
|
||||
message, err := flow.incomingRoute.DequeueWithTimeout(common.DefaultTimeout)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
switch message := message.(type) {
|
||||
case *appmessage.MsgIBDBlock:
|
||||
case *appmessage.MsgBlockHeader:
|
||||
return message, false, nil
|
||||
case *appmessage.MsgDoneIBDBlocks:
|
||||
case *appmessage.MsgDoneHeaders:
|
||||
return nil, true, nil
|
||||
default:
|
||||
return nil, false,
|
||||
protocolerrors.Errorf(true, "received unexpected message type. "+
|
||||
"expected: %s, got: %s", appmessage.CmdIBDBlock, message.Command())
|
||||
"expected: %s or %s, got: %s", appmessage.CmdHeader, appmessage.CmdDoneHeaders, message.Command())
|
||||
}
|
||||
}
|
||||
|
||||
func (flow *handleIBDFlow) processIBDBlock(msgIBDBlock *appmessage.MsgIBDBlock) error {
|
||||
block := appmessage.MsgBlockToDomainBlock(msgIBDBlock.MsgBlock)
|
||||
func (flow *handleIBDFlow) processHeader(msgBlockHeader *appmessage.MsgBlockHeader) error {
|
||||
header := appmessage.BlockHeaderToDomainBlockHeader(msgBlockHeader)
|
||||
block := &externalapi.DomainBlock{
|
||||
Header: header,
|
||||
Transactions: nil,
|
||||
}
|
||||
|
||||
blockHash := consensusserialization.BlockHash(block)
|
||||
blockInfo, err := flow.Domain().Consensus().GetBlockInfo(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if blockInfo.Exists {
|
||||
log.Debugf("IBD block %s is already in the DAG. Skipping...", blockHash)
|
||||
log.Debugf("Block header %s is already in the DAG. Skipping...", blockHash)
|
||||
return nil
|
||||
}
|
||||
err = flow.Domain().Consensus().ValidateAndInsertBlock(block)
|
||||
if err != nil {
|
||||
if !errors.As(err, &ruleerrors.RuleError{}) {
|
||||
return errors.Wrapf(err, "failed to process block %s during IBD", blockHash)
|
||||
return errors.Wrapf(err, "failed to process header %s during IBD", blockHash)
|
||||
}
|
||||
log.Infof("Rejected block %s from %s during IBD: %s", blockHash, flow.peer, err)
|
||||
log.Infof("Rejected block header %s from %s during IBD: %s", blockHash, flow.peer, err)
|
||||
|
||||
return protocolerrors.Wrapf(true, err, "got invalid block %s during IBD", blockHash)
|
||||
}
|
||||
|
@ -180,33 +180,51 @@ func (m *Manager) registerIBDFlows(router *routerpkg.Router, isStopping *uint32,
|
||||
|
||||
return []*flow{
|
||||
m.registerFlow("HandleIBD", router, []appmessage.MessageCommand{appmessage.CmdBlockLocator, appmessage.CmdIBDBlock,
|
||||
appmessage.CmdDoneIBDBlocks}, isStopping, errChan,
|
||||
appmessage.CmdDoneHeaders, appmessage.CmdIBDRootNotFound, appmessage.CmdIBDRootUTXOSetAndBlock}, isStopping, errChan,
|
||||
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
||||
return ibd.HandleIBD(m.context, incomingRoute, outgoingRoute, peer)
|
||||
},
|
||||
),
|
||||
|
||||
m.registerFlow("RequestSelectedTip", router, []appmessage.MessageCommand{appmessage.CmdSelectedTip}, isStopping, errChan,
|
||||
m.registerFlow("RequestSelectedTip", router,
|
||||
[]appmessage.MessageCommand{appmessage.CmdSelectedTip}, isStopping, errChan,
|
||||
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
||||
return selectedtip.RequestSelectedTip(m.context, incomingRoute, outgoingRoute, peer)
|
||||
},
|
||||
),
|
||||
|
||||
m.registerFlow("HandleRequestSelectedTip", router, []appmessage.MessageCommand{appmessage.CmdRequestSelectedTip}, isStopping, errChan,
|
||||
m.registerFlow("HandleRequestSelectedTip", router,
|
||||
[]appmessage.MessageCommand{appmessage.CmdRequestSelectedTip}, isStopping, errChan,
|
||||
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
||||
return selectedtip.HandleRequestSelectedTip(m.context, incomingRoute, outgoingRoute)
|
||||
},
|
||||
),
|
||||
|
||||
m.registerFlow("HandleRequestBlockLocator", router, []appmessage.MessageCommand{appmessage.CmdRequestBlockLocator}, isStopping, errChan,
|
||||
m.registerFlow("HandleRequestBlockLocator", router,
|
||||
[]appmessage.MessageCommand{appmessage.CmdRequestBlockLocator}, isStopping, errChan,
|
||||
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
||||
return ibd.HandleRequestBlockLocator(m.context, incomingRoute, outgoingRoute)
|
||||
},
|
||||
),
|
||||
|
||||
m.registerFlow("HandleRequestIBDBlocks", router, []appmessage.MessageCommand{appmessage.CmdRequestIBDBlocks, appmessage.CmdRequestNextIBDBlocks}, isStopping, errChan,
|
||||
m.registerFlow("HandleRequestHeaders", router,
|
||||
[]appmessage.MessageCommand{appmessage.CmdRequestHeaders, appmessage.CmdRequestNextHeaders}, isStopping, errChan,
|
||||
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
||||
return ibd.HandleRequestIBDBlocks(m.context, incomingRoute, outgoingRoute)
|
||||
return ibd.HandleRequestHeaders(m.context, incomingRoute, outgoingRoute)
|
||||
},
|
||||
),
|
||||
|
||||
m.registerFlow("HandleRequestIBDRootUTXOSetAndBlock", router,
|
||||
[]appmessage.MessageCommand{appmessage.CmdRequestIBDRootUTXOSetAndBlock}, isStopping, errChan,
|
||||
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
||||
return ibd.HandleRequestIBDRootUTXOSetAndBlock(m.context, incomingRoute, outgoingRoute)
|
||||
},
|
||||
),
|
||||
|
||||
m.registerFlow("HandleIBDBlockRequests", router,
|
||||
[]appmessage.MessageCommand{appmessage.CmdRequestIBDBlocks}, isStopping, errChan,
|
||||
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
||||
return ibd.HandleIBDBlockRequests(m.context, incomingRoute, outgoingRoute)
|
||||
},
|
||||
),
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package protocolerrors
|
||||
|
||||
import "github.com/pkg/errors"
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// ProtocolError is an error that signifies a violation
|
||||
// of the peer-to-peer protocol
|
||||
@ -50,3 +53,14 @@ func Wrapf(shouldBan bool, err error, format string, args ...interface{}) error
|
||||
Cause: errors.Wrapf(err, format, args...),
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertToBanningProtocolErrorIfRuleError converts the given error to
|
||||
// a banning protocol error if it's a rule error, and otherwise keep it
|
||||
// as is.
|
||||
func ConvertToBanningProtocolErrorIfRuleError(err error, format string, args ...interface{}) error {
|
||||
if !errors.As(err, &ruleerrors.RuleError{}) {
|
||||
return err
|
||||
}
|
||||
|
||||
return Wrapf(true, err, format, args...)
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import (
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type consensus struct {
|
||||
@ -132,11 +134,26 @@ func (s *consensus) GetMissingBlockBodyHashes(highHash *externalapi.DomainHash)
|
||||
return s.syncManager.GetMissingBlockBodyHashes(highHash)
|
||||
}
|
||||
|
||||
func (s *consensus) GetPruningPointUTXOSet() ([]byte, error) {
|
||||
func (s *consensus) GetPruningPointUTXOSet(expectedPruningPointHash *externalapi.DomainHash) ([]byte, error) {
|
||||
s.lock.RLock()
|
||||
defer s.lock.RUnlock()
|
||||
|
||||
return s.pruningStore.PruningPointSerializedUTXOSet(s.databaseContext)
|
||||
pruningPointHash, err := s.pruningStore.PruningPoint(s.databaseContext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if *expectedPruningPointHash != *pruningPointHash {
|
||||
return nil, errors.Wrapf(ruleerrors.ErrWrongPruningPointHash, "expected pruning point %s but got %s",
|
||||
expectedPruningPointHash,
|
||||
pruningPointHash)
|
||||
}
|
||||
|
||||
serializedUTXOSet, err := s.pruningStore.PruningPointSerializedUTXOSet(s.databaseContext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return serializedUTXOSet, nil
|
||||
}
|
||||
|
||||
func (s *consensus) SetPruningPointUTXOSet(serializedUTXOSet []byte) error {
|
||||
|
@ -12,7 +12,7 @@ type Consensus interface {
|
||||
|
||||
GetHashesBetween(lowHash, highHash *DomainHash) ([]*DomainHash, error)
|
||||
GetMissingBlockBodyHashes(highHash *DomainHash) ([]*DomainHash, error)
|
||||
GetPruningPointUTXOSet() ([]byte, error)
|
||||
GetPruningPointUTXOSet(expectedPruningPointHash *DomainHash) ([]byte, error)
|
||||
SetPruningPointUTXOSet(serializedUTXOSet []byte) error
|
||||
GetVirtualSelectedParent() (*DomainBlock, error)
|
||||
CreateBlockLocator(lowHash, highHash *DomainHash) (BlockLocator, error)
|
||||
|
@ -1,9 +1,11 @@
|
||||
package externalapi
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Each of the following represent one of the possible sync
|
||||
// states of the consensus
|
||||
const (
|
||||
SyncStateNormal SyncState = iota
|
||||
SyncStateRelay SyncState = iota
|
||||
SyncStateMissingGenesis
|
||||
SyncStateHeadersFirst
|
||||
SyncStateMissingUTXOSet
|
||||
@ -15,8 +17,8 @@ type SyncState uint8
|
||||
|
||||
func (s SyncState) String() string {
|
||||
switch s {
|
||||
case SyncStateNormal:
|
||||
return "SyncStateNormal"
|
||||
case SyncStateRelay:
|
||||
return "SyncStateRelay"
|
||||
case SyncStateHeadersFirst:
|
||||
return "SyncStateHeadersFirst"
|
||||
case SyncStateMissingUTXOSet:
|
||||
@ -25,7 +27,7 @@ func (s SyncState) String() string {
|
||||
return "SyncStateMissingBlockBodies"
|
||||
}
|
||||
|
||||
return "<unknown state>"
|
||||
return fmt.Sprintf("<unknown state (%d)>", s)
|
||||
}
|
||||
|
||||
// SyncInfo holds info about the current sync state of the consensus
|
||||
|
@ -34,7 +34,7 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock)
|
||||
}
|
||||
|
||||
if mode.State == externalapi.SyncStateHeadersFirst && !isHeaderOnlyBlock(block) {
|
||||
mode.State = externalapi.SyncStateNormal
|
||||
mode.State = externalapi.SyncStateRelay
|
||||
log.Warnf("block %s contains transactions while validating in header only mode", hash)
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if mode.State == externalapi.SyncStateNormal {
|
||||
} else if mode.State == externalapi.SyncStateRelay {
|
||||
// Attempt to add the block to the virtual
|
||||
err = bp.consensusStateManager.AddBlockToVirtual(hash)
|
||||
if err != nil {
|
||||
@ -118,7 +118,7 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock)
|
||||
}
|
||||
}
|
||||
|
||||
if mode.State == externalapi.SyncStateNormal {
|
||||
if mode.State == externalapi.SyncStateRelay {
|
||||
// Trigger pruning, which will check if the pruning point changed and delete the data if it did.
|
||||
err = bp.pruningManager.FindNextPruningPoint()
|
||||
if err != nil {
|
||||
|
@ -52,6 +52,9 @@ func (csm *consensusStateManager) restorePastUTXO(blockHash *externalapi.DomainH
|
||||
utxoDiffs = append(utxoDiffs, utxoDiff)
|
||||
|
||||
nextBlockHash, err = csm.utxoDiffStore.UTXODiffChild(csm.databaseContext, nextBlockHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// apply the diffs in reverse order
|
||||
|
@ -629,6 +629,9 @@ func (rt *reachabilityManager) reclaimIntervalAfterChosenChild(node, commonAnces
|
||||
currentInterval.Start,
|
||||
currentInterval.End-slackReachabilityIntervalForReclaiming,
|
||||
))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
currentParent, err := rt.parent(current)
|
||||
if err != nil {
|
||||
|
@ -70,7 +70,7 @@ func (sm *syncManager) resolveSyncState() (externalapi.SyncState, error) {
|
||||
return externalapi.SyncStateMissingBlockBodies, nil
|
||||
}
|
||||
|
||||
return externalapi.SyncStateNormal, nil
|
||||
return externalapi.SyncStateRelay, nil
|
||||
}
|
||||
|
||||
func (sm *syncManager) virtualSelectedParentHash() (*externalapi.DomainHash, error) {
|
||||
|
@ -234,6 +234,8 @@ var (
|
||||
ErrMissingBlockHeaderInIBD = newRuleError("ErrMissingBlockHeaderInIBD")
|
||||
|
||||
ErrMalformedUTXO = newRuleError("ErrMalformedUTXO")
|
||||
|
||||
ErrWrongPruningPointHash = newRuleError("ErrWrongPruningPointHash")
|
||||
)
|
||||
|
||||
// RuleError identifies a rule violation. It is used to indicate that
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -11,9 +11,9 @@ message KaspadMessage {
|
||||
RequestBlockLocatorMessage requestBlockLocator = 4;
|
||||
BlockLocatorMessage blockLocator = 5;
|
||||
RequestAddressesMessage requestAddresses = 6;
|
||||
RequestIBDBlocksMessage requestIBDBlocks = 7;
|
||||
RequestNextIBDBlocksMessage requestNextIBDBlocks = 8;
|
||||
DoneIBDBlocksMessage DoneIBDBlocks = 9;
|
||||
RequestHeadersMessage requestHeaders = 7;
|
||||
RequestNextHeadersMessage requestNextHeaders = 8;
|
||||
DoneHeadersMessage DoneHeaders = 9;
|
||||
RequestRelayBlocksMessage requestRelayBlocks = 10;
|
||||
RequestSelectedTipMessage requestSelectedTip = 11;
|
||||
RequestTransactionsMessage requestTransactions = 12;
|
||||
@ -27,6 +27,11 @@ message KaspadMessage {
|
||||
VersionMessage version = 20;
|
||||
TransactionNotFoundMessage transactionNotFound = 21;
|
||||
RejectMessage reject = 22;
|
||||
BlockHeaderMessage blockHeader = 23;
|
||||
RequestIBDRootUTXOSetAndBlockMessage requestIBDRootUTXOSetAndBlock = 24;
|
||||
IBDRootUTXOSetAndBlockMessage ibdRootUTXOSetAndBlock = 25;
|
||||
RequestIBDBlocksMessage requestIBDBlocks = 26;
|
||||
IBDRootNotFoundMessage ibdRootNotFound = 27;
|
||||
|
||||
GetCurrentNetworkRequestMessage getCurrentNetworkRequest = 1001;
|
||||
GetCurrentNetworkResponseMessage getCurrentNetworkResponse = 1002;
|
||||
@ -144,11 +149,11 @@ message TransactionOutput{
|
||||
|
||||
// BlockMessage start
|
||||
message BlockMessage{
|
||||
BlockHeader header = 1;
|
||||
BlockHeaderMessage header = 1;
|
||||
repeated TransactionMessage transactions = 2;
|
||||
}
|
||||
|
||||
message BlockHeader{
|
||||
message BlockHeaderMessage{
|
||||
int32 version = 1;
|
||||
repeated Hash parentHashes = 2;
|
||||
Hash hashMerkleRoot = 3;
|
||||
@ -178,27 +183,27 @@ message BlockLocatorMessage{
|
||||
// BlockLocatorMessage end
|
||||
|
||||
// GetBlocksMessage start
|
||||
message RequestIBDBlocksMessage{
|
||||
message RequestHeadersMessage{
|
||||
Hash lowHash = 1;
|
||||
Hash highHash = 2;
|
||||
}
|
||||
// GetBlocksMessage end
|
||||
|
||||
// RequestNextIBDBlocksMessage start
|
||||
message RequestNextIBDBlocksMessage{
|
||||
message RequestNextHeadersMessage{
|
||||
}
|
||||
// RequestNextIBDBlocksMessage end
|
||||
|
||||
// DoneIBDBlocksMessage start
|
||||
message DoneIBDBlocksMessage{
|
||||
message DoneHeadersMessage{
|
||||
}
|
||||
// DoneIBDBlocksMessage end
|
||||
|
||||
// GetRelayBlocksMessage start
|
||||
// RequestRelayBlocksMessage start
|
||||
message RequestRelayBlocksMessage{
|
||||
repeated Hash hashes = 1;
|
||||
}
|
||||
// GetRelayBlocksMessage end
|
||||
// RequestRelayBlocksMessage end
|
||||
|
||||
// GetSelectedTipMessage start
|
||||
message RequestSelectedTipMessage{
|
||||
@ -273,6 +278,30 @@ message RejectMessage{
|
||||
}
|
||||
// RejectMessage end
|
||||
|
||||
// RequestIBDRootUTXOSetAndBlockMessage start
|
||||
message RequestIBDRootUTXOSetAndBlockMessage{
|
||||
Hash ibdRoot = 1;
|
||||
}
|
||||
// RequestIBDRootUTXOSetAndBlockMessage end
|
||||
|
||||
// IBDRootUTXOSetAndBlockMessage start
|
||||
message IBDRootUTXOSetAndBlockMessage{
|
||||
bytes utxoSet = 1;
|
||||
BlockMessage block = 2;
|
||||
}
|
||||
// IBDRootUTXOSetAndBlockMessage end
|
||||
|
||||
// RequestIBDBlocksMessage start
|
||||
message RequestIBDBlocksMessage{
|
||||
repeated Hash hashes = 1;
|
||||
}
|
||||
// RequestIBDBlocksMessage end
|
||||
|
||||
// IBDRootNotFoundMessage start
|
||||
message IBDRootNotFoundMessage{
|
||||
}
|
||||
// IBDRootNotFoundMessage end
|
||||
|
||||
service P2P {
|
||||
rpc MessageStream (stream KaspadMessage) returns (stream KaspadMessage) {}
|
||||
}
|
||||
@ -455,7 +484,7 @@ message BlockVerboseData{
|
||||
double difficulty = 11;
|
||||
repeated string parentHashes = 12;
|
||||
string selectedParentHash = 13;
|
||||
repeated string transactionIDs=14;
|
||||
repeated string transactionIDs = 14;
|
||||
}
|
||||
|
||||
message TransactionVerboseData{
|
||||
|
@ -2,7 +2,6 @@ package protowire
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/util/mstime"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@ -15,7 +14,7 @@ func (x *KaspadMessage_Block) fromAppMessage(msgBlock *appmessage.MsgBlock) erro
|
||||
return x.Block.fromAppMessage(msgBlock)
|
||||
}
|
||||
|
||||
func (x *BlockMessage) toAppMessage() (appmessage.Message, error) {
|
||||
func (x *BlockMessage) toAppMessage() (*appmessage.MsgBlock, error) {
|
||||
if len(x.Transactions) > appmessage.MaxTxPerBlock {
|
||||
return nil, errors.Errorf("too many transactions to fit into a block "+
|
||||
"[count %d, max %d]", len(x.Transactions), appmessage.MaxTxPerBlock)
|
||||
@ -31,37 +30,11 @@ func (x *BlockMessage) toAppMessage() (appmessage.Message, error) {
|
||||
"is %d", len(protoBlockHeader.ParentHashes), appmessage.MaxBlockParents)
|
||||
}
|
||||
|
||||
parentHashes, err := protoHashesToDomain(protoBlockHeader.ParentHashes)
|
||||
header, err := x.Header.toAppMessage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hashMerkleRoot, err := protoBlockHeader.HashMerkleRoot.toDomain()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
acceptedIDMerkleRoot, err := protoBlockHeader.AcceptedIDMerkleRoot.toDomain()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
utxoCommitment, err := protoBlockHeader.UtxoCommitment.toDomain()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
header := appmessage.BlockHeader{
|
||||
Version: protoBlockHeader.Version,
|
||||
ParentHashes: parentHashes,
|
||||
HashMerkleRoot: hashMerkleRoot,
|
||||
AcceptedIDMerkleRoot: acceptedIDMerkleRoot,
|
||||
UTXOCommitment: utxoCommitment,
|
||||
Timestamp: mstime.UnixMilliseconds(protoBlockHeader.Timestamp),
|
||||
Bits: protoBlockHeader.Bits,
|
||||
Nonce: protoBlockHeader.Nonce,
|
||||
}
|
||||
|
||||
transactions := make([]*appmessage.MsgTx, len(x.Transactions))
|
||||
for i, protoTx := range x.Transactions {
|
||||
msgTx, err := protoTx.toAppMessage()
|
||||
@ -72,7 +45,7 @@ func (x *BlockMessage) toAppMessage() (appmessage.Message, error) {
|
||||
}
|
||||
|
||||
return &appmessage.MsgBlock{
|
||||
Header: header,
|
||||
Header: *header,
|
||||
Transactions: transactions,
|
||||
}, nil
|
||||
}
|
||||
@ -88,17 +61,12 @@ func (x *BlockMessage) fromAppMessage(msgBlock *appmessage.MsgBlock) error {
|
||||
"is %d", len(msgBlock.Header.ParentHashes), appmessage.MaxBlockParents)
|
||||
}
|
||||
|
||||
header := msgBlock.Header
|
||||
protoHeader := &BlockHeader{
|
||||
Version: header.Version,
|
||||
ParentHashes: domainHashesToProto(header.ParentHashes),
|
||||
HashMerkleRoot: domainHashToProto(header.HashMerkleRoot),
|
||||
AcceptedIDMerkleRoot: domainHashToProto(header.AcceptedIDMerkleRoot),
|
||||
UtxoCommitment: domainHashToProto(header.UTXOCommitment),
|
||||
Timestamp: header.Timestamp.UnixMilliseconds(),
|
||||
Bits: header.Bits,
|
||||
Nonce: header.Nonce,
|
||||
protoHeader := new(BlockHeaderMessage)
|
||||
err := protoHeader.fromAppMessage(&msgBlock.Header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
protoTransactions := make([]*TransactionMessage, len(msgBlock.Transactions))
|
||||
for i, tx := range msgBlock.Transactions {
|
||||
protoTx := new(TransactionMessage)
|
||||
|
@ -2,10 +2,10 @@ package protowire
|
||||
|
||||
import "github.com/kaspanet/kaspad/app/appmessage"
|
||||
|
||||
func (x *KaspadMessage_DoneIBDBlocks) toAppMessage() (appmessage.Message, error) {
|
||||
return &appmessage.MsgDoneIBDBlocks{}, nil
|
||||
func (x *KaspadMessage_DoneHeaders) toAppMessage() (appmessage.Message, error) {
|
||||
return &appmessage.MsgDoneHeaders{}, nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage_DoneIBDBlocks) fromAppMessage(_ *appmessage.MsgDoneIBDBlocks) error {
|
||||
func (x *KaspadMessage_DoneHeaders) fromAppMessage(_ *appmessage.MsgDoneHeaders) error {
|
||||
return nil
|
||||
}
|
||||
|
@ -0,0 +1,73 @@
|
||||
package protowire
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/util/mstime"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (x *KaspadMessage_BlockHeader) toAppMessage() (appmessage.Message, error) {
|
||||
return x.BlockHeader.toAppMessage()
|
||||
}
|
||||
|
||||
func (x *KaspadMessage_BlockHeader) fromAppMessage(msgBlockHeader *appmessage.MsgBlockHeader) error {
|
||||
x.BlockHeader = new(BlockHeaderMessage)
|
||||
return x.BlockHeader.fromAppMessage(msgBlockHeader)
|
||||
}
|
||||
|
||||
func (x *BlockHeaderMessage) toAppMessage() (*appmessage.MsgBlockHeader, error) {
|
||||
if len(x.ParentHashes) > appmessage.MaxBlockParents {
|
||||
return nil, errors.Errorf("block header has %d parents, but the maximum allowed amount "+
|
||||
"is %d", len(x.ParentHashes), appmessage.MaxBlockParents)
|
||||
}
|
||||
|
||||
parentHashes, err := protoHashesToDomain(x.ParentHashes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hashMerkleRoot, err := x.HashMerkleRoot.toDomain()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
acceptedIDMerkleRoot, err := x.AcceptedIDMerkleRoot.toDomain()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
utxoCommitment, err := x.UtxoCommitment.toDomain()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &appmessage.MsgBlockHeader{
|
||||
Version: x.Version,
|
||||
ParentHashes: parentHashes,
|
||||
HashMerkleRoot: hashMerkleRoot,
|
||||
AcceptedIDMerkleRoot: acceptedIDMerkleRoot,
|
||||
UTXOCommitment: utxoCommitment,
|
||||
Timestamp: mstime.UnixMilliseconds(x.Timestamp),
|
||||
Bits: x.Bits,
|
||||
Nonce: x.Nonce,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (x *BlockHeaderMessage) fromAppMessage(msgBlockHeader *appmessage.MsgBlockHeader) error {
|
||||
if len(msgBlockHeader.ParentHashes) > appmessage.MaxBlockParents {
|
||||
return errors.Errorf("block header has %d parents, but the maximum allowed amount "+
|
||||
"is %d", len(msgBlockHeader.ParentHashes), appmessage.MaxBlockParents)
|
||||
}
|
||||
|
||||
*x = BlockHeaderMessage{
|
||||
Version: msgBlockHeader.Version,
|
||||
ParentHashes: domainHashesToProto(msgBlockHeader.ParentHashes),
|
||||
HashMerkleRoot: domainHashToProto(msgBlockHeader.HashMerkleRoot),
|
||||
AcceptedIDMerkleRoot: domainHashToProto(msgBlockHeader.AcceptedIDMerkleRoot),
|
||||
UtxoCommitment: domainHashToProto(msgBlockHeader.UTXOCommitment),
|
||||
Timestamp: msgBlockHeader.Timestamp.UnixMilliseconds(),
|
||||
Bits: msgBlockHeader.Bits,
|
||||
Nonce: msgBlockHeader.Nonce,
|
||||
}
|
||||
return nil
|
||||
}
|
@ -7,7 +7,7 @@ func (x *KaspadMessage_IbdBlock) toAppMessage() (appmessage.Message, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &appmessage.MsgIBDBlock{MsgBlock: msgBlock.(*appmessage.MsgBlock)}, nil
|
||||
return &appmessage.MsgIBDBlock{MsgBlock: msgBlock}, nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage_IbdBlock) fromAppMessage(msgIBDBlock *appmessage.MsgIBDBlock) error {
|
||||
|
@ -0,0 +1,11 @@
|
||||
package protowire
|
||||
|
||||
import "github.com/kaspanet/kaspad/app/appmessage"
|
||||
|
||||
func (x *KaspadMessage_IbdRootNotFound) toAppMessage() (appmessage.Message, error) {
|
||||
return &appmessage.MsgIBDRootNotFound{}, nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage_IbdRootNotFound) fromAppMessage(_ *appmessage.MsgIBDRootNotFound) error {
|
||||
return nil
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package protowire
|
||||
|
||||
import "github.com/kaspanet/kaspad/app/appmessage"
|
||||
|
||||
func (x *KaspadMessage_IbdRootUTXOSetAndBlock) toAppMessage() (appmessage.Message, error) {
|
||||
msgBlock, err := x.IbdRootUTXOSetAndBlock.Block.toAppMessage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &appmessage.MsgIBDRootUTXOSetAndBlock{
|
||||
UTXOSet: x.IbdRootUTXOSetAndBlock.UtxoSet,
|
||||
Block: msgBlock,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage_IbdRootUTXOSetAndBlock) fromAppMessage(msgIBDRootUTXOSetAndBlock *appmessage.MsgIBDRootUTXOSetAndBlock) error {
|
||||
x.IbdRootUTXOSetAndBlock.UtxoSet = msgIBDRootUTXOSetAndBlock.UTXOSet
|
||||
return x.IbdRootUTXOSetAndBlock.Block.fromAppMessage(msgIBDRootUTXOSetAndBlock.Block)
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package protowire
|
||||
|
||||
import "github.com/kaspanet/kaspad/app/appmessage"
|
||||
|
||||
func (x *KaspadMessage_RequestHeaders) toAppMessage() (appmessage.Message, error) {
|
||||
lowHash, err := x.RequestHeaders.LowHash.toDomain()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
highHash, err := x.RequestHeaders.HighHash.toDomain()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &appmessage.MsgRequestHeaders{
|
||||
LowHash: lowHash,
|
||||
HighHash: highHash,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage_RequestHeaders) fromAppMessage(msgRequestHeaders *appmessage.MsgRequestHeaders) error {
|
||||
x.RequestHeaders = &RequestHeadersMessage{
|
||||
LowHash: domainHashToProto(msgRequestHeaders.LowHash),
|
||||
HighHash: domainHashToProto(msgRequestHeaders.HighHash),
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,28 +1,31 @@
|
||||
package protowire
|
||||
|
||||
import "github.com/kaspanet/kaspad/app/appmessage"
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (x *KaspadMessage_RequestIBDBlocks) toAppMessage() (appmessage.Message, error) {
|
||||
lowHash, err := x.RequestIBDBlocks.LowHash.toDomain()
|
||||
if len(x.RequestIBDBlocks.Hashes) > appmessage.MaxRequestIBDBlocksHashes {
|
||||
return nil, errors.Errorf("too many hashes for message "+
|
||||
"[count %d, max %d]", len(x.RequestIBDBlocks.Hashes), appmessage.MaxRequestIBDBlocksHashes)
|
||||
}
|
||||
hashes, err := protoHashesToDomain(x.RequestIBDBlocks.Hashes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
highHash, err := x.RequestIBDBlocks.HighHash.toDomain()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &appmessage.MsgRequestIBDBlocks{
|
||||
LowHash: lowHash,
|
||||
HighHash: highHash,
|
||||
}, nil
|
||||
return &appmessage.MsgRequestRelayBlocks{Hashes: hashes}, nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage_RequestIBDBlocks) fromAppMessage(msgGetBlocks *appmessage.MsgRequestIBDBlocks) error {
|
||||
x.RequestIBDBlocks = &RequestIBDBlocksMessage{
|
||||
LowHash: domainHashToProto(msgGetBlocks.LowHash),
|
||||
HighHash: domainHashToProto(msgGetBlocks.HighHash),
|
||||
func (x *KaspadMessage_RequestIBDBlocks) fromAppMessage(msgRequestIBDBlocks *appmessage.MsgRequestIBDBlocks) error {
|
||||
if len(msgRequestIBDBlocks.Hashes) > appmessage.MaxRequestIBDBlocksHashes {
|
||||
return errors.Errorf("too many hashes for message "+
|
||||
"[count %d, max %d]", len(msgRequestIBDBlocks.Hashes), appmessage.MaxRequestIBDBlocksHashes)
|
||||
}
|
||||
|
||||
x.RequestIBDBlocks = &RequestIBDBlocksMessage{
|
||||
Hashes: domainHashesToProto(msgRequestIBDBlocks.Hashes),
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
package protowire
|
||||
|
||||
import "github.com/kaspanet/kaspad/app/appmessage"
|
||||
|
||||
func (x *KaspadMessage_RequestIBDRootUTXOSetAndBlock) toAppMessage() (appmessage.Message, error) {
|
||||
ibdRoot, err := x.RequestIBDRootUTXOSetAndBlock.IbdRoot.toDomain()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &appmessage.MsgRequestIBDRootUTXOSetAndBlock{IBDRoot: ibdRoot}, nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage_RequestIBDRootUTXOSetAndBlock) fromAppMessage(
|
||||
msgRequestIBDRootUTXOSetAndBlock *appmessage.MsgRequestIBDRootUTXOSetAndBlock) error {
|
||||
x.RequestIBDRootUTXOSetAndBlock.IbdRoot = domainHashToProto(msgRequestIBDRootUTXOSetAndBlock.IBDRoot)
|
||||
return nil
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package protowire
|
||||
|
||||
import "github.com/kaspanet/kaspad/app/appmessage"
|
||||
|
||||
func (x *KaspadMessage_RequestNextHeaders) toAppMessage() (appmessage.Message, error) {
|
||||
return &appmessage.MsgRequestNextHeaders{}, nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage_RequestNextHeaders) fromAppMessage(_ *appmessage.MsgRequestNextHeaders) error {
|
||||
return nil
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package protowire
|
||||
|
||||
import "github.com/kaspanet/kaspad/app/appmessage"
|
||||
|
||||
func (x *KaspadMessage_RequestNextIBDBlocks) toAppMessage() (appmessage.Message, error) {
|
||||
return &appmessage.MsgRequestNextIBDBlocks{}, nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage_RequestNextIBDBlocks) fromAppMessage(_ *appmessage.MsgRequestNextIBDBlocks) error {
|
||||
return nil
|
||||
}
|
@ -6,9 +6,9 @@ import (
|
||||
)
|
||||
|
||||
func (x *KaspadMessage_RequestRelayBlocks) toAppMessage() (appmessage.Message, error) {
|
||||
if len(x.RequestRelayBlocks.Hashes) > appmessage.MsgRequestRelayBlocksHashes {
|
||||
if len(x.RequestRelayBlocks.Hashes) > appmessage.MaxRequestRelayBlocksHashes {
|
||||
return nil, errors.Errorf("too many hashes for message "+
|
||||
"[count %d, max %d]", len(x.RequestRelayBlocks.Hashes), appmessage.MsgRequestRelayBlocksHashes)
|
||||
"[count %d, max %d]", len(x.RequestRelayBlocks.Hashes), appmessage.MaxRequestRelayBlocksHashes)
|
||||
}
|
||||
hashes, err := protoHashesToDomain(x.RequestRelayBlocks.Hashes)
|
||||
if err != nil {
|
||||
@ -18,9 +18,9 @@ func (x *KaspadMessage_RequestRelayBlocks) toAppMessage() (appmessage.Message, e
|
||||
}
|
||||
|
||||
func (x *KaspadMessage_RequestRelayBlocks) fromAppMessage(msgGetRelayBlocks *appmessage.MsgRequestRelayBlocks) error {
|
||||
if len(msgGetRelayBlocks.Hashes) > appmessage.MsgRequestRelayBlocksHashes {
|
||||
if len(msgGetRelayBlocks.Hashes) > appmessage.MaxRequestRelayBlocksHashes {
|
||||
return errors.Errorf("too many hashes for message "+
|
||||
"[count %d, max %d]", len(msgGetRelayBlocks.Hashes), appmessage.MsgRequestRelayBlocksHashes)
|
||||
"[count %d, max %d]", len(msgGetRelayBlocks.Hashes), appmessage.MaxRequestRelayBlocksHashes)
|
||||
}
|
||||
|
||||
x.RequestRelayBlocks = &RequestRelayBlocksMessage{
|
||||
|
@ -22,7 +22,7 @@ func (x *KaspadMessage_GetBlockTemplateResponse) toAppMessage() (appmessage.Mess
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return appmessage.NewGetBlockTemplateResponseMessage(msgBlock.(*appmessage.MsgBlock)), nil
|
||||
return appmessage.NewGetBlockTemplateResponseMessage(msgBlock), nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage_GetBlockTemplateResponse) fromAppMessage(message *appmessage.GetBlockTemplateResponseMessage) error {
|
||||
|
@ -38,7 +38,7 @@ func (x *KaspadMessage_BlockAddedNotification) toAppMessage() (appmessage.Messag
|
||||
return nil, err
|
||||
}
|
||||
return &appmessage.BlockAddedNotificationMessage{
|
||||
Block: block.(*appmessage.MsgBlock),
|
||||
Block: block,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ func (x *KaspadMessage_SubmitBlockRequest) toAppMessage() (appmessage.Message, e
|
||||
}
|
||||
|
||||
return &appmessage.SubmitBlockRequestMessage{
|
||||
Block: blockAppMessage.(*appmessage.MsgBlock),
|
||||
Block: blockAppMessage,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -93,15 +93,15 @@ func toP2PPayload(message appmessage.Message) (isKaspadMessage_Payload, error) {
|
||||
return nil, err
|
||||
}
|
||||
return payload, nil
|
||||
case *appmessage.MsgRequestNextIBDBlocks:
|
||||
payload := new(KaspadMessage_RequestNextIBDBlocks)
|
||||
case *appmessage.MsgRequestNextHeaders:
|
||||
payload := new(KaspadMessage_RequestNextHeaders)
|
||||
err := payload.fromAppMessage(message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return payload, nil
|
||||
case *appmessage.MsgDoneIBDBlocks:
|
||||
payload := new(KaspadMessage_DoneIBDBlocks)
|
||||
case *appmessage.MsgDoneHeaders:
|
||||
payload := new(KaspadMessage_DoneHeaders)
|
||||
err := payload.fromAppMessage(message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -205,6 +205,47 @@ func toP2PPayload(message appmessage.Message) (isKaspadMessage_Payload, error) {
|
||||
return nil, err
|
||||
}
|
||||
return payload, nil
|
||||
|
||||
case *appmessage.MsgBlockHeader:
|
||||
payload := new(KaspadMessage_BlockHeader)
|
||||
err := payload.fromAppMessage(message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return payload, nil
|
||||
|
||||
case *appmessage.MsgRequestIBDRootUTXOSetAndBlock:
|
||||
payload := new(KaspadMessage_RequestIBDRootUTXOSetAndBlock)
|
||||
err := payload.fromAppMessage(message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return payload, nil
|
||||
|
||||
case *appmessage.MsgIBDRootUTXOSetAndBlock:
|
||||
payload := new(KaspadMessage_IbdRootUTXOSetAndBlock)
|
||||
err := payload.fromAppMessage(message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return payload, nil
|
||||
|
||||
case *appmessage.MsgRequestHeaders:
|
||||
payload := new(KaspadMessage_RequestHeaders)
|
||||
err := payload.fromAppMessage(message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return payload, nil
|
||||
|
||||
case *appmessage.MsgIBDRootNotFound:
|
||||
payload := new(KaspadMessage_IbdRootNotFound)
|
||||
err := payload.fromAppMessage(message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return payload, nil
|
||||
|
||||
default:
|
||||
return nil, nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user