Sync pruning point UTXO sets incrementally instead of all at once (#1431)

* Replaced the content of MsgIBDRootUTXOSetChunk with pairs of outpoint-utxo entry pairs.

* Rename utxoIter to utxoIterator.

* Add a big stinky TODO on an assert.

* Replace pruningStore staging with a UTXO set iterator.

* Reimplement receiveAndInsertIBDRootUTXOSet.

* Extract OutpointAndUTXOEntryPairsToDomainOutpointAndUTXOEntryPairs into domainconverters.go.

* Pass the outpoint and utxy entry pairs to the pruning store.

* Implement InsertCandidatePruningPointUTXOs.

* Implement ClearCandidatePruningPointUTXOs.

* Implement UpdateCandidatePruningPointMultiset.

* Use the candidate pruning point multiset in updatePruningPoint.

* Implement CandidatePruningPointUTXOIterator.

* Use the pruning point utxo set iterator for StageVirtualUTXOSet.

* Defer ClearCandidatePruningPointUTXOs.

* Implement OverwriteVirtualUTXOSet.

* Implement CommitCandidatePruningPointUTXOSet.

* Implement BeginOverwritingVirtualUTXOSet and FinishOverwritingVirtualUTXOSet.

* Implement overwriteVirtualUTXOSetAndCommitPruningPointUTXOSet.

* Rename ClearCandidatePruningPointUTXOs to ClearCandidatePruningPointData.

* Add missing methods to dbManager.

* Implement PruningPointUTXOs.

* Implement RecoverUTXOIfRequired.

* Delete the utxoserialization package.

* Fix compilation errors in TestValidateAndInsertPruningPoint.

* Switch order of operations in the if statements in PruningPointUTXOs so that Next() wouldn't be unnecessarily called.

* Fix missing pruning point utxo set staging and bad slice length.

* Fix no default multiset in InsertCandidatePruningPointUTXOs.

* Make go vet happy.

* Rename candidateXXX to importedXXX.

* Do some more renaming.

* Rename some more.

* Fix bad MsgIBDRootNotFound logic.

* Fix an error message.

* Simplify receiveIBDRootBlock.

* Fix error message in receiveAndInsertIBDRootUTXOSet.

* Do some more renaming.

* Fix merge errors.

* Fix a bug caused by calling iterator.First() unnecessarily.

* Remove databaseContext from stores and don't use a transaction in ClearXXX functions.

* Simplify receiveAndInsertIBDRootUTXOSet.

* Fix offset count in PruningPointUTXOs().

* Fix readOnlyUTXOIteratorWithDiff.First().

* Split handleRequestIBDRootUTXOSetAndBlockFlow into smaller methods.

* Rename IbdRootNotFound to UnexpectedPruningPoint.

* Rename requestIBDRootHash to requestPruningPointHash.

* Rename IBDRootHash to PruningPointHash.

* Rename RequestIBDRootUTXOSetAndBlock to RequestPruningPointUTXOSetAndBlock.

* Rename IBDRootUTXOSetChunk to PruningPointUTXOSetChunk.

* Rename RequestNextIBDRootUTXOSetChunk to RequestNextPruningPointUTXOSetChunk.

* Rename DoneIBDRootUTXOSetChunks to DonePruningPointUTXOSetChunks.

* Rename remaining references to IBD root.

* Fix an error message.

* Add a check for HadStartedImportingPruningPointUTXOSet in commitVirtualUTXODiff.

* Add a check for HadStartedImportingPruningPointUTXOSet in ImportPruningPointUTXOSetIntoVirtualUTXOSet.

* Move FinishImportingPruningPointUTXOSet closer to HadStartedImportingPruningPointUTXOSet.

* Remove reference to pruningStore in utxoSetIterator.

* Pointerify utxoSetIterator receivers.

* Fix bad insert in CommitImportedPruningPointUTXOSet.

* Rename commitImportedPruningPointUTXOSetAll to applyImportedPruningPointUTXOSet.

* Simplify PruningPointUTXOs.

* Add populateTransactionWithUTXOEntriesFromUTXOSet.

* Fix a TODO comment.

* Rename InsertImportedPruningPointUTXOs to AppendImportedPruningPointUTXOs.

* Extract handleRequestPruningPointUTXOSetAndBlockMessage to a separate method.

* Rename stuff in readOnlyUTXOIteratorWithDiff.First().

* Address toAddIterator in readOnlyUTXOIteratorWithDiff.First().

* Call First() before any full iteration on ReadOnlyUTXOSetIterator.

* Call First() before any full iteration on a database Cursor.

* Put StartImportingPruningPointUTXOSet inside the pruning point transaction.

* Make serializeOutpoint and serializeUTXOEntry free functions in pruningStore.

* Fix readOnlyUTXOIteratorWithDiff.First().

* Fix bad validations in importPruningPoint.

* Remove superfluous call to validateBlockTransactionsAgainstPastUTXO.
This commit is contained in:
stasatdaglabs 2021-01-21 17:24:52 +02:00 committed by GitHub
parent 6a03d31f98
commit 756f40c59a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
76 changed files with 2599 additions and 2044 deletions

View File

@ -3,6 +3,7 @@ package appmessage
import ( import (
"encoding/hex" "encoding/hex"
"github.com/kaspanet/kaspad/domain/consensus/utils/blockheader" "github.com/kaspanet/kaspad/domain/consensus/utils/blockheader"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi" "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks" "github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
@ -268,3 +269,49 @@ func DomainTransactionToRPCTransaction(transaction *externalapi.DomainTransactio
Payload: payload, Payload: payload,
} }
} }
// OutpointAndUTXOEntryPairsToDomainOutpointAndUTXOEntryPairs converts
// OutpointAndUTXOEntryPairs to domain OutpointAndUTXOEntryPairs
func OutpointAndUTXOEntryPairsToDomainOutpointAndUTXOEntryPairs(
outpointAndUTXOEntryPairs []*OutpointAndUTXOEntryPair) []*externalapi.OutpointAndUTXOEntryPair {
domainOutpointAndUTXOEntryPairs := make([]*externalapi.OutpointAndUTXOEntryPair, len(outpointAndUTXOEntryPairs))
for i, outpointAndUTXOEntryPair := range outpointAndUTXOEntryPairs {
domainOutpointAndUTXOEntryPairs[i] = &externalapi.OutpointAndUTXOEntryPair{
Outpoint: &externalapi.DomainOutpoint{
TransactionID: outpointAndUTXOEntryPair.Outpoint.TxID,
Index: outpointAndUTXOEntryPair.Outpoint.Index,
},
UTXOEntry: utxo.NewUTXOEntry(
outpointAndUTXOEntryPair.UTXOEntry.Amount,
outpointAndUTXOEntryPair.UTXOEntry.ScriptPublicKey,
outpointAndUTXOEntryPair.UTXOEntry.IsCoinbase,
outpointAndUTXOEntryPair.UTXOEntry.BlockBlueScore,
),
}
}
return domainOutpointAndUTXOEntryPairs
}
// DomainOutpointAndUTXOEntryPairsToOutpointAndUTXOEntryPairs converts
// domain OutpointAndUTXOEntryPairs to OutpointAndUTXOEntryPairs
func DomainOutpointAndUTXOEntryPairsToOutpointAndUTXOEntryPairs(
outpointAndUTXOEntryPairs []*externalapi.OutpointAndUTXOEntryPair) []*OutpointAndUTXOEntryPair {
domainOutpointAndUTXOEntryPairs := make([]*OutpointAndUTXOEntryPair, len(outpointAndUTXOEntryPairs))
for i, outpointAndUTXOEntryPair := range outpointAndUTXOEntryPairs {
domainOutpointAndUTXOEntryPairs[i] = &OutpointAndUTXOEntryPair{
Outpoint: &Outpoint{
TxID: outpointAndUTXOEntryPair.Outpoint.TransactionID,
Index: outpointAndUTXOEntryPair.Outpoint.Index,
},
UTXOEntry: &UTXOEntry{
Amount: outpointAndUTXOEntryPair.UTXOEntry.Amount(),
ScriptPublicKey: outpointAndUTXOEntryPair.UTXOEntry.ScriptPublicKey(),
IsCoinbase: outpointAndUTXOEntryPair.UTXOEntry.IsCoinbase(),
BlockBlueScore: outpointAndUTXOEntryPair.UTXOEntry.BlockBlueScore(),
},
}
}
return domainOutpointAndUTXOEntryPairs
}

View File

@ -51,17 +51,17 @@ const (
CmdReject CmdReject
CmdHeader CmdHeader
CmdRequestNextHeaders CmdRequestNextHeaders
CmdRequestIBDRootUTXOSetAndBlock CmdRequestPruningPointUTXOSetAndBlock
CmdIBDRootUTXOSetChunk CmdPruningPointUTXOSetChunk
CmdRequestIBDBlocks CmdRequestIBDBlocks
CmdIBDRootNotFound CmdUnexpectedPruningPoint
CmdRequestIBDRootHash CmdRequestPruningPointHash
CmdIBDRootHash CmdPruningPointHash
CmdIBDBlockLocator CmdIBDBlockLocator
CmdIBDBlockLocatorHighestHash CmdIBDBlockLocatorHighestHash
CmdBlockHeaders CmdBlockHeaders
CmdRequestNextIBDRootUTXOSetChunk CmdRequestNextPruningPointUTXOSetChunk
CmdDoneIBDRootUTXOSetChunks CmdDonePruningPointUTXOSetChunks
// rpc // rpc
CmdGetCurrentNetworkRequestMessage CmdGetCurrentNetworkRequestMessage
@ -127,38 +127,38 @@ const (
// ProtocolMessageCommandToString maps all MessageCommands to their string representation // ProtocolMessageCommandToString maps all MessageCommands to their string representation
var ProtocolMessageCommandToString = map[MessageCommand]string{ var ProtocolMessageCommandToString = map[MessageCommand]string{
CmdVersion: "Version", CmdVersion: "Version",
CmdVerAck: "VerAck", CmdVerAck: "VerAck",
CmdRequestAddresses: "RequestAddresses", CmdRequestAddresses: "RequestAddresses",
CmdAddresses: "Addresses", CmdAddresses: "Addresses",
CmdRequestHeaders: "RequestHeaders", CmdRequestHeaders: "RequestHeaders",
CmdBlock: "Block", CmdBlock: "Block",
CmdTx: "Tx", CmdTx: "Tx",
CmdPing: "Ping", CmdPing: "Ping",
CmdPong: "Pong", CmdPong: "Pong",
CmdRequestBlockLocator: "RequestBlockLocator", CmdRequestBlockLocator: "RequestBlockLocator",
CmdBlockLocator: "BlockLocator", CmdBlockLocator: "BlockLocator",
CmdInvRelayBlock: "InvRelayBlock", CmdInvRelayBlock: "InvRelayBlock",
CmdRequestRelayBlocks: "RequestRelayBlocks", CmdRequestRelayBlocks: "RequestRelayBlocks",
CmdInvTransaction: "InvTransaction", CmdInvTransaction: "InvTransaction",
CmdRequestTransactions: "RequestTransactions", CmdRequestTransactions: "RequestTransactions",
CmdIBDBlock: "IBDBlock", CmdIBDBlock: "IBDBlock",
CmdDoneHeaders: "DoneHeaders", CmdDoneHeaders: "DoneHeaders",
CmdTransactionNotFound: "TransactionNotFound", CmdTransactionNotFound: "TransactionNotFound",
CmdReject: "Reject", CmdReject: "Reject",
CmdHeader: "Header", CmdHeader: "Header",
CmdRequestNextHeaders: "RequestNextHeaders", CmdRequestNextHeaders: "RequestNextHeaders",
CmdRequestIBDRootUTXOSetAndBlock: "RequestPruningUTXOSetAndBlock", CmdRequestPruningPointUTXOSetAndBlock: "RequestPruningPointUTXOSetAndBlock",
CmdIBDRootUTXOSetChunk: "IBDRootUTXOSetChunk", CmdPruningPointUTXOSetChunk: "PruningPointUTXOSetChunk",
CmdRequestIBDBlocks: "RequestIBDBlocks", CmdRequestIBDBlocks: "RequestIBDBlocks",
CmdIBDRootNotFound: "IBDRootNotFound", CmdUnexpectedPruningPoint: "UnexpectedPruningPoint",
CmdRequestIBDRootHash: "IBDRequestIBDRootHash", CmdRequestPruningPointHash: "RequestPruningPointHashHash",
CmdIBDRootHash: "IBDIBDRootHash", CmdPruningPointHash: "PruningPointHash",
CmdIBDBlockLocator: "IBDBlockLocator", CmdIBDBlockLocator: "IBDBlockLocator",
CmdIBDBlockLocatorHighestHash: "IBDBlockLocatorHighestHash", CmdIBDBlockLocatorHighestHash: "IBDBlockLocatorHighestHash",
CmdBlockHeaders: "BlockHeaders", CmdBlockHeaders: "BlockHeaders",
CmdRequestNextIBDRootUTXOSetChunk: "RequestNextIBDRootUTXOSetChunk", CmdRequestNextPruningPointUTXOSetChunk: "RequestNextPruningPointUTXOSetChunk",
CmdDoneIBDRootUTXOSetChunks: "DoneIBDRootUTXOSetChunks", CmdDonePruningPointUTXOSetChunks: "DonePruningPointUTXOSetChunks",
} }
// RPCMessageCommandToString maps all MessageCommands to their string representation // RPCMessageCommandToString maps all MessageCommands to their string representation

View File

@ -1,22 +0,0 @@
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 CmdIBDRootNotFound
}
// NewMsgIBDRootNotFound returns a new kaspa IBDRootNotFound message that conforms to the
// Message interface.
func NewMsgIBDRootNotFound() *MsgIBDRootNotFound {
return &MsgIBDRootNotFound{}
}

View File

@ -1,16 +0,0 @@
package appmessage
// MsgDoneIBDRootUTXOSetChunks represents a kaspa DoneIBDRootUTXOSetChunks message
type MsgDoneIBDRootUTXOSetChunks struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *MsgDoneIBDRootUTXOSetChunks) Command() MessageCommand {
return CmdDoneIBDRootUTXOSetChunks
}
// NewMsgDoneIBDRootUTXOSetChunks returns a new MsgDoneIBDRootUTXOSetChunks.
func NewMsgDoneIBDRootUTXOSetChunks() *MsgDoneIBDRootUTXOSetChunks {
return &MsgDoneIBDRootUTXOSetChunks{}
}

View File

@ -0,0 +1,16 @@
package appmessage
// MsgDonePruningPointUTXOSetChunks represents a kaspa DonePruningPointUTXOSetChunks message
type MsgDonePruningPointUTXOSetChunks struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *MsgDonePruningPointUTXOSetChunks) Command() MessageCommand {
return CmdDonePruningPointUTXOSetChunks
}
// NewMsgDonePruningPointUTXOSetChunks returns a new MsgDonePruningPointUTXOSetChunks.
func NewMsgDonePruningPointUTXOSetChunks() *MsgDonePruningPointUTXOSetChunks {
return &MsgDonePruningPointUTXOSetChunks{}
}

View File

@ -1,26 +0,0 @@
package appmessage
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MsgIBDRootHashMessage implements the Message interface and represents a kaspa
// IBDRootHash message. It is used as a reply to IBD root hash requests.
type MsgIBDRootHashMessage struct {
baseMessage
Hash *externalapi.DomainHash
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgIBDRootHashMessage) Command() MessageCommand {
return CmdIBDRootHash
}
// NewMsgIBDRootHashMessage returns a new kaspa IBDRootHash message that conforms to
// the Message interface. See MsgIBDRootHashMessage for details.
func NewMsgIBDRootHashMessage(hash *externalapi.DomainHash) *MsgIBDRootHashMessage {
return &MsgIBDRootHashMessage{
Hash: hash,
}
}

View File

@ -1,19 +0,0 @@
package appmessage
// MsgIBDRootUTXOSetChunk represents a kaspa IBDRootUTXOSetChunk message
type MsgIBDRootUTXOSetChunk struct {
baseMessage
Chunk []byte
}
// Command returns the protocol command string for the message
func (msg *MsgIBDRootUTXOSetChunk) Command() MessageCommand {
return CmdIBDRootUTXOSetChunk
}
// NewMsgIBDRootUTXOSetChunk returns a new MsgIBDRootUTXOSetChunk.
func NewMsgIBDRootUTXOSetChunk(chunk []byte) *MsgIBDRootUTXOSetChunk {
return &MsgIBDRootUTXOSetChunk{
Chunk: chunk,
}
}

View File

@ -0,0 +1,23 @@
package appmessage
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MsgPruningPointHashMessage represents a kaspa PruningPointHash message
type MsgPruningPointHashMessage struct {
baseMessage
Hash *externalapi.DomainHash
}
// Command returns the protocol command string for the message
func (msg *MsgPruningPointHashMessage) Command() MessageCommand {
return CmdPruningPointHash
}
// NewPruningPointHashMessage returns a new kaspa PruningPointHash message
func NewPruningPointHashMessage(hash *externalapi.DomainHash) *MsgPruningPointHashMessage {
return &MsgPruningPointHashMessage{
Hash: hash,
}
}

View File

@ -0,0 +1,36 @@
package appmessage
import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
// MsgPruningPointUTXOSetChunk represents a kaspa PruningPointUTXOSetChunk message
type MsgPruningPointUTXOSetChunk struct {
baseMessage
OutpointAndUTXOEntryPairs []*OutpointAndUTXOEntryPair
}
// Command returns the protocol command string for the message
func (msg *MsgPruningPointUTXOSetChunk) Command() MessageCommand {
return CmdPruningPointUTXOSetChunk
}
// NewMsgPruningPointUTXOSetChunk returns a new MsgPruningPointUTXOSetChunk.
func NewMsgPruningPointUTXOSetChunk(outpointAndUTXOEntryPairs []*OutpointAndUTXOEntryPair) *MsgPruningPointUTXOSetChunk {
return &MsgPruningPointUTXOSetChunk{
OutpointAndUTXOEntryPairs: outpointAndUTXOEntryPairs,
}
}
// OutpointAndUTXOEntryPair is an outpoint along with its
// respective UTXO entry
type OutpointAndUTXOEntryPair struct {
Outpoint *Outpoint
UTXOEntry *UTXOEntry
}
// UTXOEntry houses details about an individual transaction output in a UTXO
type UTXOEntry struct {
Amount uint64
ScriptPublicKey *externalapi.ScriptPublicKey
BlockBlueScore uint64
IsCoinbase bool
}

View File

@ -1,26 +0,0 @@
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,
}
}

View File

@ -1,16 +0,0 @@
package appmessage
// MsgRequestNextIBDRootUTXOSetChunk represents a kaspa RequestNextIBDRootUTXOSetChunk message
type MsgRequestNextIBDRootUTXOSetChunk struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *MsgRequestNextIBDRootUTXOSetChunk) Command() MessageCommand {
return CmdRequestNextIBDRootUTXOSetChunk
}
// NewMsgRequestNextIBDRootUTXOSetChunk returns a new MsgRequestNextIBDRootUTXOSetChunk.
func NewMsgRequestNextIBDRootUTXOSetChunk() *MsgRequestNextIBDRootUTXOSetChunk {
return &MsgRequestNextIBDRootUTXOSetChunk{}
}

View File

@ -0,0 +1,16 @@
package appmessage
// MsgRequestNextPruningPointUTXOSetChunk represents a kaspa RequestNextPruningPointUTXOSetChunk message
type MsgRequestNextPruningPointUTXOSetChunk struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *MsgRequestNextPruningPointUTXOSetChunk) Command() MessageCommand {
return CmdRequestNextPruningPointUTXOSetChunk
}
// NewMsgRequestNextPruningPointUTXOSetChunk returns a new MsgRequestNextPruningPointUTXOSetChunk.
func NewMsgRequestNextPruningPointUTXOSetChunk() *MsgRequestNextPruningPointUTXOSetChunk {
return &MsgRequestNextPruningPointUTXOSetChunk{}
}

View File

@ -0,0 +1,23 @@
package appmessage
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MsgRequestPruningPointUTXOSetAndBlock represents a kaspa RequestPruningPointUTXOSetAndBlock message
type MsgRequestPruningPointUTXOSetAndBlock struct {
baseMessage
PruningPointHash *externalapi.DomainHash
}
// Command returns the protocol command string for the message
func (msg *MsgRequestPruningPointUTXOSetAndBlock) Command() MessageCommand {
return CmdRequestPruningPointUTXOSetAndBlock
}
// NewMsgRequestPruningPointUTXOSetAndBlock returns a new MsgRequestPruningPointUTXOSetAndBlock
func NewMsgRequestPruningPointUTXOSetAndBlock(pruningPointHash *externalapi.DomainHash) *MsgRequestPruningPointUTXOSetAndBlock {
return &MsgRequestPruningPointUTXOSetAndBlock{
PruningPointHash: pruningPointHash,
}
}

View File

@ -1,22 +0,0 @@
package appmessage
// MsgRequestIBDRootHashMessage implements the Message interface and represents a kaspa
// MsgRequestIBDRootHashMessage message. It is used to request the IBD root hash
// from a peer during IBD.
//
// This message has no payload.
type MsgRequestIBDRootHashMessage struct {
baseMessage
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgRequestIBDRootHashMessage) Command() MessageCommand {
return CmdRequestIBDRootHash
}
// NewMsgRequestIBDRootHashMessage returns a new kaspa RequestIBDRootHash message that conforms to the
// Message interface.
func NewMsgRequestIBDRootHashMessage() *MsgRequestIBDRootHashMessage {
return &MsgRequestIBDRootHashMessage{}
}

View File

@ -0,0 +1,16 @@
package appmessage
// MsgRequestPruningPointHashMessage represents a kaspa RequestPruningPointHashMessage message
type MsgRequestPruningPointHashMessage struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *MsgRequestPruningPointHashMessage) Command() MessageCommand {
return CmdRequestPruningPointHash
}
// NewMsgRequestPruningPointHashMessage returns a new kaspa RequestPruningPointHash message
func NewMsgRequestPruningPointHashMessage() *MsgRequestPruningPointHashMessage {
return &MsgRequestPruningPointHashMessage{}
}

View File

@ -0,0 +1,16 @@
package appmessage
// MsgUnexpectedPruningPoint represents a kaspa UnexpectedPruningPoint message
type MsgUnexpectedPruningPoint struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *MsgUnexpectedPruningPoint) Command() MessageCommand {
return CmdUnexpectedPruningPoint
}
// NewMsgUnexpectedPruningPoint returns a new kaspa UnexpectedPruningPoint message
func NewMsgUnexpectedPruningPoint() *MsgUnexpectedPruningPoint {
return &MsgUnexpectedPruningPoint{}
}

View File

@ -1,51 +0,0 @@
package blockrelay
import (
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/domain"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
)
// HandleIBDRootHashRequestsFlowContext is the interface for the context needed for the handleIBDRootHashRequestsFlow flow.
type HandleIBDRootHashRequestsFlowContext interface {
Domain() domain.Domain
}
type handleIBDRootHashRequestsFlow struct {
HandleIBDRootHashRequestsFlowContext
incomingRoute, outgoingRoute *router.Route
}
// HandleIBDRootHashRequests listens to appmessage.MsgRequestIBDRootHashMessage messages and sends
// the IBD root hash as response.
func HandleIBDRootHashRequests(context HandleIBDRootHashRequestsFlowContext, incomingRoute,
outgoingRoute *router.Route) error {
flow := &handleIBDRootHashRequestsFlow{
HandleIBDRootHashRequestsFlowContext: context,
incomingRoute: incomingRoute,
outgoingRoute: outgoingRoute,
}
return flow.start()
}
func (flow *handleIBDRootHashRequestsFlow) start() error {
for {
_, err := flow.incomingRoute.Dequeue()
if err != nil {
return err
}
log.Debugf("Got request for IBD root hash")
pruningPoint, err := flow.Domain().Consensus().PruningPoint()
if err != nil {
return err
}
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgIBDRootHashMessage(pruningPoint))
if err != nil {
return err
}
log.Debugf("Sent IBD root hash %s", pruningPoint)
}
}

View File

@ -0,0 +1,51 @@
package blockrelay
import (
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/domain"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
)
// HandlePruningPointHashRequestsFlowContext is the interface for the context needed for the handlePruningPointHashRequestsFlow flow.
type HandlePruningPointHashRequestsFlowContext interface {
Domain() domain.Domain
}
type handlePruningPointHashRequestsFlow struct {
HandlePruningPointHashRequestsFlowContext
incomingRoute, outgoingRoute *router.Route
}
// HandlePruningPointHashRequests listens to appmessage.MsgRequestPruningPointHashMessage messages and sends
// the pruning point hash as response.
func HandlePruningPointHashRequests(context HandlePruningPointHashRequestsFlowContext, incomingRoute,
outgoingRoute *router.Route) error {
flow := &handlePruningPointHashRequestsFlow{
HandlePruningPointHashRequestsFlowContext: context,
incomingRoute: incomingRoute,
outgoingRoute: outgoingRoute,
}
return flow.start()
}
func (flow *handlePruningPointHashRequestsFlow) start() error {
for {
_, err := flow.incomingRoute.Dequeue()
if err != nil {
return err
}
log.Debugf("Got request for a pruning point hash")
pruningPoint, err := flow.Domain().Consensus().PruningPoint()
if err != nil {
return err
}
err = flow.outgoingRoute.Enqueue(appmessage.NewPruningPointHashMessage(pruningPoint))
if err != nil {
return err
}
log.Debugf("Sent pruning point hash %s", pruningPoint)
}
}

View File

@ -1,117 +0,0 @@
package blockrelay
import (
"errors"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/common"
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
"github.com/kaspanet/kaspad/domain"
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
"github.com/kaspanet/kaspad/infrastructure/logger"
"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, ok := message.(*appmessage.MsgRequestIBDRootUTXOSetAndBlock)
if !ok {
return protocolerrors.Errorf(true, "received unexpected message type. "+
"expected: %s, got: %s", appmessage.CmdRequestIBDRootUTXOSetAndBlock, message.Command())
}
finishMeasuring := logger.LogAndMeasureExecutionTime(log, "handleRequestIBDRootUTXOSetAndBlockFlow")
log.Debugf("Got request for IBDRoot UTXOSet and Block")
serializedUTXOSet, 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
}
}
log.Debugf("Retrieved utxo set for pruning block %s", msgRequestIBDRootUTXOSetAndBlock.IBDRoot)
block, err := flow.Domain().Consensus().GetBlock(msgRequestIBDRootUTXOSetAndBlock.IBDRoot)
if err != nil {
return err
}
log.Debugf("Retrieved pruning block %s", msgRequestIBDRootUTXOSetAndBlock.IBDRoot)
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgIBDBlock(appmessage.DomainBlockToMsgBlock(block)))
if err != nil {
return err
}
// Send the UTXO set in `step`-sized chunks
const step = 1024 * 1024 // 1MB
offset := 0
chunksSent := 0
for offset < len(serializedUTXOSet) {
var chunk []byte
if offset+step < len(serializedUTXOSet) {
chunk = serializedUTXOSet[offset : offset+step]
} else {
chunk = serializedUTXOSet[offset:]
}
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgIBDRootUTXOSetChunk(chunk))
if err != nil {
return err
}
offset += step
chunksSent++
// Wait for the peer to request more chunks every `ibdBatchSize` chunks
if chunksSent%ibdBatchSize == 0 {
message, err := flow.incomingRoute.DequeueWithTimeout(common.DefaultTimeout)
if err != nil {
return err
}
_, ok := message.(*appmessage.MsgRequestNextIBDRootUTXOSetChunk)
if !ok {
return protocolerrors.Errorf(true, "received unexpected message type. "+
"expected: %s, got: %s", appmessage.CmdRequestNextIBDRootUTXOSetChunk, message.Command())
}
}
}
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgDoneIBDRootUTXOSetChunks())
if err != nil {
return err
}
finishMeasuring()
}
}

View File

@ -0,0 +1,143 @@
package blockrelay
import (
"errors"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/common"
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
"github.com/kaspanet/kaspad/domain"
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
)
// HandleRequestPruningPointUTXOSetAndBlockContext is the interface for the context needed for the HandleRequestPruningPointUTXOSetAndBlock flow.
type HandleRequestPruningPointUTXOSetAndBlockContext interface {
Domain() domain.Domain
}
type handleRequestPruningPointUTXOSetAndBlockFlow struct {
HandleRequestPruningPointUTXOSetAndBlockContext
incomingRoute, outgoingRoute *router.Route
}
// HandleRequestPruningPointUTXOSetAndBlock listens to appmessage.MsgRequestPruningPointUTXOSetAndBlock messages and sends
// the pruning point UTXO set and block body.
func HandleRequestPruningPointUTXOSetAndBlock(context HandleRequestPruningPointUTXOSetAndBlockContext, incomingRoute,
outgoingRoute *router.Route) error {
flow := &handleRequestPruningPointUTXOSetAndBlockFlow{
HandleRequestPruningPointUTXOSetAndBlockContext: context,
incomingRoute: incomingRoute,
outgoingRoute: outgoingRoute,
}
return flow.start()
}
func (flow *handleRequestPruningPointUTXOSetAndBlockFlow) start() error {
for {
msgRequestPruningPointUTXOSetAndBlock, err := flow.waitForRequestPruningPointUTXOSetAndBlockMessages()
if err != nil {
return err
}
err = flow.handleRequestPruningPointUTXOSetAndBlockMessage(msgRequestPruningPointUTXOSetAndBlock)
if err != nil {
return err
}
}
}
func (flow *handleRequestPruningPointUTXOSetAndBlockFlow) handleRequestPruningPointUTXOSetAndBlockMessage(
msgRequestPruningPointUTXOSetAndBlock *appmessage.MsgRequestPruningPointUTXOSetAndBlock) error {
onEnd := logger.LogAndMeasureExecutionTime(log, "handleRequestPruningPointUTXOSetAndBlockFlow")
defer onEnd()
log.Debugf("Got request for PruningPointHash UTXOSet and Block")
err := flow.sendPruningPointBlock(msgRequestPruningPointUTXOSetAndBlock)
if err != nil {
return err
}
return flow.sendPruningPointUTXOSet(msgRequestPruningPointUTXOSetAndBlock)
}
func (flow *handleRequestPruningPointUTXOSetAndBlockFlow) waitForRequestPruningPointUTXOSetAndBlockMessages() (
*appmessage.MsgRequestPruningPointUTXOSetAndBlock, error) {
message, err := flow.incomingRoute.Dequeue()
if err != nil {
return nil, err
}
msgRequestPruningPointUTXOSetAndBlock, ok := message.(*appmessage.MsgRequestPruningPointUTXOSetAndBlock)
if !ok {
return nil, protocolerrors.Errorf(true, "received unexpected message type. "+
"expected: %s, got: %s", appmessage.CmdRequestPruningPointUTXOSetAndBlock, message.Command())
}
return msgRequestPruningPointUTXOSetAndBlock, nil
}
func (flow *handleRequestPruningPointUTXOSetAndBlockFlow) sendPruningPointBlock(
msgRequestPruningPointUTXOSetAndBlock *appmessage.MsgRequestPruningPointUTXOSetAndBlock) error {
block, err := flow.Domain().Consensus().GetBlock(msgRequestPruningPointUTXOSetAndBlock.PruningPointHash)
if err != nil {
return err
}
log.Debugf("Retrieved pruning block %s", msgRequestPruningPointUTXOSetAndBlock.PruningPointHash)
return flow.outgoingRoute.Enqueue(appmessage.NewMsgIBDBlock(appmessage.DomainBlockToMsgBlock(block)))
}
func (flow *handleRequestPruningPointUTXOSetAndBlockFlow) sendPruningPointUTXOSet(
msgRequestPruningPointUTXOSetAndBlock *appmessage.MsgRequestPruningPointUTXOSetAndBlock) error {
// Send the UTXO set in `step`-sized chunks
const step = 1000
offset := 0
chunksSent := 0
for {
pruningPointUTXOs, err := flow.Domain().Consensus().GetPruningPointUTXOs(
msgRequestPruningPointUTXOSetAndBlock.PruningPointHash, offset, step)
if err != nil {
if errors.Is(err, ruleerrors.ErrWrongPruningPointHash) {
return flow.outgoingRoute.Enqueue(appmessage.NewMsgUnexpectedPruningPoint())
}
}
log.Debugf("Retrieved %d UTXOs for pruning block %s",
len(pruningPointUTXOs), msgRequestPruningPointUTXOSetAndBlock.PruningPointHash)
outpointAndUTXOEntryPairs :=
appmessage.DomainOutpointAndUTXOEntryPairsToOutpointAndUTXOEntryPairs(pruningPointUTXOs)
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgPruningPointUTXOSetChunk(outpointAndUTXOEntryPairs))
if err != nil {
return err
}
if len(pruningPointUTXOs) < step {
log.Debugf("Finished sending UTXOs for pruning block %s",
msgRequestPruningPointUTXOSetAndBlock.PruningPointHash)
return flow.outgoingRoute.Enqueue(appmessage.NewMsgDonePruningPointUTXOSetChunks())
}
offset += step
chunksSent++
// Wait for the peer to request more chunks every `ibdBatchSize` chunks
if chunksSent%ibdBatchSize == 0 {
message, err := flow.incomingRoute.DequeueWithTimeout(common.DefaultTimeout)
if err != nil {
return err
}
_, ok := message.(*appmessage.MsgRequestNextPruningPointUTXOSetChunk)
if !ok {
return protocolerrors.Errorf(true, "received unexpected message type. "+
"expected: %s, got: %s", appmessage.CmdRequestNextPruningPointUTXOSetChunk, message.Command())
}
}
}
}

View File

@ -1,6 +1,7 @@
package blockrelay package blockrelay
import ( import (
"fmt"
"github.com/kaspanet/kaspad/infrastructure/logger" "github.com/kaspanet/kaspad/infrastructure/logger"
"time" "time"
@ -288,7 +289,7 @@ func (flow *handleRelayInvsFlow) processHeader(msgBlockHeader *appmessage.MsgBlo
func (flow *handleRelayInvsFlow) syncPruningPointUTXOSet() (bool, error) { func (flow *handleRelayInvsFlow) syncPruningPointUTXOSet() (bool, error) {
log.Debugf("Checking if a new pruning point is available") log.Debugf("Checking if a new pruning point is available")
err := flow.outgoingRoute.Enqueue(appmessage.NewMsgRequestIBDRootHashMessage()) err := flow.outgoingRoute.Enqueue(appmessage.NewMsgRequestPruningPointHashMessage())
if err != nil { if err != nil {
return false, err return false, err
} }
@ -296,36 +297,36 @@ func (flow *handleRelayInvsFlow) syncPruningPointUTXOSet() (bool, error) {
if err != nil { if err != nil {
return false, err return false, err
} }
msgIBDRootHash, ok := message.(*appmessage.MsgIBDRootHashMessage) msgPruningPointHash, ok := message.(*appmessage.MsgPruningPointHashMessage)
if !ok { if !ok {
return false, protocolerrors.Errorf(true, "received unexpected message type. "+ return false, protocolerrors.Errorf(true, "received unexpected message type. "+
"expected: %s, got: %s", appmessage.CmdIBDRootHash, message.Command()) "expected: %s, got: %s", appmessage.CmdPruningPointHash, message.Command())
} }
blockInfo, err := flow.Domain().Consensus().GetBlockInfo(msgIBDRootHash.Hash) blockInfo, err := flow.Domain().Consensus().GetBlockInfo(msgPruningPointHash.Hash)
if err != nil { if err != nil {
return false, err return false, err
} }
if blockInfo.BlockStatus != externalapi.StatusHeaderOnly { if blockInfo.BlockStatus != externalapi.StatusHeaderOnly {
log.Debugf("Already has the block data of the new suggested pruning point %s", msgIBDRootHash.Hash) log.Debugf("Already has the block data of the new suggested pruning point %s", msgPruningPointHash.Hash)
return true, nil return true, nil
} }
log.Infof("Checking if the suggested pruning point %s is compatible to the node DAG", msgIBDRootHash.Hash) log.Infof("Checking if the suggested pruning point %s is compatible to the node DAG", msgPruningPointHash.Hash)
isValid, err := flow.Domain().Consensus().IsValidPruningPoint(msgIBDRootHash.Hash) isValid, err := flow.Domain().Consensus().IsValidPruningPoint(msgPruningPointHash.Hash)
if err != nil { if err != nil {
return false, err return false, err
} }
if !isValid { if !isValid {
log.Infof("The suggested pruning point %s is incompatible to this node DAG, so stopping IBD with this"+ log.Infof("The suggested pruning point %s is incompatible to this node DAG, so stopping IBD with this"+
" peer", msgIBDRootHash.Hash) " peer", msgPruningPointHash.Hash)
return false, nil return false, nil
} }
log.Info("Fetching the pruning point UTXO set") log.Info("Fetching the pruning point UTXO set")
succeed, err := flow.fetchMissingUTXOSet(msgIBDRootHash.Hash) succeed, err := flow.fetchMissingUTXOSet(msgPruningPointHash.Hash)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -339,94 +340,118 @@ func (flow *handleRelayInvsFlow) syncPruningPointUTXOSet() (bool, error) {
return true, nil return true, nil
} }
func (flow *handleRelayInvsFlow) fetchMissingUTXOSet(ibdRootHash *externalapi.DomainHash) (succeed bool, err error) { func (flow *handleRelayInvsFlow) fetchMissingUTXOSet(pruningPointHash *externalapi.DomainHash) (succeed bool, err error) {
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgRequestIBDRootUTXOSetAndBlock(ibdRootHash)) defer func() {
err := flow.Domain().Consensus().ClearImportedPruningPointData()
if err != nil {
panic(fmt.Sprintf("failed to clear imported pruning point data: %s", err))
}
}()
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgRequestPruningPointUTXOSetAndBlock(pruningPointHash))
if err != nil { if err != nil {
return false, err return false, err
} }
utxoSet, block, found, err := flow.receiveIBDRootUTXOSetAndBlock() block, err := flow.receivePruningPointBlock()
if err != nil { if err != nil {
return false, err return false, err
} }
if !found { receivedAll, err := flow.receiveAndInsertPruningPointUTXOSet(pruningPointHash)
if err != nil {
return false, err
}
if !receivedAll {
return false, nil return false, nil
} }
err = flow.Domain().Consensus().ValidateAndInsertPruningPoint(block, utxoSet) err = flow.Domain().Consensus().ValidateAndInsertImportedPruningPoint(block)
if err != nil { if err != nil {
// TODO: Find a better way to deal with finality conflicts. // TODO: Find a better way to deal with finality conflicts.
if errors.Is(err, ruleerrors.ErrSuggestedPruningViolatesFinality) { if errors.Is(err, ruleerrors.ErrSuggestedPruningViolatesFinality) {
return false, nil return false, nil
} }
return false, protocolerrors.ConvertToBanningProtocolErrorIfRuleError(err, "error with IBD root UTXO set") return false, protocolerrors.ConvertToBanningProtocolErrorIfRuleError(err, "error with pruning point UTXO set")
} }
return true, nil return true, nil
} }
func (flow *handleRelayInvsFlow) receiveIBDRootUTXOSetAndBlock() ([]byte, *externalapi.DomainBlock, bool, error) { func (flow *handleRelayInvsFlow) receivePruningPointBlock() (*externalapi.DomainBlock, error) {
onEnd := logger.LogAndMeasureExecutionTime(log, "receiveIBDRootUTXOSetAndBlock") onEnd := logger.LogAndMeasureExecutionTime(log, "receivePruningPointBlock")
defer onEnd() defer onEnd()
message, err := flow.dequeueIncomingMessageAndSkipInvs(common.DefaultTimeout) message, err := flow.dequeueIncomingMessageAndSkipInvs(common.DefaultTimeout)
if err != nil { if err != nil {
return nil, nil, false, err return nil, err
} }
var block *externalapi.DomainBlock ibdBlockMessage, ok := message.(*appmessage.MsgIBDBlock)
switch message := message.(type) { if !ok {
case *appmessage.MsgIBDBlock: return nil, protocolerrors.Errorf(true, "received unexpected message type. "+
block = appmessage.MsgBlockToDomainBlock(message.MsgBlock) "expected: %s, got: %s", appmessage.CmdIBDBlock, message.Command())
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.CmdIBDBlock, appmessage.CmdIBDRootNotFound, message.Command(),
)
} }
log.Debugf("Received IBD root block %s", consensushashing.BlockHash(block)) block := appmessage.MsgBlockToDomainBlock(ibdBlockMessage.MsgBlock)
log.Debugf("Received pruning point block %s", consensushashing.BlockHash(block))
return block, nil
}
func (flow *handleRelayInvsFlow) receiveAndInsertPruningPointUTXOSet(
pruningPointHash *externalapi.DomainHash) (bool, error) {
onEnd := logger.LogAndMeasureExecutionTime(log, "receiveAndInsertPruningPointUTXOSet")
defer onEnd()
serializedUTXOSet := []byte{}
receivedAllChunks := false
receivedChunkCount := 0 receivedChunkCount := 0
for !receivedAllChunks { receivedUTXOCount := 0
for {
message, err := flow.dequeueIncomingMessageAndSkipInvs(common.DefaultTimeout) message, err := flow.dequeueIncomingMessageAndSkipInvs(common.DefaultTimeout)
if err != nil { if err != nil {
return nil, nil, false, err return false, err
} }
switch message := message.(type) { switch message := message.(type) {
case *appmessage.MsgIBDRootUTXOSetChunk: case *appmessage.MsgPruningPointUTXOSetChunk:
serializedUTXOSet = append(serializedUTXOSet, message.Chunk...) receivedUTXOCount += len(message.OutpointAndUTXOEntryPairs)
case *appmessage.MsgDoneIBDRootUTXOSetChunks: domainOutpointAndUTXOEntryPairs :=
receivedAllChunks = true appmessage.OutpointAndUTXOEntryPairsToDomainOutpointAndUTXOEntryPairs(message.OutpointAndUTXOEntryPairs)
default:
return nil, nil, false,
protocolerrors.Errorf(true, "received unexpected message type. "+
"expected: %s or %s, got: %s",
appmessage.CmdIBDRootUTXOSetChunk, appmessage.CmdDoneIBDRootUTXOSetChunks, message.Command(),
)
}
receivedChunkCount++ err := flow.Domain().Consensus().AppendImportedPruningPointUTXOs(domainOutpointAndUTXOEntryPairs)
if !receivedAllChunks && receivedChunkCount%ibdBatchSize == 0 {
log.Debugf("Received %d UTXO set chunks so far, totaling in %d bytes",
receivedChunkCount, len(serializedUTXOSet))
requestNextIBDRootUTXOSetChunkMessage := appmessage.NewMsgRequestNextIBDRootUTXOSetChunk()
err := flow.outgoingRoute.Enqueue(requestNextIBDRootUTXOSetChunkMessage)
if err != nil { if err != nil {
return nil, nil, false, err return false, err
} }
receivedChunkCount++
if receivedChunkCount%ibdBatchSize == 0 {
log.Debugf("Received %d UTXO set chunks so far, totaling in %d UTXOs",
receivedChunkCount, receivedUTXOCount)
requestNextPruningPointUTXOSetChunkMessage := appmessage.NewMsgRequestNextPruningPointUTXOSetChunk()
err := flow.outgoingRoute.Enqueue(requestNextPruningPointUTXOSetChunkMessage)
if err != nil {
return false, err
}
}
case *appmessage.MsgDonePruningPointUTXOSetChunks:
log.Debugf("Finished receiving the UTXO set. Total UTXOs: %d", receivedUTXOCount)
return true, nil
case *appmessage.MsgUnexpectedPruningPoint:
log.Debugf("Could not receive the next UTXO chunk because the pruning point %s "+
"is no longer the pruning point of peer %s", pruningPointHash, flow.peer)
return false, nil
default:
return false, protocolerrors.Errorf(true, "received unexpected message type. "+
"expected: %s or %s or %s, got: %s", appmessage.CmdPruningPointUTXOSetChunk,
appmessage.CmdDonePruningPointUTXOSetChunks, appmessage.CmdUnexpectedPruningPoint, message.Command(),
)
} }
} }
log.Debugf("Finished receiving the UTXO set. Total bytes: %d", len(serializedUTXOSet))
return serializedUTXOSet, block, true, nil
} }
func (flow *handleRelayInvsFlow) syncMissingBlockBodies(highHash *externalapi.DomainHash) error { func (flow *handleRelayInvsFlow) syncMissingBlockBodies(highHash *externalapi.DomainHash) error {

View File

@ -137,9 +137,9 @@ func (m *Manager) registerBlockRelayFlows(router *routerpkg.Router, isStopping *
return []*flow{ return []*flow{
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.CmdIBDRootNotFound, appmessage.CmdIBDRootUTXOSetChunk, appmessage.CmdDoneHeaders, appmessage.CmdUnexpectedPruningPoint, appmessage.CmdPruningPointUTXOSetChunk,
appmessage.CmdBlockHeaders, appmessage.CmdIBDRootHash, appmessage.CmdIBDBlockLocatorHighestHash, appmessage.CmdBlockHeaders, appmessage.CmdPruningPointHash, appmessage.CmdIBDBlockLocatorHighestHash,
appmessage.CmdDoneIBDRootUTXOSetChunks}, 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)
@ -166,11 +166,11 @@ func (m *Manager) registerBlockRelayFlows(router *routerpkg.Router, isStopping *
}, },
), ),
m.registerFlow("HandleRequestIBDRootUTXOSetAndBlock", router, m.registerFlow("HandleRequestPruningPointUTXOSetAndBlock", router,
[]appmessage.MessageCommand{appmessage.CmdRequestIBDRootUTXOSetAndBlock, []appmessage.MessageCommand{appmessage.CmdRequestPruningPointUTXOSetAndBlock,
appmessage.CmdRequestNextIBDRootUTXOSetChunk}, isStopping, errChan, appmessage.CmdRequestNextPruningPointUTXOSetChunk}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error { func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return blockrelay.HandleRequestIBDRootUTXOSetAndBlock(m.context, incomingRoute, outgoingRoute) return blockrelay.HandleRequestPruningPointUTXOSetAndBlock(m.context, incomingRoute, outgoingRoute)
}, },
), ),
@ -181,10 +181,10 @@ func (m *Manager) registerBlockRelayFlows(router *routerpkg.Router, isStopping *
}, },
), ),
m.registerFlow("HandleIBDRootHashRequests", router, m.registerFlow("HandlePruningPointHashRequests", router,
[]appmessage.MessageCommand{appmessage.CmdRequestIBDRootHash}, isStopping, errChan, []appmessage.MessageCommand{appmessage.CmdRequestPruningPointHash}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error { func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return blockrelay.HandleIBDRootHashRequests(m.context, incomingRoute, outgoingRoute) return blockrelay.HandlePruningPointHashRequests(m.context, incomingRoute, outgoingRoute)
}, },
), ),

View File

@ -199,7 +199,9 @@ func (s *consensus) GetMissingBlockBodyHashes(highHash *externalapi.DomainHash)
return s.syncManager.GetMissingBlockBodyHashes(highHash) return s.syncManager.GetMissingBlockBodyHashes(highHash)
} }
func (s *consensus) GetPruningPointUTXOSet(expectedPruningPointHash *externalapi.DomainHash) ([]byte, error) { func (s *consensus) GetPruningPointUTXOs(expectedPruningPointHash *externalapi.DomainHash,
offset int, limit int) ([]*externalapi.OutpointAndUTXOEntryPair, error) {
s.lock.Lock() s.lock.Lock()
defer s.lock.Unlock() defer s.lock.Unlock()
@ -214,11 +216,11 @@ func (s *consensus) GetPruningPointUTXOSet(expectedPruningPointHash *externalapi
pruningPointHash) pruningPointHash)
} }
serializedUTXOSet, err := s.pruningStore.PruningPointSerializedUTXOSet(s.databaseContext) pruningPointUTXOs, err := s.pruningStore.PruningPointUTXOs(s.databaseContext, offset, limit)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return serializedUTXOSet, nil return pruningPointUTXOs, nil
} }
func (s *consensus) PruningPoint() (*externalapi.DomainHash, error) { func (s *consensus) PruningPoint() (*externalapi.DomainHash, error) {
@ -228,11 +230,25 @@ func (s *consensus) PruningPoint() (*externalapi.DomainHash, error) {
return s.pruningStore.PruningPoint(s.databaseContext) return s.pruningStore.PruningPoint(s.databaseContext)
} }
func (s *consensus) ValidateAndInsertPruningPoint(newPruningPoint *externalapi.DomainBlock, serializedUTXOSet []byte) error { func (s *consensus) ClearImportedPruningPointData() error {
s.lock.Lock() s.lock.Lock()
defer s.lock.Unlock() defer s.lock.Unlock()
return s.blockProcessor.ValidateAndInsertPruningPoint(newPruningPoint, serializedUTXOSet) return s.pruningManager.ClearImportedPruningPointData()
}
func (s *consensus) AppendImportedPruningPointUTXOs(outpointAndUTXOEntryPairs []*externalapi.OutpointAndUTXOEntryPair) error {
s.lock.Lock()
defer s.lock.Unlock()
return s.pruningManager.AppendImportedPruningPointUTXOs(outpointAndUTXOEntryPairs)
}
func (s *consensus) ValidateAndInsertImportedPruningPoint(newPruningPoint *externalapi.DomainBlock) error {
s.lock.Lock()
defer s.lock.Unlock()
return s.blockProcessor.ValidateAndInsertImportedPruningPoint(newPruningPoint)
} }
func (s *consensus) GetVirtualSelectedParent() (*externalapi.DomainHash, error) { func (s *consensus) GetVirtualSelectedParent() (*externalapi.DomainHash, error) {

View File

@ -17,6 +17,14 @@ func (dbw *dbManager) Has(key model.DBKey) (bool, error) {
return dbw.db.Has(dbKeyToDatabaseKey(key)) return dbw.db.Has(dbKeyToDatabaseKey(key))
} }
func (dbw *dbManager) Put(key model.DBKey, value []byte) error {
return dbw.db.Put(dbKeyToDatabaseKey(key), value)
}
func (dbw *dbManager) Delete(key model.DBKey) error {
return dbw.db.Delete(dbKeyToDatabaseKey(key))
}
func (dbw *dbManager) Cursor(bucket model.DBBucket) (model.DBCursor, error) { func (dbw *dbManager) Cursor(bucket model.DBBucket) (model.DBCursor, error) {
cursor, err := dbw.db.Cursor(dbBucketToDatabaseBucket(bucket)) cursor, err := dbw.db.Cursor(dbBucketToDatabaseBucket(bucket))
if err != nil { if err != nil {

View File

@ -10,7 +10,7 @@ func utxoCollectionToDBUTXOCollection(utxoCollection model.UTXOCollection) ([]*D
items := make([]*DbUtxoCollectionItem, utxoCollection.Len()) items := make([]*DbUtxoCollectionItem, utxoCollection.Len())
i := 0 i := 0
utxoIterator := utxoCollection.Iterator() utxoIterator := utxoCollection.Iterator()
for utxoIterator.Next() { for ok := utxoIterator.First(); ok; ok = utxoIterator.Next() {
outpoint, entry, err := utxoIterator.Get() outpoint, entry, err := utxoIterator.Get()
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -11,7 +11,6 @@ type consensusStateStore struct {
tipsStaging []*externalapi.DomainHash tipsStaging []*externalapi.DomainHash
virtualDiffParentsStaging []*externalapi.DomainHash virtualDiffParentsStaging []*externalapi.DomainHash
virtualUTXODiffStaging model.UTXODiff virtualUTXODiffStaging model.UTXODiff
virtualUTXOSetStaging model.UTXOCollection
virtualUTXOSetCache *utxolrucache.LRUCache virtualUTXOSetCache *utxolrucache.LRUCache
@ -30,7 +29,6 @@ func (css *consensusStateStore) Discard() {
css.tipsStaging = nil css.tipsStaging = nil
css.virtualUTXODiffStaging = nil css.virtualUTXODiffStaging = nil
css.virtualDiffParentsStaging = nil css.virtualDiffParentsStaging = nil
css.virtualUTXOSetStaging = nil
} }
func (css *consensusStateStore) Commit(dbTx model.DBTransaction) error { func (css *consensusStateStore) Commit(dbTx model.DBTransaction) error {
@ -48,11 +46,6 @@ func (css *consensusStateStore) Commit(dbTx model.DBTransaction) error {
return err return err
} }
err = css.commitVirtualUTXOSet(dbTx)
if err != nil {
return err
}
css.Discard() css.Discard()
return nil return nil

View File

@ -19,22 +19,25 @@ func utxoKey(outpoint *externalapi.DomainOutpoint) (model.DBKey, error) {
return utxoSetBucket.Key(serializedOutpoint), nil return utxoSetBucket.Key(serializedOutpoint), nil
} }
func (css *consensusStateStore) StageVirtualUTXODiff(virtualUTXODiff model.UTXODiff) error { func (css *consensusStateStore) StageVirtualUTXODiff(virtualUTXODiff model.UTXODiff) {
if css.virtualUTXOSetStaging != nil {
return errors.New("cannot stage virtual UTXO diff while virtual UTXO set is staged")
}
css.virtualUTXODiffStaging = virtualUTXODiff css.virtualUTXODiffStaging = virtualUTXODiff
return nil
} }
func (css *consensusStateStore) commitVirtualUTXODiff(dbTx model.DBTransaction) error { func (css *consensusStateStore) commitVirtualUTXODiff(dbTx model.DBTransaction) error {
hadStartedImportingPruningPointUTXOSet, err := css.HadStartedImportingPruningPointUTXOSet(dbTx)
if err != nil {
return err
}
if hadStartedImportingPruningPointUTXOSet {
return errors.New("cannot commit virtual UTXO diff after starting to import the pruning point UTXO set")
}
if css.virtualUTXODiffStaging == nil { if css.virtualUTXODiffStaging == nil {
return nil return nil
} }
toRemoveIterator := css.virtualUTXODiffStaging.ToRemove().Iterator() toRemoveIterator := css.virtualUTXODiffStaging.ToRemove().Iterator()
for toRemoveIterator.Next() { for ok := toRemoveIterator.First(); ok; ok = toRemoveIterator.Next() {
toRemoveOutpoint, _, err := toRemoveIterator.Get() toRemoveOutpoint, _, err := toRemoveIterator.Get()
if err != nil { if err != nil {
return err return err
@ -53,7 +56,7 @@ func (css *consensusStateStore) commitVirtualUTXODiff(dbTx model.DBTransaction)
} }
toAddIterator := css.virtualUTXODiffStaging.ToAdd().Iterator() toAddIterator := css.virtualUTXODiffStaging.ToAdd().Iterator()
for toAddIterator.Next() { for ok := toAddIterator.First(); ok; ok = toAddIterator.Next() {
toAddOutpoint, toAddEntry, err := toAddIterator.Get() toAddOutpoint, toAddEntry, err := toAddIterator.Get()
if err != nil { if err != nil {
return err return err
@ -80,63 +83,9 @@ func (css *consensusStateStore) commitVirtualUTXODiff(dbTx model.DBTransaction)
return nil return nil
} }
func (css *consensusStateStore) commitVirtualUTXOSet(dbTx model.DBTransaction) error {
if css.virtualUTXOSetStaging == nil {
return nil
}
// Clear the existing virtual utxo set in database before adding the new one
cursor, err := dbTx.Cursor(utxoSetBucket)
if err != nil {
return err
}
for cursor.Next() {
key, err := cursor.Key()
if err != nil {
return err
}
err = dbTx.Delete(key)
if err != nil {
return err
}
}
// Now put the new virtualUTXOSet into the database
css.virtualUTXOSetCache.Clear()
iterator := css.virtualUTXOSetStaging.Iterator()
for iterator.Next() {
outpoint, utxoEntry, err := iterator.Get()
if err != nil {
return err
}
css.virtualUTXOSetCache.Add(outpoint, utxoEntry)
dbKey, err := utxoKey(outpoint)
if err != nil {
return err
}
serializedEntry, err := serializeUTXOEntry(utxoEntry)
if err != nil {
return err
}
err = dbTx.Put(dbKey, serializedEntry)
if err != nil {
return err
}
}
// Note: we don't discard the staging here since that's
// being done at the end of Commit()
return nil
}
func (css *consensusStateStore) UTXOByOutpoint(dbContext model.DBReader, outpoint *externalapi.DomainOutpoint) ( func (css *consensusStateStore) UTXOByOutpoint(dbContext model.DBReader, outpoint *externalapi.DomainOutpoint) (
externalapi.UTXOEntry, error) { externalapi.UTXOEntry, error) {
if css.virtualUTXOSetStaging != nil {
return css.utxoByOutpointFromStagedVirtualUTXOSet(outpoint)
}
return css.utxoByOutpointFromStagedVirtualUTXODiff(dbContext, outpoint) return css.utxoByOutpointFromStagedVirtualUTXODiff(dbContext, outpoint)
} }
@ -176,20 +125,7 @@ func (css *consensusStateStore) utxoByOutpointFromStagedVirtualUTXODiff(dbContex
return entry, nil return entry, nil
} }
func (css *consensusStateStore) utxoByOutpointFromStagedVirtualUTXOSet(outpoint *externalapi.DomainOutpoint) (
externalapi.UTXOEntry, error) {
if utxoEntry, ok := css.virtualUTXOSetStaging.Get(outpoint); ok {
return utxoEntry, nil
}
return nil, errors.Errorf("outpoint was not found")
}
func (css *consensusStateStore) HasUTXOByOutpoint(dbContext model.DBReader, outpoint *externalapi.DomainOutpoint) (bool, error) { func (css *consensusStateStore) HasUTXOByOutpoint(dbContext model.DBReader, outpoint *externalapi.DomainOutpoint) (bool, error) {
if css.virtualUTXOSetStaging != nil {
return css.hasUTXOByOutpointFromStagedVirtualUTXOSet(outpoint), nil
}
return css.hasUTXOByOutpointFromStagedVirtualUTXODiff(dbContext, outpoint) return css.hasUTXOByOutpointFromStagedVirtualUTXODiff(dbContext, outpoint)
} }
@ -213,10 +149,6 @@ func (css *consensusStateStore) hasUTXOByOutpointFromStagedVirtualUTXODiff(dbCon
return dbContext.Has(key) return dbContext.Has(key)
} }
func (css *consensusStateStore) hasUTXOByOutpointFromStagedVirtualUTXOSet(outpoint *externalapi.DomainOutpoint) bool {
return css.virtualUTXOSetStaging.Contains(outpoint)
}
func (css *consensusStateStore) VirtualUTXOSetIterator(dbContext model.DBReader) (model.ReadOnlyUTXOSetIterator, error) { func (css *consensusStateStore) VirtualUTXOSetIterator(dbContext model.DBReader) (model.ReadOnlyUTXOSetIterator, error) {
cursor, err := dbContext.Cursor(utxoSetBucket) cursor, err := dbContext.Cursor(utxoSetBucket)
if err != nil { if err != nil {
@ -239,6 +171,10 @@ func newCursorUTXOSetIterator(cursor model.DBCursor) model.ReadOnlyUTXOSetIterat
return &utxoSetIterator{cursor: cursor} return &utxoSetIterator{cursor: cursor}
} }
func (u utxoSetIterator) First() bool {
return u.cursor.First()
}
func (u utxoSetIterator) Next() bool { func (u utxoSetIterator) Next() bool {
return u.cursor.Next() return u.cursor.Next()
} }
@ -266,25 +202,3 @@ func (u utxoSetIterator) Get() (outpoint *externalapi.DomainOutpoint, utxoEntry
return outpoint, utxoEntry, nil return outpoint, utxoEntry, nil
} }
func (css *consensusStateStore) StageVirtualUTXOSet(virtualUTXOSetIterator model.ReadOnlyUTXOSetIterator) error {
if css.virtualUTXODiffStaging != nil {
return errors.New("cannot stage virtual UTXO set while virtual UTXO diff is staged")
}
utxoMap := make(map[externalapi.DomainOutpoint]externalapi.UTXOEntry)
for virtualUTXOSetIterator.Next() {
outpoint, entry, err := virtualUTXOSetIterator.Get()
if err != nil {
return err
}
if _, exists := utxoMap[*outpoint]; exists {
return errors.Errorf("outpoint %s is found more than once in the given iterator", outpoint)
}
utxoMap[*outpoint] = entry
}
css.virtualUTXOSetStaging = utxo.NewUTXOCollection(utxoMap)
return nil
}

View File

@ -0,0 +1,81 @@
package consensusstatestore
import (
"github.com/kaspanet/kaspad/domain/consensus/database"
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/pkg/errors"
)
var importingPruningPointUTXOSetKey = database.MakeBucket(nil).Key([]byte("importing-pruning-point-utxo-set"))
func (css *consensusStateStore) StartImportingPruningPointUTXOSet(dbContext model.DBWriter) error {
return dbContext.Put(importingPruningPointUTXOSetKey, []byte{0})
}
func (css *consensusStateStore) HadStartedImportingPruningPointUTXOSet(dbContext model.DBWriter) (bool, error) {
return dbContext.Has(importingPruningPointUTXOSetKey)
}
func (css *consensusStateStore) FinishImportingPruningPointUTXOSet(dbContext model.DBWriter) error {
return dbContext.Delete(importingPruningPointUTXOSetKey)
}
func (css *consensusStateStore) ImportPruningPointUTXOSetIntoVirtualUTXOSet(dbContext model.DBWriter,
pruningPointUTXOSetIterator model.ReadOnlyUTXOSetIterator) error {
if css.virtualUTXODiffStaging != nil {
return errors.New("cannot import virtual UTXO set while virtual UTXO diff is staged")
}
hadStartedImportingPruningPointUTXOSet, err := css.HadStartedImportingPruningPointUTXOSet(dbContext)
if err != nil {
return err
}
if !hadStartedImportingPruningPointUTXOSet {
return errors.New("cannot import pruning point UTXO set " +
"without calling StartImportingPruningPointUTXOSet first")
}
// Clear the cache
css.virtualUTXOSetCache.Clear()
// Delete all the old UTXOs from the database
deleteCursor, err := dbContext.Cursor(utxoSetBucket)
if err != nil {
return err
}
for ok := deleteCursor.First(); ok; ok = deleteCursor.Next() {
key, err := deleteCursor.Key()
if err != nil {
return err
}
err = dbContext.Delete(key)
if err != nil {
return err
}
}
// Insert all the new UTXOs into the database
for ok := pruningPointUTXOSetIterator.First(); ok; ok = pruningPointUTXOSetIterator.Next() {
outpoint, entry, err := pruningPointUTXOSetIterator.Get()
if err != nil {
return err
}
key, err := utxoKey(outpoint)
if err != nil {
return err
}
serializedUTXOEntry, err := serializeUTXOEntry(entry)
if err != nil {
return err
}
err = dbContext.Put(key, serializedUTXOEntry)
if err != nil {
return err
}
}
return nil
}

View File

@ -0,0 +1,213 @@
package pruningstore
import (
"github.com/golang/protobuf/proto"
"github.com/kaspanet/kaspad/domain/consensus/database"
"github.com/kaspanet/kaspad/domain/consensus/database/serialization"
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
var importedPruningPointUTXOsBucket = database.MakeBucket([]byte("imported-pruning-point-utxos"))
var importedPruningPointMultiset = database.MakeBucket(nil).Key([]byte("imported-pruning-point-multiset"))
func (ps *pruningStore) ClearImportedPruningPointUTXOs(dbContext model.DBWriter) error {
cursor, err := dbContext.Cursor(importedPruningPointUTXOsBucket)
if err != nil {
return err
}
for ok := cursor.First(); ok; ok = cursor.Next() {
key, err := cursor.Key()
if err != nil {
return err
}
err = dbContext.Delete(key)
if err != nil {
return err
}
}
return nil
}
func (ps *pruningStore) AppendImportedPruningPointUTXOs(dbTx model.DBTransaction,
outpointAndUTXOEntryPairs []*externalapi.OutpointAndUTXOEntryPair) error {
for _, outpointAndUTXOEntryPair := range outpointAndUTXOEntryPairs {
key, err := ps.importedPruningPointUTXOKey(outpointAndUTXOEntryPair.Outpoint)
if err != nil {
return err
}
serializedUTXOEntry, err := serializeUTXOEntry(outpointAndUTXOEntryPair.UTXOEntry)
if err != nil {
return err
}
err = dbTx.Put(key, serializedUTXOEntry)
if err != nil {
return err
}
}
return nil
}
func (ps *pruningStore) ImportedPruningPointUTXOIterator(dbContext model.DBReader) (model.ReadOnlyUTXOSetIterator, error) {
cursor, err := dbContext.Cursor(importedPruningPointUTXOsBucket)
if err != nil {
return nil, err
}
return ps.newCursorUTXOSetIterator(cursor), nil
}
type utxoSetIterator struct {
cursor model.DBCursor
}
func (ps *pruningStore) newCursorUTXOSetIterator(cursor model.DBCursor) model.ReadOnlyUTXOSetIterator {
return &utxoSetIterator{cursor: cursor}
}
func (u *utxoSetIterator) First() bool {
return u.cursor.First()
}
func (u *utxoSetIterator) Next() bool {
return u.cursor.Next()
}
func (u *utxoSetIterator) Get() (outpoint *externalapi.DomainOutpoint, utxoEntry externalapi.UTXOEntry, err error) {
key, err := u.cursor.Key()
if err != nil {
panic(err)
}
utxoEntryBytes, err := u.cursor.Value()
if err != nil {
return nil, nil, err
}
outpoint, err = deserializeOutpoint(key.Suffix())
if err != nil {
return nil, nil, err
}
utxoEntry, err = deserializeUTXOEntry(utxoEntryBytes)
if err != nil {
return nil, nil, err
}
return outpoint, utxoEntry, nil
}
func (ps *pruningStore) importedPruningPointUTXOKey(outpoint *externalapi.DomainOutpoint) (model.DBKey, error) {
serializedOutpoint, err := serializeOutpoint(outpoint)
if err != nil {
return nil, err
}
return importedPruningPointUTXOsBucket.Key(serializedOutpoint), nil
}
func serializeOutpoint(outpoint *externalapi.DomainOutpoint) ([]byte, error) {
return proto.Marshal(serialization.DomainOutpointToDbOutpoint(outpoint))
}
func serializeUTXOEntry(entry externalapi.UTXOEntry) ([]byte, error) {
return proto.Marshal(serialization.UTXOEntryToDBUTXOEntry(entry))
}
func deserializeOutpoint(outpointBytes []byte) (*externalapi.DomainOutpoint, error) {
dbOutpoint := &serialization.DbOutpoint{}
err := proto.Unmarshal(outpointBytes, dbOutpoint)
if err != nil {
return nil, err
}
return serialization.DbOutpointToDomainOutpoint(dbOutpoint)
}
func deserializeUTXOEntry(entryBytes []byte) (externalapi.UTXOEntry, error) {
dbEntry := &serialization.DbUtxoEntry{}
err := proto.Unmarshal(entryBytes, dbEntry)
if err != nil {
return nil, err
}
return serialization.DBUTXOEntryToUTXOEntry(dbEntry)
}
func (ps *pruningStore) ClearImportedPruningPointMultiset(dbContext model.DBWriter) error {
return dbContext.Delete(importedPruningPointMultiset)
}
func (ps *pruningStore) ImportedPruningPointMultiset(dbContext model.DBReader) (model.Multiset, error) {
multisetBytes, err := dbContext.Get(importedPruningPointMultiset)
if err != nil {
return nil, err
}
return ps.deserializeMultiset(multisetBytes)
}
func (ps *pruningStore) UpdateImportedPruningPointMultiset(dbTx model.DBTransaction, multiset model.Multiset) error {
multisetBytes, err := ps.serializeMultiset(multiset)
if err != nil {
return err
}
return dbTx.Put(importedPruningPointMultiset, multisetBytes)
}
func (ps *pruningStore) serializeMultiset(multiset model.Multiset) ([]byte, error) {
return proto.Marshal(serialization.MultisetToDBMultiset(multiset))
}
func (ps *pruningStore) deserializeMultiset(multisetBytes []byte) (model.Multiset, error) {
dbMultiset := &serialization.DbMultiset{}
err := proto.Unmarshal(multisetBytes, dbMultiset)
if err != nil {
return nil, err
}
return serialization.DBMultisetToMultiset(dbMultiset)
}
func (ps *pruningStore) CommitImportedPruningPointUTXOSet(dbContext model.DBWriter) error {
// Delete all the old UTXOs from the database
deleteCursor, err := dbContext.Cursor(pruningPointUTXOSetBucket)
if err != nil {
return err
}
for ok := deleteCursor.First(); ok; ok = deleteCursor.Next() {
key, err := deleteCursor.Key()
if err != nil {
return err
}
err = dbContext.Delete(key)
if err != nil {
return err
}
}
// Insert all the new UTXOs into the database
insertCursor, err := dbContext.Cursor(importedPruningPointUTXOsBucket)
if err != nil {
return err
}
for ok := insertCursor.First(); ok; ok = insertCursor.Next() {
importedPruningPointUTXOSetKey, err := insertCursor.Key()
if err != nil {
return err
}
pruningPointUTXOSetKey := pruningPointUTXOSetBucket.Key(importedPruningPointUTXOSetKey.Suffix())
serializedUTXOEntry, err := insertCursor.Value()
if err != nil {
return err
}
err = dbContext.Put(pruningPointUTXOSetKey, serializedUTXOEntry)
if err != nil {
return err
}
}
return nil
}

View File

@ -10,15 +10,21 @@ import (
var pruningBlockHashKey = database.MakeBucket(nil).Key([]byte("pruning-block-hash")) var pruningBlockHashKey = database.MakeBucket(nil).Key([]byte("pruning-block-hash"))
var candidatePruningPointHashKey = database.MakeBucket(nil).Key([]byte("candidate-pruning-point-hash")) var candidatePruningPointHashKey = database.MakeBucket(nil).Key([]byte("candidate-pruning-point-hash"))
var pruningSerializedUTXOSetKey = database.MakeBucket(nil).Key([]byte("pruning-utxo-set")) var pruningPointUTXOSetBucket = database.MakeBucket([]byte("pruning-point-utxo-set"))
// pruningStore represents a store for the current pruning state // pruningStore represents a store for the current pruning state
type pruningStore struct { type pruningStore struct {
pruningPointStaging *externalapi.DomainHash pruningPointStaging *externalapi.DomainHash
pruningPointCandidateStaging *externalapi.DomainHash
serializedUTXOSetStaging []byte
pruningPointCandidateCache *externalapi.DomainHash
pruningPointCache *externalapi.DomainHash pruningPointCache *externalapi.DomainHash
pruningPointCandidateStaging *externalapi.DomainHash
pruningPointCandidateCache *externalapi.DomainHash
pruningPointUTXOSetStaging model.ReadOnlyUTXOSetIterator
}
// New instantiates a new PruningStore
func New() model.PruningStore {
return &pruningStore{}
} }
func (ps *pruningStore) StagePruningPointCandidate(candidate *externalapi.DomainHash) { func (ps *pruningStore) StagePruningPointCandidate(candidate *externalapi.DomainHash) {
@ -59,24 +65,22 @@ func (ps *pruningStore) HasPruningPointCandidate(dbContext model.DBReader) (bool
return dbContext.Has(candidatePruningPointHashKey) return dbContext.Has(candidatePruningPointHashKey)
} }
// New instantiates a new PruningStore // Stage stages the pruning state
func New() model.PruningStore { func (ps *pruningStore) StagePruningPoint(pruningPointBlockHash *externalapi.DomainHash) {
return &pruningStore{} ps.pruningPointStaging = pruningPointBlockHash
} }
// Stage stages the pruning state func (ps *pruningStore) StagePruningPointUTXOSet(pruningPointUTXOSetIterator model.ReadOnlyUTXOSetIterator) {
func (ps *pruningStore) StagePruningPoint(pruningPointBlockHash *externalapi.DomainHash, pruningPointUTXOSetBytes []byte) { ps.pruningPointUTXOSetStaging = pruningPointUTXOSetIterator
ps.pruningPointStaging = pruningPointBlockHash
ps.serializedUTXOSetStaging = pruningPointUTXOSetBytes
} }
func (ps *pruningStore) IsStaged() bool { func (ps *pruningStore) IsStaged() bool {
return ps.pruningPointStaging != nil || ps.serializedUTXOSetStaging != nil return ps.pruningPointStaging != nil || ps.pruningPointUTXOSetStaging != nil
} }
func (ps *pruningStore) Discard() { func (ps *pruningStore) Discard() {
ps.pruningPointStaging = nil ps.pruningPointStaging = nil
ps.serializedUTXOSetStaging = nil ps.pruningPointUTXOSetStaging = nil
} }
func (ps *pruningStore) Commit(dbTx model.DBTransaction) error { func (ps *pruningStore) Commit(dbTx model.DBTransaction) error {
@ -104,14 +108,42 @@ func (ps *pruningStore) Commit(dbTx model.DBTransaction) error {
ps.pruningPointCandidateCache = ps.pruningPointCandidateStaging ps.pruningPointCandidateCache = ps.pruningPointCandidateStaging
} }
if ps.serializedUTXOSetStaging != nil { if ps.pruningPointUTXOSetStaging != nil {
utxoSetBytes, err := ps.serializeUTXOSetBytes(ps.serializedUTXOSetStaging) // Delete all the old UTXOs from the database
deleteCursor, err := dbTx.Cursor(pruningPointUTXOSetBucket)
if err != nil { if err != nil {
return err return err
} }
err = dbTx.Put(pruningSerializedUTXOSetKey, utxoSetBytes) for ok := deleteCursor.First(); ok; ok = deleteCursor.Next() {
if err != nil { key, err := deleteCursor.Key()
return err if err != nil {
return err
}
err = dbTx.Delete(key)
if err != nil {
return err
}
}
// Insert all the new UTXOs into the database
for ok := ps.pruningPointUTXOSetStaging.First(); ok; ok = ps.pruningPointUTXOSetStaging.Next() {
outpoint, entry, err := ps.pruningPointUTXOSetStaging.Get()
if err != nil {
return err
}
serializedOutpoint, err := serializeOutpoint(outpoint)
if err != nil {
return err
}
key := pruningPointUTXOSetBucket.Key(serializedOutpoint)
serializedUTXOEntry, err := serializeUTXOEntry(entry)
if err != nil {
return err
}
err = dbTx.Put(key, serializedUTXOEntry)
if err != nil {
return err
}
} }
} }
@ -142,24 +174,6 @@ func (ps *pruningStore) PruningPoint(dbContext model.DBReader) (*externalapi.Dom
return pruningPoint, nil return pruningPoint, nil
} }
// PruningPointSerializedUTXOSet returns the serialized UTXO set of the current pruning point
func (ps *pruningStore) PruningPointSerializedUTXOSet(dbContext model.DBReader) ([]byte, error) {
if ps.serializedUTXOSetStaging != nil {
return ps.serializedUTXOSetStaging, nil
}
dbPruningPointUTXOSetBytes, err := dbContext.Get(pruningSerializedUTXOSetKey)
if err != nil {
return nil, err
}
pruningPointUTXOSet, err := ps.deserializeUTXOSetBytes(dbPruningPointUTXOSetBytes)
if err != nil {
return nil, err
}
return pruningPointUTXOSet, nil
}
func (ps *pruningStore) serializeHash(hash *externalapi.DomainHash) ([]byte, error) { func (ps *pruningStore) serializeHash(hash *externalapi.DomainHash) ([]byte, error) {
return proto.Marshal(serialization.DomainHashToDbHash(hash)) return proto.Marshal(serialization.DomainHashToDbHash(hash))
} }
@ -199,3 +213,31 @@ func (ps *pruningStore) HasPruningPoint(dbContext model.DBReader) (bool, error)
return dbContext.Has(pruningBlockHashKey) return dbContext.Has(pruningBlockHashKey)
} }
func (ps *pruningStore) PruningPointUTXOs(dbContext model.DBReader,
offset int, limit int) ([]*externalapi.OutpointAndUTXOEntryPair, error) {
cursor, err := dbContext.Cursor(pruningPointUTXOSetBucket)
if err != nil {
return nil, err
}
pruningPointUTXOIterator := ps.newCursorUTXOSetIterator(cursor)
offsetIndex := 0
for offsetIndex < offset && pruningPointUTXOIterator.Next() {
offsetIndex++
}
outpointAndUTXOEntryPairs := make([]*externalapi.OutpointAndUTXOEntryPair, 0, limit)
for len(outpointAndUTXOEntryPairs) < limit && pruningPointUTXOIterator.Next() {
outpoint, utxoEntry, err := pruningPointUTXOIterator.Get()
if err != nil {
return nil, err
}
outpointAndUTXOEntryPairs = append(outpointAndUTXOEntryPairs, &externalapi.OutpointAndUTXOEntryPair{
Outpoint: outpoint,
UTXOEntry: utxoEntry,
})
}
return outpointAndUTXOEntryPairs, nil
}

View File

@ -357,6 +357,15 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat
} }
} }
err = consensusStateManager.RecoverUTXOIfRequired()
if err != nil {
return nil, err
}
err = pruningManager.ClearImportedPruningPointData()
if err != nil {
return nil, err
}
return c, nil return c, nil
} }

View File

@ -45,6 +45,8 @@ type DBReader interface {
// DBWriter is an interface to write to the database // DBWriter is an interface to write to the database
type DBWriter interface { type DBWriter interface {
DBReader
// Put sets the value for the given key. It overwrites // Put sets the value for the given key. It overwrites
// any previous value for that key. // any previous value for that key.
Put(key DBKey, value []byte) error Put(key DBKey, value []byte) error
@ -58,7 +60,6 @@ type DBWriter interface {
// access that requires an open database transaction // access that requires an open database transaction
type DBTransaction interface { type DBTransaction interface {
DBWriter DBWriter
DBReader
// Rollback rolls back whatever changes were made to the // Rollback rolls back whatever changes were made to the
// database within this transaction. // database within this transaction.
@ -77,7 +78,7 @@ type DBTransaction interface {
// DBManager defines the interface of a database that can begin // DBManager defines the interface of a database that can begin
// transactions and read data. // transactions and read data.
type DBManager interface { type DBManager interface {
DBReader DBWriter
// Begin begins a new database transaction. // Begin begins a new database transaction.
Begin() (DBTransaction, error) Begin() (DBTransaction, error)

View File

@ -13,9 +13,11 @@ type Consensus interface {
GetHashesBetween(lowHash, highHash *DomainHash, maxBlueScoreDifference uint64) ([]*DomainHash, error) GetHashesBetween(lowHash, highHash *DomainHash, maxBlueScoreDifference uint64) ([]*DomainHash, error)
GetMissingBlockBodyHashes(highHash *DomainHash) ([]*DomainHash, error) GetMissingBlockBodyHashes(highHash *DomainHash) ([]*DomainHash, error)
GetPruningPointUTXOSet(expectedPruningPointHash *DomainHash) ([]byte, error) GetPruningPointUTXOs(expectedPruningPointHash *DomainHash, offset int, limit int) ([]*OutpointAndUTXOEntryPair, error)
PruningPoint() (*DomainHash, error) PruningPoint() (*DomainHash, error)
ValidateAndInsertPruningPoint(newPruningPoint *DomainBlock, serializedUTXOSet []byte) error ClearImportedPruningPointData() error
AppendImportedPruningPointUTXOs(outpointAndUTXOEntryPairs []*OutpointAndUTXOEntryPair) error
ValidateAndInsertImportedPruningPoint(newPruningPoint *DomainBlock) error
GetVirtualSelectedParent() (*DomainHash, error) GetVirtualSelectedParent() (*DomainHash, error)
CreateBlockLocator(lowHash, highHash *DomainHash, limit uint32) (BlockLocator, error) CreateBlockLocator(lowHash, highHash *DomainHash, limit uint32) (BlockLocator, error)
CreateHeadersSelectedChainBlockLocator(lowHash, highHash *DomainHash) (BlockLocator, error) CreateHeadersSelectedChainBlockLocator(lowHash, highHash *DomainHash) (BlockLocator, error)

View File

@ -11,3 +11,10 @@ type UTXOEntry interface {
IsCoinbase() bool IsCoinbase() bool
Equal(other UTXOEntry) bool Equal(other UTXOEntry) bool
} }
// OutpointAndUTXOEntryPair is an outpoint along with its
// respective UTXO entry
type OutpointAndUTXOEntryPair struct {
Outpoint *DomainOutpoint
UTXOEntry UTXOEntry
}

View File

@ -7,8 +7,7 @@ type ConsensusStateStore interface {
Store Store
IsStaged() bool IsStaged() bool
StageVirtualUTXODiff(virtualUTXODiff UTXODiff) error StageVirtualUTXODiff(virtualUTXODiff UTXODiff)
StageVirtualUTXOSet(virtualUTXOSetIterator ReadOnlyUTXOSetIterator) error
UTXOByOutpoint(dbContext DBReader, outpoint *externalapi.DomainOutpoint) (externalapi.UTXOEntry, error) UTXOByOutpoint(dbContext DBReader, outpoint *externalapi.DomainOutpoint) (externalapi.UTXOEntry, error)
HasUTXOByOutpoint(dbContext DBReader, outpoint *externalapi.DomainOutpoint) (bool, error) HasUTXOByOutpoint(dbContext DBReader, outpoint *externalapi.DomainOutpoint) (bool, error)
VirtualUTXOSetIterator(dbContext DBReader) (ReadOnlyUTXOSetIterator, error) VirtualUTXOSetIterator(dbContext DBReader) (ReadOnlyUTXOSetIterator, error)
@ -18,4 +17,9 @@ type ConsensusStateStore interface {
StageTips(tipHashes []*externalapi.DomainHash) StageTips(tipHashes []*externalapi.DomainHash)
Tips(dbContext DBReader) ([]*externalapi.DomainHash, error) Tips(dbContext DBReader) ([]*externalapi.DomainHash, error)
StartImportingPruningPointUTXOSet(dbContext DBWriter) error
HadStartedImportingPruningPointUTXOSet(dbContext DBWriter) (bool, error)
ImportPruningPointUTXOSetIntoVirtualUTXOSet(dbContext DBWriter, pruningPointUTXOSetIterator ReadOnlyUTXOSetIterator) error
FinishImportingPruningPointUTXOSet(dbContext DBWriter) error
} }

View File

@ -5,12 +5,20 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
// PruningStore represents a store for the current pruning state // PruningStore represents a store for the current pruning state
type PruningStore interface { type PruningStore interface {
Store Store
StagePruningPoint(pruningPointBlockHash *externalapi.DomainHash, pruningPointUTXOSetBytes []byte) StagePruningPoint(pruningPointBlockHash *externalapi.DomainHash)
StagePruningPointUTXOSet(pruningPointUTXOSetIterator ReadOnlyUTXOSetIterator)
StagePruningPointCandidate(candidate *externalapi.DomainHash) StagePruningPointCandidate(candidate *externalapi.DomainHash)
IsStaged() bool IsStaged() bool
PruningPointCandidate(dbContext DBReader) (*externalapi.DomainHash, error) PruningPointCandidate(dbContext DBReader) (*externalapi.DomainHash, error)
HasPruningPointCandidate(dbContext DBReader) (bool, error) HasPruningPointCandidate(dbContext DBReader) (bool, error)
PruningPoint(dbContext DBReader) (*externalapi.DomainHash, error) PruningPoint(dbContext DBReader) (*externalapi.DomainHash, error)
HasPruningPoint(dbContext DBReader) (bool, error) HasPruningPoint(dbContext DBReader) (bool, error)
PruningPointSerializedUTXOSet(dbContext DBReader) ([]byte, error) ClearImportedPruningPointUTXOs(dbContext DBWriter) error
AppendImportedPruningPointUTXOs(dbTx DBTransaction, outpointAndUTXOEntryPairs []*externalapi.OutpointAndUTXOEntryPair) error
ImportedPruningPointUTXOIterator(dbContext DBReader) (ReadOnlyUTXOSetIterator, error)
ClearImportedPruningPointMultiset(dbContext DBWriter) error
ImportedPruningPointMultiset(dbContext DBReader) (Multiset, error)
UpdateImportedPruningPointMultiset(dbTx DBTransaction, multiset Multiset) error
CommitImportedPruningPointUTXOSet(dbContext DBWriter) error
PruningPointUTXOs(dbContext DBReader, offset int, limit int) ([]*externalapi.OutpointAndUTXOEntryPair, error)
} }

View File

@ -5,5 +5,5 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
// BlockProcessor is responsible for processing incoming blocks // BlockProcessor is responsible for processing incoming blocks
type BlockProcessor interface { type BlockProcessor interface {
ValidateAndInsertBlock(block *externalapi.DomainBlock) (*externalapi.BlockInsertionResult, error) ValidateAndInsertBlock(block *externalapi.DomainBlock) (*externalapi.BlockInsertionResult, error)
ValidateAndInsertPruningPoint(newPruningPoint *externalapi.DomainBlock, serializedUTXOSet []byte) error ValidateAndInsertImportedPruningPoint(newPruningPoint *externalapi.DomainBlock) error
} }

View File

@ -6,8 +6,9 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
type ConsensusStateManager interface { type ConsensusStateManager interface {
AddBlock(blockHash *externalapi.DomainHash) (*externalapi.SelectedChainPath, error) AddBlock(blockHash *externalapi.DomainHash) (*externalapi.SelectedChainPath, error)
PopulateTransactionWithUTXOEntries(transaction *externalapi.DomainTransaction) error PopulateTransactionWithUTXOEntries(transaction *externalapi.DomainTransaction) error
UpdatePruningPoint(newPruningPoint *externalapi.DomainBlock, serializedUTXOSet []byte) error ImportPruningPoint(newPruningPoint *externalapi.DomainBlock) error
RestorePastUTXOSetIterator(blockHash *externalapi.DomainHash) (ReadOnlyUTXOSetIterator, error) RestorePastUTXOSetIterator(blockHash *externalapi.DomainHash) (ReadOnlyUTXOSetIterator, error)
CalculatePastUTXOAndAcceptanceData(blockHash *externalapi.DomainHash) (UTXODiff, externalapi.AcceptanceData, Multiset, error) CalculatePastUTXOAndAcceptanceData(blockHash *externalapi.DomainHash) (UTXODiff, externalapi.AcceptanceData, Multiset, error)
GetVirtualSelectedParentChainFromBlock(blockHash *externalapi.DomainHash) (*externalapi.SelectedChainPath, error) GetVirtualSelectedParentChainFromBlock(blockHash *externalapi.DomainHash) (*externalapi.SelectedChainPath, error)
RecoverUTXOIfRequired() error
} }

View File

@ -6,4 +6,6 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
type PruningManager interface { type PruningManager interface {
UpdatePruningPointByVirtual() error UpdatePruningPointByVirtual() error
IsValidPruningPoint(blockHash *externalapi.DomainHash) (bool, error) IsValidPruningPoint(blockHash *externalapi.DomainHash) (bool, error)
ClearImportedPruningPointData() error
AppendImportedPruningPointUTXOs(outpointAndUTXOEntryPairs []*externalapi.OutpointAndUTXOEntryPair) error
} }

View File

@ -11,6 +11,7 @@ type ReadOnlyUTXOSet interface {
// ReadOnlyUTXOSetIterator is an iterator over all entries in a // ReadOnlyUTXOSetIterator is an iterator over all entries in a
// ReadOnlyUTXOSet // ReadOnlyUTXOSet
type ReadOnlyUTXOSetIterator interface { type ReadOnlyUTXOSetIterator interface {
First() bool
Next() bool Next() bool
Get() (outpoint *externalapi.DomainOutpoint, utxoEntry externalapi.UTXOEntry, err error) Get() (outpoint *externalapi.DomainOutpoint, utxoEntry externalapi.UTXOEntry, err error)
} }

View File

@ -137,9 +137,9 @@ func (bp *blockProcessor) ValidateAndInsertBlock(block *externalapi.DomainBlock)
return bp.validateAndInsertBlock(block, false) return bp.validateAndInsertBlock(block, false)
} }
func (bp *blockProcessor) ValidateAndInsertPruningPoint(newPruningPoint *externalapi.DomainBlock, serializedUTXOSet []byte) error { func (bp *blockProcessor) ValidateAndInsertImportedPruningPoint(newPruningPoint *externalapi.DomainBlock) error {
onEnd := logger.LogAndMeasureExecutionTime(log, "ValidateAndInsertPruningPoint") onEnd := logger.LogAndMeasureExecutionTime(log, "ValidateAndInsertImportedPruningPoint")
defer onEnd() defer onEnd()
return bp.validateAndInsertPruningPoint(newPruningPoint, serializedUTXOSet) return bp.validateAndInsertImportedPruningPoint(newPruningPoint)
} }

View File

@ -87,7 +87,7 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock,
if !isHeaderOnlyBlock { if !isHeaderOnlyBlock {
// There's no need to update the consensus state manager when // There's no need to update the consensus state manager when
// processing the pruning point since it was already handled // processing the pruning point since it was already handled
// in consensusStateManager.UpdatePruningPoint // in consensusStateManager.ImportPruningPoint
if !isPruningPoint { if !isPruningPoint {
// Attempt to add the block to the virtual // Attempt to add the block to the virtual
selectedParentChainChanges, err = bp.consensusStateManager.AddBlock(blockHash) selectedParentChainChanges, err = bp.consensusStateManager.AddBlock(blockHash)

View File

@ -7,7 +7,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
func (bp *blockProcessor) validateAndInsertPruningPoint(newPruningPoint *externalapi.DomainBlock, serializedUTXOSet []byte) error { func (bp *blockProcessor) validateAndInsertImportedPruningPoint(newPruningPoint *externalapi.DomainBlock) error {
log.Info("Checking that the given pruning point is the expected pruning point") log.Info("Checking that the given pruning point is the expected pruning point")
newPruningPointHash := consensushashing.BlockHash(newPruningPoint) newPruningPointHash := consensushashing.BlockHash(newPruningPoint)
@ -29,7 +29,7 @@ func (bp *blockProcessor) validateAndInsertPruningPoint(newPruningPoint *externa
} }
log.Infof("Updating consensus state manager according to the new pruning point %s", newPruningPointHash) log.Infof("Updating consensus state manager according to the new pruning point %s", newPruningPointHash)
err = bp.consensusStateManager.UpdatePruningPoint(newPruningPoint, serializedUTXOSet) err = bp.consensusStateManager.ImportPruningPoint(newPruningPoint)
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,9 +1,6 @@
package blockprocessor_test package blockprocessor_test
import ( import (
"testing"
"time"
"github.com/kaspanet/kaspad/domain/consensus" "github.com/kaspanet/kaspad/domain/consensus"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi" "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/model/testapi" "github.com/kaspanet/kaspad/domain/consensus/model/testapi"
@ -11,10 +8,10 @@ import (
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing" "github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/domain/consensus/utils/testutils" "github.com/kaspanet/kaspad/domain/consensus/utils/testutils"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo" "github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxoserialization"
"github.com/kaspanet/kaspad/domain/dagconfig" "github.com/kaspanet/kaspad/domain/dagconfig"
"github.com/pkg/errors" "github.com/pkg/errors"
"google.golang.org/protobuf/proto" "testing"
"time"
) )
func addBlock(tcSyncer, tcSyncee testapi.TestConsensus, parentHashes []*externalapi.DomainHash, t *testing.T) *externalapi.DomainHash { func addBlock(tcSyncer, tcSyncee testapi.TestConsensus, parentHashes []*externalapi.DomainHash, t *testing.T) *externalapi.DomainHash {
@ -39,7 +36,7 @@ func addBlock(tcSyncer, tcSyncee testapi.TestConsensus, parentHashes []*external
return consensushashing.BlockHash(block) return consensushashing.BlockHash(block)
} }
func TestValidateAndInsertPruningPoint(t *testing.T) { func TestValidateAndInsertImportedPruningPoint(t *testing.T) {
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) { testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
// This is done to reduce the pruning depth to 6 blocks // This is done to reduce the pruning depth to 6 blocks
finalityDepth := 3 finalityDepth := 3
@ -95,9 +92,13 @@ func TestValidateAndInsertPruningPoint(t *testing.T) {
t.Fatalf("Unexpected pruning point %s", pruningPoint) t.Fatalf("Unexpected pruning point %s", pruningPoint)
} }
pruningPointUTXOSet, err := tcSyncer.GetPruningPointUTXOSet(pruningPoint) pruningPointUTXOs, err := tcSyncer.GetPruningPointUTXOs(pruningPoint, 0, 1000)
if err != nil { if err != nil {
t.Fatalf("GetPruningPointUTXOSet: %+v", err) t.Fatalf("GetPruningPointUTXOs: %+v", err)
}
err = tcSyncee.AppendImportedPruningPointUTXOs(pruningPointUTXOs)
if err != nil {
t.Fatalf("AppendImportedPruningPointUTXOs: %+v", err)
} }
tip, err := tcSyncer.GetBlock(tipHash) tip, err := tcSyncer.GetBlock(tipHash)
@ -105,8 +106,8 @@ func TestValidateAndInsertPruningPoint(t *testing.T) {
t.Fatalf("GetBlock: %+v", err) t.Fatalf("GetBlock: %+v", err)
} }
// Check that ValidateAndInsertPruningPoint fails for invalid pruning point // Check that ValidateAndInsertImportedPruningPoint fails for invalid pruning point
err = tcSyncee.ValidateAndInsertPruningPoint(tip, pruningPointUTXOSet) err = tcSyncee.ValidateAndInsertImportedPruningPoint(tip)
if !errors.Is(err, ruleerrors.ErrUnexpectedPruningPoint) { if !errors.Is(err, ruleerrors.ErrUnexpectedPruningPoint) {
t.Fatalf("Unexpected error: %+v", err) t.Fatalf("Unexpected error: %+v", err)
} }
@ -119,27 +120,40 @@ func TestValidateAndInsertPruningPoint(t *testing.T) {
invalidPruningPointBlock := pruningPointBlock.Clone() invalidPruningPointBlock := pruningPointBlock.Clone()
invalidPruningPointBlock.Transactions[0].Version += 1 invalidPruningPointBlock.Transactions[0].Version += 1
// Check that ValidateAndInsertPruningPoint fails for invalid block // Check that ValidateAndInsertImportedPruningPoint fails for invalid block
err = tcSyncee.ValidateAndInsertPruningPoint(invalidPruningPointBlock, pruningPointUTXOSet) err = tcSyncee.ValidateAndInsertImportedPruningPoint(invalidPruningPointBlock)
if !errors.Is(err, ruleerrors.ErrBadMerkleRoot) { if !errors.Is(err, ruleerrors.ErrBadMerkleRoot) {
t.Fatalf("Unexpected error: %+v", err) t.Fatalf("Unexpected error: %+v", err)
} }
serializedFakeUTXOSet, err := makeSerializedFakeUTXOSet() err = tcSyncee.ClearImportedPruningPointData()
if err != nil { if err != nil {
t.Fatalf("makeSerializedFakeUTXOSet: %+v", err) t.Fatalf("ClearImportedPruningPointData: %+v", err)
}
err = tcSyncee.AppendImportedPruningPointUTXOs(makeFakeUTXOs())
if err != nil {
t.Fatalf("AppendImportedPruningPointUTXOs: %+v", err)
} }
// Check that ValidateAndInsertPruningPoint fails if the UTXO commitment doesn't fit the provided UTXO set. // Check that ValidateAndInsertImportedPruningPoint fails if the UTXO commitment doesn't fit the provided UTXO set.
err = tcSyncee.ValidateAndInsertPruningPoint(pruningPointBlock, serializedFakeUTXOSet) err = tcSyncee.ValidateAndInsertImportedPruningPoint(pruningPointBlock)
if !errors.Is(err, ruleerrors.ErrBadPruningPointUTXOSet) { if !errors.Is(err, ruleerrors.ErrBadPruningPointUTXOSet) {
t.Fatalf("Unexpected error: %+v", err) t.Fatalf("Unexpected error: %+v", err)
} }
// Check that ValidateAndInsertPruningPoint works given the right arguments. err = tcSyncee.ClearImportedPruningPointData()
err = tcSyncee.ValidateAndInsertPruningPoint(pruningPointBlock, pruningPointUTXOSet)
if err != nil { if err != nil {
t.Fatalf("ValidateAndInsertPruningPoint: %+v", err) t.Fatalf("ClearImportedPruningPointData: %+v", err)
}
err = tcSyncee.AppendImportedPruningPointUTXOs(pruningPointUTXOs)
if err != nil {
t.Fatalf("AppendImportedPruningPointUTXOs: %+v", err)
}
// Check that ValidateAndInsertImportedPruningPoint works given the right arguments.
err = tcSyncee.ValidateAndInsertImportedPruningPoint(pruningPointBlock)
if err != nil {
t.Fatalf("ValidateAndInsertImportedPruningPoint: %+v", err)
} }
virtualSelectedParent, err := tcSyncer.GetVirtualSelectedParent() virtualSelectedParent, err := tcSyncer.GetVirtualSelectedParent()
@ -256,9 +270,13 @@ func TestValidateAndInsertPruningPointWithSideBlocks(t *testing.T) {
t.Fatalf("Unexpected pruning point %s", pruningPoint) t.Fatalf("Unexpected pruning point %s", pruningPoint)
} }
pruningPointUTXOSet, err := tcSyncer.GetPruningPointUTXOSet(pruningPoint) pruningPointUTXOs, err := tcSyncer.GetPruningPointUTXOs(pruningPoint, 0, 1000)
if err != nil { if err != nil {
t.Fatalf("GetPruningPointUTXOSet: %+v", err) t.Fatalf("GetPruningPointUTXOs: %+v", err)
}
err = tcSyncee.AppendImportedPruningPointUTXOs(pruningPointUTXOs)
if err != nil {
t.Fatalf("AppendImportedPruningPointUTXOs: %+v", err)
} }
// Check that ValidateAndInsertPruningPoint works. // Check that ValidateAndInsertPruningPoint works.
@ -266,7 +284,7 @@ func TestValidateAndInsertPruningPointWithSideBlocks(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("GetBlock: %+v", err) t.Fatalf("GetBlock: %+v", err)
} }
err = tcSyncee.ValidateAndInsertPruningPoint(pruningPointBlock, pruningPointUTXOSet) err = tcSyncee.ValidateAndInsertImportedPruningPoint(pruningPointBlock)
if err != nil { if err != nil {
t.Fatalf("ValidateAndInsertPruningPoint: %+v", err) t.Fatalf("ValidateAndInsertPruningPoint: %+v", err)
} }
@ -362,33 +380,37 @@ func TestValidateAndInsertPruningPointWithSideBlocks(t *testing.T) {
}) })
} }
type fakeUTXOSetIterator struct { func makeFakeUTXOs() []*externalapi.OutpointAndUTXOEntryPair {
nextCalled bool return []*externalapi.OutpointAndUTXOEntryPair{
} {
Outpoint: &externalapi.DomainOutpoint{
func (f *fakeUTXOSetIterator) Next() bool { TransactionID: externalapi.DomainTransactionID{},
if f.nextCalled { Index: 0,
return false },
UTXOEntry: utxo.NewUTXOEntry(
0,
&externalapi.ScriptPublicKey{
Script: nil,
Version: 0,
},
false,
0,
),
},
{
Outpoint: &externalapi.DomainOutpoint{
TransactionID: externalapi.DomainTransactionID{},
Index: 1,
},
UTXOEntry: utxo.NewUTXOEntry(
2,
&externalapi.ScriptPublicKey{
Script: nil,
Version: 0,
},
true,
3,
),
},
} }
f.nextCalled = true
return true
}
func (f *fakeUTXOSetIterator) Get() (outpoint *externalapi.DomainOutpoint, utxoEntry externalapi.UTXOEntry, err error) {
return &externalapi.DomainOutpoint{
TransactionID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}),
Index: 0,
}, utxo.NewUTXOEntry(1000, &externalapi.ScriptPublicKey{
Script: []byte{1, 2, 3},
Version: 0,
}, false, 2000), nil
}
func makeSerializedFakeUTXOSet() ([]byte, error) {
serializedUtxo, err := utxoserialization.ReadOnlyUTXOSetToProtoUTXOSet(&fakeUTXOSetIterator{})
if err != nil {
return nil, err
}
return proto.Marshal(serializedUtxo)
} }

View File

@ -89,7 +89,7 @@ func checkBlockUTXOCommitment(t *testing.T, consensus testapi.TestConsensus, blo
// Build a Multiset // Build a Multiset
ms := multiset.New() ms := multiset.New()
for utxoSetIterator.Next() { for ok := utxoSetIterator.First(); ok; ok = utxoSetIterator.Next() {
outpoint, entry, err := utxoSetIterator.Get() outpoint, entry, err := utxoSetIterator.Get()
if err != nil { if err != nil {
t.Fatalf("Error getting from UTXOSet iterator: %+v", err) t.Fatalf("Error getting from UTXOSet iterator: %+v", err)

View File

@ -0,0 +1,218 @@
package consensusstatemanager
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/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/pkg/errors"
)
func (csm *consensusStateManager) ImportPruningPoint(newPruningPoint *externalapi.DomainBlock) error {
onEnd := logger.LogAndMeasureExecutionTime(log, "ImportPruningPoint")
defer onEnd()
err := csm.importPruningPoint(newPruningPoint)
if err != nil {
csm.discardImportedPruningPointUTXOSetChanges()
return err
}
return csm.applyImportedPruningPointUTXOSet()
}
func (csm *consensusStateManager) importPruningPoint(newPruningPoint *externalapi.DomainBlock) error {
log.Debugf("importPruningPoint start")
defer log.Debugf("importPruningPoint end")
newPruningPointHash := consensushashing.BlockHash(newPruningPoint)
// We ignore the shouldSendNotification return value because we always want to send finality conflict notification
// in case the new pruning point violates finality
isViolatingFinality, _, err := csm.isViolatingFinality(newPruningPointHash)
if err != nil {
return err
}
if isViolatingFinality {
log.Warnf("Finality Violation Detected! The suggest pruning point %s violates finality!", newPruningPointHash)
return errors.Wrapf(ruleerrors.ErrSuggestedPruningViolatesFinality, "%s cannot be a pruning point because "+
"it violates finality", newPruningPointHash)
}
importedPruningPointMultiset, err := csm.pruningStore.ImportedPruningPointMultiset(csm.databaseContext)
if err != nil {
return err
}
newPruningPointHeader, err := csm.blockHeaderStore.BlockHeader(csm.databaseContext, newPruningPointHash)
if err != nil {
return err
}
log.Debugf("The UTXO commitment of the pruning point: %s",
newPruningPointHeader.UTXOCommitment())
if !newPruningPointHeader.UTXOCommitment().Equal(importedPruningPointMultiset.Hash()) {
return errors.Wrapf(ruleerrors.ErrBadPruningPointUTXOSet, "the expected multiset hash of the pruning "+
"point UTXO set is %s but got %s", newPruningPointHeader.UTXOCommitment(), *importedPruningPointMultiset.Hash())
}
log.Debugf("The new pruning point UTXO commitment validation passed")
log.Debugf("Staging the the pruning point as the only DAG tip")
newTips := []*externalapi.DomainHash{newPruningPointHash}
csm.consensusStateStore.StageTips(newTips)
log.Debugf("Setting the pruning point as the only virtual parent")
err = csm.dagTopologyManager.SetParents(model.VirtualBlockHash, newTips)
if err != nil {
return err
}
log.Debugf("Calculating GHOSTDAG for the new virtual")
err = csm.ghostdagManager.GHOSTDAG(model.VirtualBlockHash)
if err != nil {
return err
}
log.Debugf("Deleting all existing virtual diff parents")
csm.consensusStateStore.StageVirtualDiffParents(nil)
log.Debugf("Updating the new pruning point to be the new virtual diff parent with an empty diff")
err = csm.stageDiff(newPruningPointHash, utxo.NewUTXODiff(), nil)
if err != nil {
return err
}
log.Debugf("Staging the new pruning point")
csm.pruningStore.StagePruningPoint(newPruningPointHash)
log.Debugf("Populating the pruning point with UTXO entries")
importedPruningPointUTXOIterator, err := csm.pruningStore.ImportedPruningPointUTXOIterator(csm.databaseContext)
if err != nil {
return err
}
// Clone the pruningPoint block here because validateBlockTransactionsAgainstPastUTXO
// assumes that the block UTXOEntries are pre-filled during further validations
newPruningPointClone := newPruningPoint.Clone()
err = csm.populateTransactionWithUTXOEntriesFromUTXOSet(newPruningPointClone, importedPruningPointUTXOIterator)
if err != nil {
return err
}
// Before we manually mark the new pruning point as valid, we validate that all of its transactions are valid
// against the provided UTXO set.
log.Debugf("Validating that the pruning point is UTXO valid")
newPruningPointSelectedParentMedianTime, err := csm.pastMedianTimeManager.PastMedianTime(newPruningPointHash)
if err != nil {
return err
}
log.Tracef("The past median time of pruning block %s is %d",
newPruningPointHash, newPruningPointSelectedParentMedianTime)
for i, transaction := range newPruningPointClone.Transactions {
transactionID := consensushashing.TransactionID(transaction)
log.Tracef("Validating transaction %s in pruning block %s against "+
"the pruning point's past UTXO", transactionID, newPruningPointHash)
if i == transactionhelper.CoinbaseTransactionIndex {
log.Tracef("Skipping transaction %s because it is the coinbase", transactionID)
continue
}
log.Tracef("Validating transaction %s and populating it with mass and fee", transactionID)
err = csm.transactionValidator.ValidateTransactionInContextAndPopulateMassAndFee(
transaction, newPruningPointHash, newPruningPointSelectedParentMedianTime)
if err != nil {
return err
}
log.Tracef("Validation against the pruning point's past UTXO "+
"passed for transaction %s", transactionID)
}
log.Debugf("Staging the new pruning point as %s", externalapi.StatusUTXOValid)
csm.blockStatusStore.Stage(newPruningPointHash, externalapi.StatusUTXOValid)
log.Debugf("Staging the new pruning point multiset")
csm.multisetStore.Stage(newPruningPointHash, importedPruningPointMultiset)
return nil
}
func (csm *consensusStateManager) discardImportedPruningPointUTXOSetChanges() {
for _, store := range csm.stores {
store.Discard()
}
}
func (csm *consensusStateManager) applyImportedPruningPointUTXOSet() error {
dbTx, err := csm.databaseContext.Begin()
if err != nil {
return err
}
for _, store := range csm.stores {
err = store.Commit(dbTx)
if err != nil {
return err
}
}
log.Debugf("Starting to import virtual UTXO set and pruning point utxo set")
err = csm.consensusStateStore.StartImportingPruningPointUTXOSet(dbTx)
if err != nil {
return err
}
log.Debugf("Committing all staged data for imported pruning point")
err = dbTx.Commit()
if err != nil {
return err
}
return csm.importVirtualUTXOSetAndPruningPointUTXOSet()
}
func (csm *consensusStateManager) importVirtualUTXOSetAndPruningPointUTXOSet() error {
onEnd := logger.LogAndMeasureExecutionTime(log, "importVirtualUTXOSetAndPruningPointUTXOSet")
defer onEnd()
log.Debugf("Getting an iterator into the imported pruning point utxo set")
pruningPointUTXOSetIterator, err := csm.pruningStore.ImportedPruningPointUTXOIterator(csm.databaseContext)
if err != nil {
return err
}
log.Debugf("Importing the virtual UTXO set")
err = csm.consensusStateStore.ImportPruningPointUTXOSetIntoVirtualUTXOSet(csm.databaseContext, pruningPointUTXOSetIterator)
if err != nil {
return err
}
log.Debugf("Importing the new pruning point UTXO set")
err = csm.pruningStore.CommitImportedPruningPointUTXOSet(csm.databaseContext)
if err != nil {
return err
}
log.Debugf("Finishing to import virtual UTXO set and pruning point UTXO set")
return csm.consensusStateStore.FinishImportingPruningPointUTXOSet(csm.databaseContext)
}
func (csm *consensusStateManager) RecoverUTXOIfRequired() error {
hadStartedImportingPruningPointUTXOSet, err := csm.consensusStateStore.HadStartedImportingPruningPointUTXOSet(csm.databaseContext)
if err != nil {
return err
}
if !hadStartedImportingPruningPointUTXOSet {
return nil
}
log.Warnf("Unimported pruning point UTXO set detected. Attempting to recover...")
err = csm.importVirtualUTXOSetAndPruningPointUTXOSet()
if err != nil {
return err
}
log.Warnf("Unimported UTXO set successfully recovered")
return nil
}

View File

@ -75,3 +75,49 @@ func (csm *consensusStateManager) populateTransactionWithUTXOEntriesFromVirtualO
return nil return nil
} }
func (csm *consensusStateManager) populateTransactionWithUTXOEntriesFromUTXOSet(
pruningPoint *externalapi.DomainBlock, iterator model.ReadOnlyUTXOSetIterator) error {
// Collect the required outpoints from the block
outpointsForPopulation := make(map[externalapi.DomainOutpoint]interface{})
for _, transaction := range pruningPoint.Transactions {
for _, input := range transaction.Inputs {
outpointsForPopulation[input.PreviousOutpoint] = struct{}{}
}
}
// Collect the UTXO entries from the iterator
outpointsToUTXOEntries := make(map[externalapi.DomainOutpoint]externalapi.UTXOEntry, len(outpointsForPopulation))
for ok := iterator.First(); ok; ok = iterator.Next() {
outpoint, utxoEntry, err := iterator.Get()
if err != nil {
return err
}
outpointValue := *outpoint
if _, ok := outpointsForPopulation[outpointValue]; ok {
outpointsToUTXOEntries[outpointValue] = utxoEntry
}
if len(outpointsForPopulation) == len(outpointsToUTXOEntries) {
break
}
}
// Populate the block with the collected UTXO entries
var missingOutpoints []*externalapi.DomainOutpoint
for _, transaction := range pruningPoint.Transactions {
for _, input := range transaction.Inputs {
utxoEntry, ok := outpointsToUTXOEntries[input.PreviousOutpoint]
if !ok {
missingOutpoints = append(missingOutpoints, &input.PreviousOutpoint)
continue
}
input.UTXOEntry = utxoEntry
}
}
if len(missingOutpoints) > 0 {
return ruleerrors.NewErrMissingTxOut(missingOutpoints)
}
return nil
}

View File

@ -1,174 +0,0 @@
package consensusstatemanager
import (
"github.com/golang/protobuf/proto"
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/domain/consensus/utils/serialization"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxoserialization"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/pkg/errors"
)
func (csm *consensusStateManager) UpdatePruningPoint(newPruningPoint *externalapi.DomainBlock, serializedUTXOSet []byte) error {
onEnd := logger.LogAndMeasureExecutionTime(log, "UpdatePruningPoint")
defer onEnd()
err := csm.updatePruningPoint(newPruningPoint, serializedUTXOSet)
if err != nil {
csm.discardSetPruningPointUTXOSetChanges()
return err
}
return csm.commitSetPruningPointUTXOSetAll()
}
func (csm *consensusStateManager) updatePruningPoint(newPruningPoint *externalapi.DomainBlock, serializedUTXOSet []byte) error {
log.Debugf("updatePruningPoint start")
defer log.Debugf("updatePruningPoint end")
newPruningPointHash := consensushashing.BlockHash(newPruningPoint)
// We ignore the shouldSendNotification return value because we always want to send finality conflict notification
// in case the new pruning point violates finality
isViolatingFinality, _, err := csm.isViolatingFinality(newPruningPointHash)
if err != nil {
return err
}
if isViolatingFinality {
log.Warnf("Finality Violation Detected! The suggest pruning point %s violates finality!", newPruningPointHash)
return errors.Wrapf(ruleerrors.ErrSuggestedPruningViolatesFinality, "%s cannot be a pruning point because "+
"it violates finality", newPruningPointHash)
}
protoUTXOSet := &utxoserialization.ProtoUTXOSet{}
err = proto.Unmarshal(serializedUTXOSet, protoUTXOSet)
if err != nil {
return err
}
utxoSetMultiSet, err := utxoserialization.CalculateMultisetFromProtoUTXOSet(protoUTXOSet)
if err != nil {
return err
}
log.Debugf("Calculated multiset for given UTXO set: %s", utxoSetMultiSet.Hash())
newPruningPointHeader, err := csm.blockHeaderStore.BlockHeader(csm.databaseContext, newPruningPointHash)
if err != nil {
return err
}
log.Debugf("The UTXO commitment of the pruning point: %s",
newPruningPointHeader.UTXOCommitment())
if !newPruningPointHeader.UTXOCommitment().Equal(utxoSetMultiSet.Hash()) {
return errors.Wrapf(ruleerrors.ErrBadPruningPointUTXOSet, "the expected multiset hash of the pruning "+
"point UTXO set is %s but got %s", newPruningPointHeader.UTXOCommitment(), *utxoSetMultiSet.Hash())
}
log.Debugf("The new pruning point UTXO commitment validation passed")
newTips := []*externalapi.DomainHash{newPruningPointHash}
log.Debugf("Staging the the pruning point as the only DAG tip")
csm.consensusStateStore.StageTips(newTips)
log.Debugf("Setting the pruning point as the only virtual parent")
err = csm.dagTopologyManager.SetParents(model.VirtualBlockHash, newTips)
if err != nil {
return err
}
log.Debugf("Calculating GHOSTDAG for the new virtual")
err = csm.ghostdagManager.GHOSTDAG(model.VirtualBlockHash)
if err != nil {
return err
}
log.Debugf("Staging the virtual UTXO set")
err = csm.consensusStateStore.StageVirtualUTXOSet(protoUTXOSetToReadOnlyUTXOSetIterator(protoUTXOSet))
if err != nil {
return err
}
log.Debugf("Deleting all the existing virtual diff parents")
csm.consensusStateStore.StageVirtualDiffParents(nil)
log.Debugf("Updating the new pruning point to be the new virtual diff parent with an empty diff")
err = csm.stageDiff(newPruningPointHash, utxo.NewUTXODiff(), nil)
if err != nil {
return err
}
log.Debugf("Staging the new pruning point and its UTXO set")
csm.pruningStore.StagePruningPoint(newPruningPointHash, serializedUTXOSet)
// Before we manually mark the new pruning point as valid, we validate that all of its transactions are valid
// against the provided UTXO set.
log.Debugf("Validating that the pruning point is UTXO valid")
// validateBlockTransactionsAgainstPastUTXO pre-fills the block's transactions inputs, which
// are assumed to not be pre-filled during further validations.
// Therefore - clone newPruningPoint before passing it to validateBlockTransactionsAgainstPastUTXO
err = csm.validateBlockTransactionsAgainstPastUTXO(newPruningPoint.Clone(), utxo.NewUTXODiff())
if err != nil {
return err
}
log.Debugf("Staging the new pruning point as %s", externalapi.StatusUTXOValid)
csm.blockStatusStore.Stage(newPruningPointHash, externalapi.StatusUTXOValid)
log.Debugf("Staging the new pruning point multiset")
csm.multisetStore.Stage(newPruningPointHash, utxoSetMultiSet)
return nil
}
func (csm *consensusStateManager) discardSetPruningPointUTXOSetChanges() {
for _, store := range csm.stores {
store.Discard()
}
}
func (csm *consensusStateManager) commitSetPruningPointUTXOSetAll() error {
dbTx, err := csm.databaseContext.Begin()
if err != nil {
return err
}
for _, store := range csm.stores {
err = store.Commit(dbTx)
if err != nil {
return err
}
}
return dbTx.Commit()
}
type protoUTXOSetIterator struct {
utxoSet *utxoserialization.ProtoUTXOSet
index int
}
func (p *protoUTXOSetIterator) Next() bool {
p.index++
return p.index < len(p.utxoSet.Utxos)
}
func (p *protoUTXOSetIterator) Get() (outpoint *externalapi.DomainOutpoint, utxoEntry externalapi.UTXOEntry, err error) {
entry, outpoint, err := utxo.DeserializeUTXO(p.utxoSet.Utxos[p.index].EntryOutpointPair)
if err != nil {
if serialization.IsMalformedError(err) {
return nil, nil, errors.Wrapf(ruleerrors.ErrMalformedUTXO, "malformed utxo: %s", err)
}
return nil, nil, err
}
return outpoint, entry, nil
}
func protoUTXOSetToReadOnlyUTXOSetIterator(protoUTXOSet *utxoserialization.ProtoUTXOSet) model.ReadOnlyUTXOSetIterator {
return &protoUTXOSetIterator{utxoSet: protoUTXOSet, index: -1}
}

View File

@ -52,10 +52,7 @@ func (csm *consensusStateManager) updateVirtual(newBlockHash *externalapi.Domain
csm.multisetStore.Stage(model.VirtualBlockHash, virtualMultiset) csm.multisetStore.Stage(model.VirtualBlockHash, virtualMultiset)
log.Debugf("Staging new UTXO diff for the virtual block") log.Debugf("Staging new UTXO diff for the virtual block")
err = csm.consensusStateStore.StageVirtualUTXODiff(virtualUTXODiff) csm.consensusStateStore.StageVirtualUTXODiff(virtualUTXODiff)
if err != nil {
return nil, err
}
log.Debugf("Updating the virtual diff parents after adding %s to the DAG", newBlockHash) log.Debugf("Updating the virtual diff parents after adding %s to the DAG", newBlockHash)
err = csm.updateVirtualDiffParents(virtualUTXODiff) err = csm.updateVirtualDiffParents(virtualUTXODiff)

View File

@ -1,17 +1,18 @@
package pruningmanager package pruningmanager
import ( import (
"github.com/golang/protobuf/proto"
"github.com/kaspanet/kaspad/domain/consensus/model" "github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi" "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxoserialization" "github.com/kaspanet/kaspad/domain/consensus/utils/multiset"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
"github.com/kaspanet/kaspad/infrastructure/db/database"
"github.com/kaspanet/kaspad/infrastructure/logger" "github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// pruningManager resolves and manages the current pruning point // pruningManager resolves and manages the current pruning point
type pruningManager struct { type pruningManager struct {
databaseContext model.DBReader databaseContext model.DBManager
dagTraversalManager model.DAGTraversalManager dagTraversalManager model.DAGTraversalManager
dagTopologyManager model.DAGTopologyManager dagTopologyManager model.DAGTopologyManager
@ -36,7 +37,7 @@ type pruningManager struct {
// New instantiates a new PruningManager // New instantiates a new PruningManager
func New( func New(
databaseContext model.DBReader, databaseContext model.DBManager,
dagTraversalManager model.DAGTraversalManager, dagTraversalManager model.DAGTraversalManager,
dagTopologyManager model.DAGTopologyManager, dagTopologyManager model.DAGTopologyManager,
@ -310,16 +311,20 @@ func (pm *pruningManager) savePruningPoint(pruningPointHash *externalapi.DomainH
onEnd := logger.LogAndMeasureExecutionTime(log, "pruningManager.savePruningPoint") onEnd := logger.LogAndMeasureExecutionTime(log, "pruningManager.savePruningPoint")
defer onEnd() defer onEnd()
utxoIter, err := pm.consensusStateManager.RestorePastUTXOSetIterator(pruningPointHash) utxoSetIterator, err := pm.consensusStateManager.RestorePastUTXOSetIterator(pruningPointHash)
if err != nil { if err != nil {
return err return err
} }
serializedUtxo, err := pm.calculateAndValidateSerializedUTXOSet(utxoIter, pruningPointHash) // TODO: This is an assert that takes ~30 seconds to run
// It must be removed or optimized before launching testnet
err = pm.validateUTXOSetFitsCommitment(utxoSetIterator, pruningPointHash)
if err != nil { if err != nil {
return err return err
} }
pm.pruningStore.StagePruningPoint(pruningPointHash, serializedUtxo)
pm.pruningStore.StagePruningPoint(pruningPointHash)
pm.pruningStore.StagePruningPointUTXOSet(utxoSetIterator)
return nil return nil
} }
@ -410,32 +415,24 @@ func (pm *pruningManager) pruningPointCandidate() (*externalapi.DomainHash, erro
return pm.pruningStore.PruningPointCandidate(pm.databaseContext) return pm.pruningStore.PruningPointCandidate(pm.databaseContext)
} }
func (pm *pruningManager) calculateAndValidateSerializedUTXOSet(
iter model.ReadOnlyUTXOSetIterator, pruningPointHash *externalapi.DomainHash) ([]byte, error) {
serializedUtxo, err := utxoserialization.ReadOnlyUTXOSetToProtoUTXOSet(iter)
if err != nil {
return nil, err
}
err = pm.validateUTXOSetFitsCommitment(serializedUtxo, pruningPointHash)
if err != nil {
return nil, err
}
return proto.Marshal(serializedUtxo)
}
// validateUTXOSetFitsCommitment makes sure that the calculated UTXOSet of the new pruning point fits the commitment. // validateUTXOSetFitsCommitment makes sure that the calculated UTXOSet of the new pruning point fits the commitment.
// This is a sanity test, to make sure that kaspad doesn't store, and subsequently sends syncing peers the wrong UTXOSet. // This is a sanity test, to make sure that kaspad doesn't store, and subsequently sends syncing peers the wrong UTXOSet.
func (pm *pruningManager) validateUTXOSetFitsCommitment( func (pm *pruningManager) validateUTXOSetFitsCommitment(utxoSetIterator model.ReadOnlyUTXOSetIterator,
serializedUtxo *utxoserialization.ProtoUTXOSet, pruningPointHash *externalapi.DomainHash) error { pruningPointHash *externalapi.DomainHash) error {
utxoSetMultiSet, err := utxoserialization.CalculateMultisetFromProtoUTXOSet(serializedUtxo) utxoSetMultiset := multiset.New()
if err != nil { for ok := utxoSetIterator.First(); ok; ok = utxoSetIterator.Next() {
return err outpoint, entry, err := utxoSetIterator.Get()
if err != nil {
return err
}
serializedUTXO, err := utxo.SerializeUTXO(entry, outpoint)
if err != nil {
return err
}
utxoSetMultiset.Add(serializedUTXO)
} }
utxoSetHash := utxoSetMultiSet.Hash() utxoSetHash := utxoSetMultiset.Hash()
header, err := pm.blockHeaderStore.BlockHeader(pm.databaseContext, pruningPointHash) header, err := pm.blockHeaderStore.BlockHeader(pm.databaseContext, pruningPointHash)
if err != nil { if err != nil {
@ -459,3 +456,47 @@ func (pm *pruningManager) validateUTXOSetFitsCommitment(
func (pm *pruningManager) finalityScore(blueScore uint64) uint64 { func (pm *pruningManager) finalityScore(blueScore uint64) uint64 {
return blueScore / pm.finalityInterval return blueScore / pm.finalityInterval
} }
func (pm *pruningManager) ClearImportedPruningPointData() error {
err := pm.pruningStore.ClearImportedPruningPointMultiset(pm.databaseContext)
if err != nil {
return err
}
return pm.pruningStore.ClearImportedPruningPointUTXOs(pm.databaseContext)
}
func (pm *pruningManager) AppendImportedPruningPointUTXOs(
outpointAndUTXOEntryPairs []*externalapi.OutpointAndUTXOEntryPair) error {
dbTx, err := pm.databaseContext.Begin()
if err != nil {
return err
}
defer dbTx.RollbackUnlessClosed()
importedMultiset, err := pm.pruningStore.ImportedPruningPointMultiset(dbTx)
if err != nil {
if !database.IsNotFoundError(err) {
return err
}
importedMultiset = multiset.New()
}
for _, outpointAndUTXOEntryPair := range outpointAndUTXOEntryPairs {
serializedUTXO, err := utxo.SerializeUTXO(outpointAndUTXOEntryPair.UTXOEntry, outpointAndUTXOEntryPair.Outpoint)
if err != nil {
return err
}
importedMultiset.Add(serializedUTXO)
}
err = pm.pruningStore.UpdateImportedPruningPointMultiset(dbTx, importedMultiset)
if err != nil {
return err
}
err = pm.pruningStore.AppendImportedPruningPointUTXOs(dbTx, outpointAndUTXOEntryPairs)
if err != nil {
return err
}
return dbTx.Commit()
}

View File

@ -29,6 +29,11 @@ func (uc utxoCollection) Iterator() model.ReadOnlyUTXOSetIterator {
return &utxoCollectionIterator{index: -1, pairs: pairs} return &utxoCollectionIterator{index: -1, pairs: pairs}
} }
func (uci *utxoCollectionIterator) First() bool {
uci.index = 0
return len(uci.pairs) > 0
}
func (uci *utxoCollectionIterator) Next() bool { func (uci *utxoCollectionIterator) Next() bool {
uci.index++ uci.index++
return uci.index < len(uci.pairs) return uci.index < len(uci.pairs)

View File

@ -36,10 +36,31 @@ func IteratorWithDiff(iterator model.ReadOnlyUTXOSetIterator, diff model.UTXODif
return &readOnlyUTXOIteratorWithDiff{ return &readOnlyUTXOIteratorWithDiff{
baseIterator: iterator, baseIterator: iterator,
diff: d, diff: d,
toAddIterator: d.mutableUTXODiff.toAdd.Iterator(), toAddIterator: d.ToAdd().Iterator(),
}, nil }, nil
} }
func (r *readOnlyUTXOIteratorWithDiff) First() bool {
baseNotEmpty := r.baseIterator.First()
baseEmpty := !baseNotEmpty
r.toAddIterator = r.diff.ToAdd().Iterator()
toAddEmpty := r.diff.ToAdd().Len() == 0
if baseEmpty {
if toAddEmpty {
return false
}
return r.Next()
}
r.currentOutpoint, r.currentUTXOEntry, r.currentErr = r.baseIterator.Get()
if r.diff.mutableUTXODiff.toRemove.containsWithBlueScore(r.currentOutpoint, r.currentUTXOEntry.BlockBlueScore()) {
return r.Next()
}
return true
}
func (r *readOnlyUTXOIteratorWithDiff) Next() bool { func (r *readOnlyUTXOIteratorWithDiff) Next() bool {
for r.baseIterator.Next() { // keep looping until we reach an outpoint/entry pair that is not in r.diff.toRemove for r.baseIterator.Next() { // keep looping until we reach an outpoint/entry pair that is not in r.diff.toRemove
r.currentOutpoint, r.currentUTXOEntry, r.currentErr = r.baseIterator.Get() r.currentOutpoint, r.currentUTXOEntry, r.currentErr = r.baseIterator.Get()

View File

@ -1,3 +0,0 @@
//go:generate protoc --go_out=. --go-grpc_out=. --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative utxo.proto
package utxoserialization

View File

@ -1,15 +0,0 @@
package utxoserialization
import (
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/utils/multiset"
)
// CalculateMultisetFromProtoUTXOSet calculates the Multiset corresponding to the given ProtuUTXOSet
func CalculateMultisetFromProtoUTXOSet(protoUTXOSet *ProtoUTXOSet) (model.Multiset, error) {
ms := multiset.New()
for _, utxo := range protoUTXOSet.Utxos {
ms.Add(utxo.EntryOutpointPair)
}
return ms, nil
}

View File

@ -1,30 +0,0 @@
package utxoserialization
import (
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
)
// ReadOnlyUTXOSetToProtoUTXOSet converts ReadOnlyUTXOSetIterator to ProtoUTXOSet
func ReadOnlyUTXOSetToProtoUTXOSet(iter model.ReadOnlyUTXOSetIterator) (*ProtoUTXOSet, error) {
protoUTXOSet := &ProtoUTXOSet{
Utxos: []*ProtoUTXO{},
}
for iter.Next() {
outpoint, entry, err := iter.Get()
if err != nil {
return nil, err
}
serializedUTXOBytes, err := utxo.SerializeUTXO(entry, outpoint)
if err != nil {
return nil, err
}
protoUTXOSet.Utxos = append(protoUTXOSet.Utxos, &ProtoUTXO{
EntryOutpointPair: serializedUTXOBytes,
})
}
return protoUTXOSet, nil
}

View File

@ -1,217 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.12.3
// source: utxo.proto
package utxoserialization
import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type ProtoUTXO struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
EntryOutpointPair []byte `protobuf:"bytes,1,opt,name=entryOutpointPair,proto3" json:"entryOutpointPair,omitempty"`
}
func (x *ProtoUTXO) Reset() {
*x = ProtoUTXO{}
if protoimpl.UnsafeEnabled {
mi := &file_utxo_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ProtoUTXO) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ProtoUTXO) ProtoMessage() {}
func (x *ProtoUTXO) ProtoReflect() protoreflect.Message {
mi := &file_utxo_proto_msgTypes[0]
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 ProtoUTXO.ProtoReflect.Descriptor instead.
func (*ProtoUTXO) Descriptor() ([]byte, []int) {
return file_utxo_proto_rawDescGZIP(), []int{0}
}
func (x *ProtoUTXO) GetEntryOutpointPair() []byte {
if x != nil {
return x.EntryOutpointPair
}
return nil
}
type ProtoUTXOSet struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Utxos []*ProtoUTXO `protobuf:"bytes,1,rep,name=utxos,proto3" json:"utxos,omitempty"`
}
func (x *ProtoUTXOSet) Reset() {
*x = ProtoUTXOSet{}
if protoimpl.UnsafeEnabled {
mi := &file_utxo_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ProtoUTXOSet) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ProtoUTXOSet) ProtoMessage() {}
func (x *ProtoUTXOSet) ProtoReflect() protoreflect.Message {
mi := &file_utxo_proto_msgTypes[1]
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 ProtoUTXOSet.ProtoReflect.Descriptor instead.
func (*ProtoUTXOSet) Descriptor() ([]byte, []int) {
return file_utxo_proto_rawDescGZIP(), []int{1}
}
func (x *ProtoUTXOSet) GetUtxos() []*ProtoUTXO {
if x != nil {
return x.Utxos
}
return nil
}
var File_utxo_proto protoreflect.FileDescriptor
var file_utxo_proto_rawDesc = []byte{
0x0a, 0x0a, 0x75, 0x74, 0x78, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x75, 0x74,
0x78, 0x6f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22,
0x39, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x55, 0x54, 0x58, 0x4f, 0x12, 0x2c, 0x0a, 0x11,
0x65, 0x6e, 0x74, 0x72, 0x79, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x50, 0x61, 0x69,
0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x4f, 0x75,
0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x50, 0x61, 0x69, 0x72, 0x22, 0x42, 0x0a, 0x0c, 0x50, 0x72,
0x6f, 0x74, 0x6f, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x12, 0x32, 0x0a, 0x05, 0x75, 0x74,
0x78, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x74, 0x78, 0x6f,
0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x72,
0x6f, 0x74, 0x6f, 0x55, 0x54, 0x58, 0x4f, 0x52, 0x05, 0x75, 0x74, 0x78, 0x6f, 0x73, 0x42, 0x45,
0x5a, 0x43, 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, 0x64, 0x6f, 0x6d,
0x61, 0x69, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2f, 0x75, 0x74,
0x69, 0x6c, 0x73, 0x2f, 0x75, 0x74, 0x78, 0x6f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_utxo_proto_rawDescOnce sync.Once
file_utxo_proto_rawDescData = file_utxo_proto_rawDesc
)
func file_utxo_proto_rawDescGZIP() []byte {
file_utxo_proto_rawDescOnce.Do(func() {
file_utxo_proto_rawDescData = protoimpl.X.CompressGZIP(file_utxo_proto_rawDescData)
})
return file_utxo_proto_rawDescData
}
var file_utxo_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_utxo_proto_goTypes = []interface{}{
(*ProtoUTXO)(nil), // 0: utxoserialization.ProtoUTXO
(*ProtoUTXOSet)(nil), // 1: utxoserialization.ProtoUTXOSet
}
var file_utxo_proto_depIdxs = []int32{
0, // 0: utxoserialization.ProtoUTXOSet.utxos:type_name -> utxoserialization.ProtoUTXO
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_utxo_proto_init() }
func file_utxo_proto_init() {
if File_utxo_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_utxo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ProtoUTXO); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_utxo_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ProtoUTXOSet); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_utxo_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_utxo_proto_goTypes,
DependencyIndexes: file_utxo_proto_depIdxs,
MessageInfos: file_utxo_proto_msgTypes,
}.Build()
File_utxo_proto = out.File
file_utxo_proto_rawDesc = nil
file_utxo_proto_goTypes = nil
file_utxo_proto_depIdxs = nil
}

View File

@ -1,12 +0,0 @@
syntax = "proto3";
package utxoserialization;
option go_package = "github.com/kaspanet/kaspad/domain/consensus/utils/utxoserialization";
message ProtoUTXO {
bytes entryOutpointPair = 1;
}
message ProtoUTXOSet {
repeated ProtoUTXO utxos = 1;
}

View File

@ -28,17 +28,17 @@ message KaspadMessage {
VersionMessage version = 20; VersionMessage version = 20;
TransactionNotFoundMessage transactionNotFound = 21; TransactionNotFoundMessage transactionNotFound = 21;
RejectMessage reject = 22; RejectMessage reject = 22;
RequestIBDRootUTXOSetAndBlockMessage requestIBDRootUTXOSetAndBlock = 24; RequestPruningPointUTXOSetAndBlockMessage requestPruningPointUTXOSetAndBlock = 24;
IbdRootUtxoSetChunkMessage ibdRootUtxoSetChunk = 25; PruningPointUtxoSetChunkMessage pruningPointUtxoSetChunk = 25;
RequestIBDBlocksMessage requestIBDBlocks = 26; RequestIBDBlocksMessage requestIBDBlocks = 26;
IBDRootNotFoundMessage ibdRootNotFound = 27; UnexpectedPruningPointMessage unexpectedPruningPoint = 27;
RequestIBDRootHashMessage requestIBDRootHash = 28; RequestPruningPointHashMessage requestPruningPointHash = 28;
IBDRootHashMessage ibdRootHash = 29; PruningPointHashMessage pruningPointHash = 29;
IbdBlockLocatorMessage ibdBlockLocator = 30; IbdBlockLocatorMessage ibdBlockLocator = 30;
IbdBlockLocatorHighestHashMessage ibdBlockLocatorHighestHash = 31; IbdBlockLocatorHighestHashMessage ibdBlockLocatorHighestHash = 31;
BlockHeadersMessage blockHeaders = 32; BlockHeadersMessage blockHeaders = 32;
RequestNextIbdRootUtxoSetChunkMessage requestNextIbdRootUtxoSetChunk = 33; RequestNextPruningPointUtxoSetChunkMessage requestNextPruningPointUtxoSetChunk = 33;
DoneIbdRootUtxoSetChunksMessage doneIbdRootUtxoSetChunks = 34; DonePruningPointUtxoSetChunksMessage donePruningPointUtxoSetChunks = 34;
GetCurrentNetworkRequestMessage getCurrentNetworkRequest = 1001; GetCurrentNetworkRequestMessage getCurrentNetworkRequest = 1001;
GetCurrentNetworkResponseMessage getCurrentNetworkResponse = 1002; GetCurrentNetworkResponseMessage getCurrentNetworkResponse = 1002;

View File

@ -1594,16 +1594,16 @@ func (x *RejectMessage) GetReason() string {
return "" return ""
} }
type RequestIBDRootUTXOSetAndBlockMessage struct { type RequestPruningPointUTXOSetAndBlockMessage struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
IbdRoot *Hash `protobuf:"bytes,1,opt,name=ibdRoot,proto3" json:"ibdRoot,omitempty"` PruningPointHash *Hash `protobuf:"bytes,1,opt,name=pruningPointHash,proto3" json:"pruningPointHash,omitempty"`
} }
func (x *RequestIBDRootUTXOSetAndBlockMessage) Reset() { func (x *RequestPruningPointUTXOSetAndBlockMessage) Reset() {
*x = RequestIBDRootUTXOSetAndBlockMessage{} *x = RequestPruningPointUTXOSetAndBlockMessage{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[28] mi := &file_p2p_proto_msgTypes[28]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -1611,13 +1611,13 @@ func (x *RequestIBDRootUTXOSetAndBlockMessage) Reset() {
} }
} }
func (x *RequestIBDRootUTXOSetAndBlockMessage) String() string { func (x *RequestPruningPointUTXOSetAndBlockMessage) String() string {
return protoimpl.X.MessageStringOf(x) return protoimpl.X.MessageStringOf(x)
} }
func (*RequestIBDRootUTXOSetAndBlockMessage) ProtoMessage() {} func (*RequestPruningPointUTXOSetAndBlockMessage) ProtoMessage() {}
func (x *RequestIBDRootUTXOSetAndBlockMessage) ProtoReflect() protoreflect.Message { func (x *RequestPruningPointUTXOSetAndBlockMessage) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[28] mi := &file_p2p_proto_msgTypes[28]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -1629,28 +1629,28 @@ func (x *RequestIBDRootUTXOSetAndBlockMessage) ProtoReflect() protoreflect.Messa
return mi.MessageOf(x) return mi.MessageOf(x)
} }
// Deprecated: Use RequestIBDRootUTXOSetAndBlockMessage.ProtoReflect.Descriptor instead. // Deprecated: Use RequestPruningPointUTXOSetAndBlockMessage.ProtoReflect.Descriptor instead.
func (*RequestIBDRootUTXOSetAndBlockMessage) Descriptor() ([]byte, []int) { func (*RequestPruningPointUTXOSetAndBlockMessage) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{28} return file_p2p_proto_rawDescGZIP(), []int{28}
} }
func (x *RequestIBDRootUTXOSetAndBlockMessage) GetIbdRoot() *Hash { func (x *RequestPruningPointUTXOSetAndBlockMessage) GetPruningPointHash() *Hash {
if x != nil { if x != nil {
return x.IbdRoot return x.PruningPointHash
} }
return nil return nil
} }
type IbdRootUtxoSetChunkMessage struct { type PruningPointUtxoSetChunkMessage struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Chunk []byte `protobuf:"bytes,1,opt,name=chunk,proto3" json:"chunk,omitempty"` OutpointAndUtxoEntryPairs []*OutpointAndUtxoEntryPair `protobuf:"bytes,1,rep,name=outpointAndUtxoEntryPairs,proto3" json:"outpointAndUtxoEntryPairs,omitempty"`
} }
func (x *IbdRootUtxoSetChunkMessage) Reset() { func (x *PruningPointUtxoSetChunkMessage) Reset() {
*x = IbdRootUtxoSetChunkMessage{} *x = PruningPointUtxoSetChunkMessage{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[29] mi := &file_p2p_proto_msgTypes[29]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -1658,13 +1658,13 @@ func (x *IbdRootUtxoSetChunkMessage) Reset() {
} }
} }
func (x *IbdRootUtxoSetChunkMessage) String() string { func (x *PruningPointUtxoSetChunkMessage) String() string {
return protoimpl.X.MessageStringOf(x) return protoimpl.X.MessageStringOf(x)
} }
func (*IbdRootUtxoSetChunkMessage) ProtoMessage() {} func (*PruningPointUtxoSetChunkMessage) ProtoMessage() {}
func (x *IbdRootUtxoSetChunkMessage) ProtoReflect() protoreflect.Message { func (x *PruningPointUtxoSetChunkMessage) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[29] mi := &file_p2p_proto_msgTypes[29]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -1676,26 +1676,29 @@ func (x *IbdRootUtxoSetChunkMessage) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x) return mi.MessageOf(x)
} }
// Deprecated: Use IbdRootUtxoSetChunkMessage.ProtoReflect.Descriptor instead. // Deprecated: Use PruningPointUtxoSetChunkMessage.ProtoReflect.Descriptor instead.
func (*IbdRootUtxoSetChunkMessage) Descriptor() ([]byte, []int) { func (*PruningPointUtxoSetChunkMessage) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{29} return file_p2p_proto_rawDescGZIP(), []int{29}
} }
func (x *IbdRootUtxoSetChunkMessage) GetChunk() []byte { func (x *PruningPointUtxoSetChunkMessage) GetOutpointAndUtxoEntryPairs() []*OutpointAndUtxoEntryPair {
if x != nil { if x != nil {
return x.Chunk return x.OutpointAndUtxoEntryPairs
} }
return nil return nil
} }
type RequestNextIbdRootUtxoSetChunkMessage struct { type OutpointAndUtxoEntryPair struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Outpoint *Outpoint `protobuf:"bytes,1,opt,name=outpoint,proto3" json:"outpoint,omitempty"`
UtxoEntry *UtxoEntry `protobuf:"bytes,2,opt,name=utxoEntry,proto3" json:"utxoEntry,omitempty"`
} }
func (x *RequestNextIbdRootUtxoSetChunkMessage) Reset() { func (x *OutpointAndUtxoEntryPair) Reset() {
*x = RequestNextIbdRootUtxoSetChunkMessage{} *x = OutpointAndUtxoEntryPair{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[30] mi := &file_p2p_proto_msgTypes[30]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -1703,13 +1706,13 @@ func (x *RequestNextIbdRootUtxoSetChunkMessage) Reset() {
} }
} }
func (x *RequestNextIbdRootUtxoSetChunkMessage) String() string { func (x *OutpointAndUtxoEntryPair) String() string {
return protoimpl.X.MessageStringOf(x) return protoimpl.X.MessageStringOf(x)
} }
func (*RequestNextIbdRootUtxoSetChunkMessage) ProtoMessage() {} func (*OutpointAndUtxoEntryPair) ProtoMessage() {}
func (x *RequestNextIbdRootUtxoSetChunkMessage) ProtoReflect() protoreflect.Message { func (x *OutpointAndUtxoEntryPair) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[30] mi := &file_p2p_proto_msgTypes[30]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -1721,19 +1724,38 @@ func (x *RequestNextIbdRootUtxoSetChunkMessage) ProtoReflect() protoreflect.Mess
return mi.MessageOf(x) return mi.MessageOf(x)
} }
// Deprecated: Use RequestNextIbdRootUtxoSetChunkMessage.ProtoReflect.Descriptor instead. // Deprecated: Use OutpointAndUtxoEntryPair.ProtoReflect.Descriptor instead.
func (*RequestNextIbdRootUtxoSetChunkMessage) Descriptor() ([]byte, []int) { func (*OutpointAndUtxoEntryPair) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{30} return file_p2p_proto_rawDescGZIP(), []int{30}
} }
type DoneIbdRootUtxoSetChunksMessage struct { func (x *OutpointAndUtxoEntryPair) GetOutpoint() *Outpoint {
if x != nil {
return x.Outpoint
}
return nil
}
func (x *OutpointAndUtxoEntryPair) GetUtxoEntry() *UtxoEntry {
if x != nil {
return x.UtxoEntry
}
return nil
}
type UtxoEntry struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Amount uint64 `protobuf:"varint,1,opt,name=amount,proto3" json:"amount,omitempty"`
ScriptPublicKey *ScriptPublicKey `protobuf:"bytes,2,opt,name=scriptPublicKey,proto3" json:"scriptPublicKey,omitempty"`
BlockBlueScore uint64 `protobuf:"varint,3,opt,name=blockBlueScore,proto3" json:"blockBlueScore,omitempty"`
IsCoinbase bool `protobuf:"varint,4,opt,name=isCoinbase,proto3" json:"isCoinbase,omitempty"`
} }
func (x *DoneIbdRootUtxoSetChunksMessage) Reset() { func (x *UtxoEntry) Reset() {
*x = DoneIbdRootUtxoSetChunksMessage{} *x = UtxoEntry{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[31] mi := &file_p2p_proto_msgTypes[31]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -1741,13 +1763,13 @@ func (x *DoneIbdRootUtxoSetChunksMessage) Reset() {
} }
} }
func (x *DoneIbdRootUtxoSetChunksMessage) String() string { func (x *UtxoEntry) String() string {
return protoimpl.X.MessageStringOf(x) return protoimpl.X.MessageStringOf(x)
} }
func (*DoneIbdRootUtxoSetChunksMessage) ProtoMessage() {} func (*UtxoEntry) ProtoMessage() {}
func (x *DoneIbdRootUtxoSetChunksMessage) ProtoReflect() protoreflect.Message { func (x *UtxoEntry) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[31] mi := &file_p2p_proto_msgTypes[31]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -1759,11 +1781,115 @@ func (x *DoneIbdRootUtxoSetChunksMessage) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x) return mi.MessageOf(x)
} }
// Deprecated: Use DoneIbdRootUtxoSetChunksMessage.ProtoReflect.Descriptor instead. // Deprecated: Use UtxoEntry.ProtoReflect.Descriptor instead.
func (*DoneIbdRootUtxoSetChunksMessage) Descriptor() ([]byte, []int) { func (*UtxoEntry) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{31} return file_p2p_proto_rawDescGZIP(), []int{31}
} }
func (x *UtxoEntry) GetAmount() uint64 {
if x != nil {
return x.Amount
}
return 0
}
func (x *UtxoEntry) GetScriptPublicKey() *ScriptPublicKey {
if x != nil {
return x.ScriptPublicKey
}
return nil
}
func (x *UtxoEntry) GetBlockBlueScore() uint64 {
if x != nil {
return x.BlockBlueScore
}
return 0
}
func (x *UtxoEntry) GetIsCoinbase() bool {
if x != nil {
return x.IsCoinbase
}
return false
}
type RequestNextPruningPointUtxoSetChunkMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *RequestNextPruningPointUtxoSetChunkMessage) Reset() {
*x = RequestNextPruningPointUtxoSetChunkMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[32]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RequestNextPruningPointUtxoSetChunkMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RequestNextPruningPointUtxoSetChunkMessage) ProtoMessage() {}
func (x *RequestNextPruningPointUtxoSetChunkMessage) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[32]
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 RequestNextPruningPointUtxoSetChunkMessage.ProtoReflect.Descriptor instead.
func (*RequestNextPruningPointUtxoSetChunkMessage) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{32}
}
type DonePruningPointUtxoSetChunksMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *DonePruningPointUtxoSetChunksMessage) Reset() {
*x = DonePruningPointUtxoSetChunksMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[33]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *DonePruningPointUtxoSetChunksMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DonePruningPointUtxoSetChunksMessage) ProtoMessage() {}
func (x *DonePruningPointUtxoSetChunksMessage) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[33]
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 DonePruningPointUtxoSetChunksMessage.ProtoReflect.Descriptor instead.
func (*DonePruningPointUtxoSetChunksMessage) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{33}
}
type RequestIBDBlocksMessage struct { type RequestIBDBlocksMessage struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -1775,7 +1901,7 @@ type RequestIBDBlocksMessage struct {
func (x *RequestIBDBlocksMessage) Reset() { func (x *RequestIBDBlocksMessage) Reset() {
*x = RequestIBDBlocksMessage{} *x = RequestIBDBlocksMessage{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[32] mi := &file_p2p_proto_msgTypes[34]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -1788,7 +1914,7 @@ func (x *RequestIBDBlocksMessage) String() string {
func (*RequestIBDBlocksMessage) ProtoMessage() {} func (*RequestIBDBlocksMessage) ProtoMessage() {}
func (x *RequestIBDBlocksMessage) ProtoReflect() protoreflect.Message { func (x *RequestIBDBlocksMessage) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[32] mi := &file_p2p_proto_msgTypes[34]
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 {
@ -1801,7 +1927,7 @@ func (x *RequestIBDBlocksMessage) ProtoReflect() protoreflect.Message {
// Deprecated: Use RequestIBDBlocksMessage.ProtoReflect.Descriptor instead. // Deprecated: Use RequestIBDBlocksMessage.ProtoReflect.Descriptor instead.
func (*RequestIBDBlocksMessage) Descriptor() ([]byte, []int) { func (*RequestIBDBlocksMessage) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{32} return file_p2p_proto_rawDescGZIP(), []int{34}
} }
func (x *RequestIBDBlocksMessage) GetHashes() []*Hash { func (x *RequestIBDBlocksMessage) GetHashes() []*Hash {
@ -1811,92 +1937,14 @@ func (x *RequestIBDBlocksMessage) GetHashes() []*Hash {
return nil return nil
} }
type IBDRootNotFoundMessage struct { type UnexpectedPruningPointMessage struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
} }
func (x *IBDRootNotFoundMessage) Reset() { func (x *UnexpectedPruningPointMessage) Reset() {
*x = IBDRootNotFoundMessage{} *x = UnexpectedPruningPointMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[33]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *IBDRootNotFoundMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*IBDRootNotFoundMessage) ProtoMessage() {}
func (x *IBDRootNotFoundMessage) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[33]
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 IBDRootNotFoundMessage.ProtoReflect.Descriptor instead.
func (*IBDRootNotFoundMessage) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{33}
}
type RequestIBDRootHashMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *RequestIBDRootHashMessage) Reset() {
*x = RequestIBDRootHashMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[34]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RequestIBDRootHashMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RequestIBDRootHashMessage) ProtoMessage() {}
func (x *RequestIBDRootHashMessage) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[34]
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 RequestIBDRootHashMessage.ProtoReflect.Descriptor instead.
func (*RequestIBDRootHashMessage) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{34}
}
type IBDRootHashMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Hash *Hash `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
}
func (x *IBDRootHashMessage) Reset() {
*x = IBDRootHashMessage{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[35] mi := &file_p2p_proto_msgTypes[35]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -1904,13 +1952,13 @@ func (x *IBDRootHashMessage) Reset() {
} }
} }
func (x *IBDRootHashMessage) String() string { func (x *UnexpectedPruningPointMessage) String() string {
return protoimpl.X.MessageStringOf(x) return protoimpl.X.MessageStringOf(x)
} }
func (*IBDRootHashMessage) ProtoMessage() {} func (*UnexpectedPruningPointMessage) ProtoMessage() {}
func (x *IBDRootHashMessage) ProtoReflect() protoreflect.Message { func (x *UnexpectedPruningPointMessage) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[35] mi := &file_p2p_proto_msgTypes[35]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -1922,12 +1970,90 @@ func (x *IBDRootHashMessage) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x) return mi.MessageOf(x)
} }
// Deprecated: Use IBDRootHashMessage.ProtoReflect.Descriptor instead. // Deprecated: Use UnexpectedPruningPointMessage.ProtoReflect.Descriptor instead.
func (*IBDRootHashMessage) Descriptor() ([]byte, []int) { func (*UnexpectedPruningPointMessage) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{35} return file_p2p_proto_rawDescGZIP(), []int{35}
} }
func (x *IBDRootHashMessage) GetHash() *Hash { type RequestPruningPointHashMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *RequestPruningPointHashMessage) Reset() {
*x = RequestPruningPointHashMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[36]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RequestPruningPointHashMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RequestPruningPointHashMessage) ProtoMessage() {}
func (x *RequestPruningPointHashMessage) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[36]
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 RequestPruningPointHashMessage.ProtoReflect.Descriptor instead.
func (*RequestPruningPointHashMessage) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{36}
}
type PruningPointHashMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Hash *Hash `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
}
func (x *PruningPointHashMessage) Reset() {
*x = PruningPointHashMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[37]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PruningPointHashMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PruningPointHashMessage) ProtoMessage() {}
func (x *PruningPointHashMessage) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[37]
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 PruningPointHashMessage.ProtoReflect.Descriptor instead.
func (*PruningPointHashMessage) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{37}
}
func (x *PruningPointHashMessage) GetHash() *Hash {
if x != nil { if x != nil {
return x.Hash return x.Hash
} }
@ -1946,7 +2072,7 @@ type IbdBlockLocatorMessage struct {
func (x *IbdBlockLocatorMessage) Reset() { func (x *IbdBlockLocatorMessage) Reset() {
*x = IbdBlockLocatorMessage{} *x = IbdBlockLocatorMessage{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[36] mi := &file_p2p_proto_msgTypes[38]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -1959,7 +2085,7 @@ func (x *IbdBlockLocatorMessage) String() string {
func (*IbdBlockLocatorMessage) ProtoMessage() {} func (*IbdBlockLocatorMessage) ProtoMessage() {}
func (x *IbdBlockLocatorMessage) ProtoReflect() protoreflect.Message { func (x *IbdBlockLocatorMessage) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[36] mi := &file_p2p_proto_msgTypes[38]
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 {
@ -1972,7 +2098,7 @@ func (x *IbdBlockLocatorMessage) ProtoReflect() protoreflect.Message {
// Deprecated: Use IbdBlockLocatorMessage.ProtoReflect.Descriptor instead. // Deprecated: Use IbdBlockLocatorMessage.ProtoReflect.Descriptor instead.
func (*IbdBlockLocatorMessage) Descriptor() ([]byte, []int) { func (*IbdBlockLocatorMessage) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{36} return file_p2p_proto_rawDescGZIP(), []int{38}
} }
func (x *IbdBlockLocatorMessage) GetTargetHash() *Hash { func (x *IbdBlockLocatorMessage) GetTargetHash() *Hash {
@ -2000,7 +2126,7 @@ type IbdBlockLocatorHighestHashMessage struct {
func (x *IbdBlockLocatorHighestHashMessage) Reset() { func (x *IbdBlockLocatorHighestHashMessage) Reset() {
*x = IbdBlockLocatorHighestHashMessage{} *x = IbdBlockLocatorHighestHashMessage{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_p2p_proto_msgTypes[37] mi := &file_p2p_proto_msgTypes[39]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -2013,7 +2139,7 @@ func (x *IbdBlockLocatorHighestHashMessage) String() string {
func (*IbdBlockLocatorHighestHashMessage) ProtoMessage() {} func (*IbdBlockLocatorHighestHashMessage) ProtoMessage() {}
func (x *IbdBlockLocatorHighestHashMessage) ProtoReflect() protoreflect.Message { func (x *IbdBlockLocatorHighestHashMessage) ProtoReflect() protoreflect.Message {
mi := &file_p2p_proto_msgTypes[37] mi := &file_p2p_proto_msgTypes[39]
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 {
@ -2026,7 +2152,7 @@ func (x *IbdBlockLocatorHighestHashMessage) ProtoReflect() protoreflect.Message
// Deprecated: Use IbdBlockLocatorHighestHashMessage.ProtoReflect.Descriptor instead. // Deprecated: Use IbdBlockLocatorHighestHashMessage.ProtoReflect.Descriptor instead.
func (*IbdBlockLocatorHighestHashMessage) Descriptor() ([]byte, []int) { func (*IbdBlockLocatorHighestHashMessage) Descriptor() ([]byte, []int) {
return file_p2p_proto_rawDescGZIP(), []int{37} return file_p2p_proto_rawDescGZIP(), []int{39}
} }
func (x *IbdBlockLocatorHighestHashMessage) GetHighestHash() *Hash { func (x *IbdBlockLocatorHighestHashMessage) GetHighestHash() *Hash {
@ -2047,7 +2173,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[38] mi := &file_p2p_proto_msgTypes[40]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -2060,7 +2186,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[38] mi := &file_p2p_proto_msgTypes[40]
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 {
@ -2073,7 +2199,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{38} return file_p2p_proto_rawDescGZIP(), []int{40}
} }
func (x *BlockHeadersMessage) GetBlockHeaders() []*BlockHeaderMessage { func (x *BlockHeadersMessage) GetBlockHeaders() []*BlockHeaderMessage {
@ -2268,54 +2394,82 @@ var file_p2p_proto_rawDesc = []byte{
0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x22, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x22,
0x27, 0x0a, 0x0d, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x27, 0x0a, 0x0d, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x51, 0x0a, 0x24, 0x52, 0x65, 0x71, 0x75, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x68, 0x0a, 0x29, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x49, 0x42, 0x44, 0x52, 0x6f, 0x6f, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x65, 0x73, 0x74, 0x50, 0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x55,
0x74, 0x41, 0x6e, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x41, 0x6e, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65,
0x12, 0x29, 0x0a, 0x07, 0x69, 0x62, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x10, 0x70, 0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67,
0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x48, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x73, 0x68, 0x52, 0x07, 0x69, 0x62, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x22, 0x32, 0x0a, 0x1a, 0x49, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x48, 0x61, 0x73, 0x68,
0x62, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x55, 0x74, 0x78, 0x6f, 0x53, 0x65, 0x74, 0x43, 0x68, 0x75, 0x52, 0x10, 0x70, 0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x61,
0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, 0x75, 0x73, 0x68, 0x22, 0x84, 0x01, 0x0a, 0x1f, 0x50, 0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f,
0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x22, 0x69, 0x6e, 0x74, 0x55, 0x74, 0x78, 0x6f, 0x53, 0x65, 0x74, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x4d,
0x27, 0x0a, 0x25, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4e, 0x65, 0x78, 0x74, 0x49, 0x62, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x61, 0x0a, 0x19, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69,
0x64, 0x52, 0x6f, 0x6f, 0x74, 0x55, 0x74, 0x78, 0x6f, 0x53, 0x65, 0x74, 0x43, 0x68, 0x75, 0x6e, 0x6e, 0x74, 0x41, 0x6e, 0x64, 0x55, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x61,
0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x44, 0x6f, 0x6e, 0x65, 0x69, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x49, 0x62, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x55, 0x74, 0x78, 0x6f, 0x53, 0x65, 0x74, 0x43, 0x68, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x41, 0x6e,
0x75, 0x6e, 0x6b, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x42, 0x0a, 0x17, 0x52, 0x64, 0x55, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x61, 0x69, 0x72, 0x52, 0x19,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x42, 0x44, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x4d, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x41, 0x6e, 0x64, 0x55, 0x74, 0x78, 0x6f, 0x45,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x61, 0x69, 0x72, 0x73, 0x22, 0x7f, 0x0a, 0x18, 0x4f, 0x75, 0x74,
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x41, 0x6e, 0x64, 0x55, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72,
0x72, 0x65, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x79, 0x50, 0x61, 0x69, 0x72, 0x12, 0x2f, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e,
0x18, 0x0a, 0x16, 0x49, 0x42, 0x44, 0x52, 0x6f, 0x6f, 0x74, 0x4e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77,
0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x1b, 0x0a, 0x19, 0x52, 0x65, 0x71, 0x69, 0x72, 0x65, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x08, 0x6f, 0x75,
0x75, 0x65, 0x73, 0x74, 0x49, 0x42, 0x44, 0x52, 0x6f, 0x6f, 0x74, 0x48, 0x61, 0x73, 0x68, 0x4d, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x09, 0x75, 0x74, 0x78, 0x6f, 0x45, 0x6e,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x39, 0x0a, 0x12, 0x49, 0x42, 0x44, 0x52, 0x6f, 0x6f, 0x74, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x74, 0x48, 0x61, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x55, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x09, 0x75, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x22, 0xb1, 0x01, 0x0a, 0x09, 0x55,
0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x04, 0x68, 0x61, 0x73, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75,
0x68, 0x22, 0x8a, 0x01, 0x0a, 0x16, 0x49, 0x62, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4c, 0x6f, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
0x63, 0x61, 0x74, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2f, 0x0a, 0x0a, 0x12, 0x44, 0x0a, 0x0f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63,
0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x48, 0x61, 0x73, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x50, 0x75, 0x62, 0x6c,
0x68, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x3f, 0x0a, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x0f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x50, 0x75, 0x62,
0x12, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x48, 0x61, 0x73, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x42,
0x68, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6c, 0x75, 0x65, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e,
0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x12, 0x62, 0x6c, 0x6f, 0x63, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x6c, 0x75, 0x65, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x1e,
0x6b, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x56, 0x0a, 0x0a, 0x69, 0x73, 0x43, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01,
0x0a, 0x21, 0x49, 0x62, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x43, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, 0x22, 0x2c,
0x72, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x48, 0x61, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x0a, 0x2a, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4e, 0x65, 0x78, 0x74, 0x50, 0x72, 0x75,
0x61, 0x67, 0x65, 0x12, 0x31, 0x0a, 0x0b, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x48, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x55, 0x74, 0x78, 0x6f, 0x53, 0x65, 0x74,
0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x26, 0x0a, 0x24,
0x77, 0x69, 0x72, 0x65, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x0b, 0x68, 0x69, 0x67, 0x68, 0x65, 0x44, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74,
0x73, 0x74, 0x48, 0x61, 0x73, 0x68, 0x22, 0x58, 0x0a, 0x13, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x55, 0x74, 0x78, 0x6f, 0x53, 0x65, 0x74, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x4d, 0x65, 0x73,
0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x41, 0x0a, 0x73, 0x61, 0x67, 0x65, 0x22, 0x42, 0x0a, 0x17, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x42, 0x44, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x27, 0x0a, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x48, 0x61, 0x73, 0x68,
0x67, 0x65, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x52, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x1f, 0x0a, 0x1d, 0x55, 0x6e, 0x65, 0x78,
0x42, 0x26, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50, 0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69,
0x61, 0x73, 0x70, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x2f, 0x70, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x20, 0x0a, 0x1e, 0x52, 0x65, 0x71,
0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x75, 0x65, 0x73, 0x74, 0x50, 0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74,
0x48, 0x61, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x3e, 0x0a, 0x17, 0x50,
0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65,
0x2e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x8a, 0x01, 0x0a, 0x16,
0x49, 0x62, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2f, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x0a, 0x74, 0x61, 0x72,
0x67, 0x65, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x3f, 0x0a, 0x12, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x02, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e,
0x48, 0x61, 0x73, 0x68, 0x52, 0x12, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4c, 0x6f, 0x63, 0x61, 0x74,
0x6f, 0x72, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x56, 0x0a, 0x21, 0x49, 0x62, 0x64, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x48, 0x69, 0x67, 0x68, 0x65,
0x73, 0x74, 0x48, 0x61, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x31, 0x0a,
0x0b, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x48,
0x61, 0x73, 0x68, 0x52, 0x0b, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x48, 0x61, 0x73, 0x68,
0x22, 0x58, 0x0a, 0x13, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48,
0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0c, 0x62, 0x6c,
0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x42, 0x26, 0x5a, 0x24, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x6e, 0x65,
0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69,
0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -2330,47 +2484,49 @@ func file_p2p_proto_rawDescGZIP() []byte {
return file_p2p_proto_rawDescData return file_p2p_proto_rawDescData
} }
var file_p2p_proto_msgTypes = make([]protoimpl.MessageInfo, 39) var file_p2p_proto_msgTypes = make([]protoimpl.MessageInfo, 41)
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
(*NetAddress)(nil), // 2: protowire.NetAddress (*NetAddress)(nil), // 2: protowire.NetAddress
(*SubnetworkId)(nil), // 3: protowire.SubnetworkId (*SubnetworkId)(nil), // 3: protowire.SubnetworkId
(*TransactionMessage)(nil), // 4: protowire.TransactionMessage (*TransactionMessage)(nil), // 4: protowire.TransactionMessage
(*TransactionInput)(nil), // 5: protowire.TransactionInput (*TransactionInput)(nil), // 5: protowire.TransactionInput
(*Outpoint)(nil), // 6: protowire.Outpoint (*Outpoint)(nil), // 6: protowire.Outpoint
(*TransactionId)(nil), // 7: protowire.TransactionId (*TransactionId)(nil), // 7: protowire.TransactionId
(*ScriptPublicKey)(nil), // 8: protowire.ScriptPublicKey (*ScriptPublicKey)(nil), // 8: protowire.ScriptPublicKey
(*TransactionOutput)(nil), // 9: protowire.TransactionOutput (*TransactionOutput)(nil), // 9: protowire.TransactionOutput
(*BlockMessage)(nil), // 10: protowire.BlockMessage (*BlockMessage)(nil), // 10: protowire.BlockMessage
(*BlockHeaderMessage)(nil), // 11: protowire.BlockHeaderMessage (*BlockHeaderMessage)(nil), // 11: protowire.BlockHeaderMessage
(*Hash)(nil), // 12: protowire.Hash (*Hash)(nil), // 12: protowire.Hash
(*RequestBlockLocatorMessage)(nil), // 13: protowire.RequestBlockLocatorMessage (*RequestBlockLocatorMessage)(nil), // 13: protowire.RequestBlockLocatorMessage
(*BlockLocatorMessage)(nil), // 14: protowire.BlockLocatorMessage (*BlockLocatorMessage)(nil), // 14: protowire.BlockLocatorMessage
(*RequestHeadersMessage)(nil), // 15: protowire.RequestHeadersMessage (*RequestHeadersMessage)(nil), // 15: protowire.RequestHeadersMessage
(*RequestNextHeadersMessage)(nil), // 16: protowire.RequestNextHeadersMessage (*RequestNextHeadersMessage)(nil), // 16: protowire.RequestNextHeadersMessage
(*DoneHeadersMessage)(nil), // 17: protowire.DoneHeadersMessage (*DoneHeadersMessage)(nil), // 17: protowire.DoneHeadersMessage
(*RequestRelayBlocksMessage)(nil), // 18: protowire.RequestRelayBlocksMessage (*RequestRelayBlocksMessage)(nil), // 18: protowire.RequestRelayBlocksMessage
(*RequestTransactionsMessage)(nil), // 19: protowire.RequestTransactionsMessage (*RequestTransactionsMessage)(nil), // 19: protowire.RequestTransactionsMessage
(*TransactionNotFoundMessage)(nil), // 20: protowire.TransactionNotFoundMessage (*TransactionNotFoundMessage)(nil), // 20: protowire.TransactionNotFoundMessage
(*InvRelayBlockMessage)(nil), // 21: protowire.InvRelayBlockMessage (*InvRelayBlockMessage)(nil), // 21: protowire.InvRelayBlockMessage
(*InvTransactionsMessage)(nil), // 22: protowire.InvTransactionsMessage (*InvTransactionsMessage)(nil), // 22: protowire.InvTransactionsMessage
(*PingMessage)(nil), // 23: protowire.PingMessage (*PingMessage)(nil), // 23: protowire.PingMessage
(*PongMessage)(nil), // 24: protowire.PongMessage (*PongMessage)(nil), // 24: protowire.PongMessage
(*VerackMessage)(nil), // 25: protowire.VerackMessage (*VerackMessage)(nil), // 25: protowire.VerackMessage
(*VersionMessage)(nil), // 26: protowire.VersionMessage (*VersionMessage)(nil), // 26: protowire.VersionMessage
(*RejectMessage)(nil), // 27: protowire.RejectMessage (*RejectMessage)(nil), // 27: protowire.RejectMessage
(*RequestIBDRootUTXOSetAndBlockMessage)(nil), // 28: protowire.RequestIBDRootUTXOSetAndBlockMessage (*RequestPruningPointUTXOSetAndBlockMessage)(nil), // 28: protowire.RequestPruningPointUTXOSetAndBlockMessage
(*IbdRootUtxoSetChunkMessage)(nil), // 29: protowire.IbdRootUtxoSetChunkMessage (*PruningPointUtxoSetChunkMessage)(nil), // 29: protowire.PruningPointUtxoSetChunkMessage
(*RequestNextIbdRootUtxoSetChunkMessage)(nil), // 30: protowire.RequestNextIbdRootUtxoSetChunkMessage (*OutpointAndUtxoEntryPair)(nil), // 30: protowire.OutpointAndUtxoEntryPair
(*DoneIbdRootUtxoSetChunksMessage)(nil), // 31: protowire.DoneIbdRootUtxoSetChunksMessage (*UtxoEntry)(nil), // 31: protowire.UtxoEntry
(*RequestIBDBlocksMessage)(nil), // 32: protowire.RequestIBDBlocksMessage (*RequestNextPruningPointUtxoSetChunkMessage)(nil), // 32: protowire.RequestNextPruningPointUtxoSetChunkMessage
(*IBDRootNotFoundMessage)(nil), // 33: protowire.IBDRootNotFoundMessage (*DonePruningPointUtxoSetChunksMessage)(nil), // 33: protowire.DonePruningPointUtxoSetChunksMessage
(*RequestIBDRootHashMessage)(nil), // 34: protowire.RequestIBDRootHashMessage (*RequestIBDBlocksMessage)(nil), // 34: protowire.RequestIBDBlocksMessage
(*IBDRootHashMessage)(nil), // 35: protowire.IBDRootHashMessage (*UnexpectedPruningPointMessage)(nil), // 35: protowire.UnexpectedPruningPointMessage
(*IbdBlockLocatorMessage)(nil), // 36: protowire.IbdBlockLocatorMessage (*RequestPruningPointHashMessage)(nil), // 36: protowire.RequestPruningPointHashMessage
(*IbdBlockLocatorHighestHashMessage)(nil), // 37: protowire.IbdBlockLocatorHighestHashMessage (*PruningPointHashMessage)(nil), // 37: protowire.PruningPointHashMessage
(*BlockHeadersMessage)(nil), // 38: protowire.BlockHeadersMessage (*IbdBlockLocatorMessage)(nil), // 38: protowire.IbdBlockLocatorMessage
(*IbdBlockLocatorHighestHashMessage)(nil), // 39: protowire.IbdBlockLocatorHighestHashMessage
(*BlockHeadersMessage)(nil), // 40: 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
@ -2400,18 +2556,22 @@ var file_p2p_proto_depIdxs = []int32{
7, // 24: protowire.InvTransactionsMessage.ids:type_name -> protowire.TransactionId 7, // 24: protowire.InvTransactionsMessage.ids:type_name -> protowire.TransactionId
2, // 25: protowire.VersionMessage.address:type_name -> protowire.NetAddress 2, // 25: protowire.VersionMessage.address:type_name -> protowire.NetAddress
3, // 26: protowire.VersionMessage.subnetworkId:type_name -> protowire.SubnetworkId 3, // 26: protowire.VersionMessage.subnetworkId:type_name -> protowire.SubnetworkId
12, // 27: protowire.RequestIBDRootUTXOSetAndBlockMessage.ibdRoot:type_name -> protowire.Hash 12, // 27: protowire.RequestPruningPointUTXOSetAndBlockMessage.pruningPointHash:type_name -> protowire.Hash
12, // 28: protowire.RequestIBDBlocksMessage.hashes:type_name -> protowire.Hash 30, // 28: protowire.PruningPointUtxoSetChunkMessage.outpointAndUtxoEntryPairs:type_name -> protowire.OutpointAndUtxoEntryPair
12, // 29: protowire.IBDRootHashMessage.hash:type_name -> protowire.Hash 6, // 29: protowire.OutpointAndUtxoEntryPair.outpoint:type_name -> protowire.Outpoint
12, // 30: protowire.IbdBlockLocatorMessage.targetHash:type_name -> protowire.Hash 31, // 30: protowire.OutpointAndUtxoEntryPair.utxoEntry:type_name -> protowire.UtxoEntry
12, // 31: protowire.IbdBlockLocatorMessage.blockLocatorHashes:type_name -> protowire.Hash 8, // 31: protowire.UtxoEntry.scriptPublicKey:type_name -> protowire.ScriptPublicKey
12, // 32: protowire.IbdBlockLocatorHighestHashMessage.highestHash:type_name -> protowire.Hash 12, // 32: protowire.RequestIBDBlocksMessage.hashes:type_name -> protowire.Hash
11, // 33: protowire.BlockHeadersMessage.blockHeaders:type_name -> protowire.BlockHeaderMessage 12, // 33: protowire.PruningPointHashMessage.hash:type_name -> protowire.Hash
34, // [34:34] is the sub-list for method output_type 12, // 34: protowire.IbdBlockLocatorMessage.targetHash:type_name -> protowire.Hash
34, // [34:34] is the sub-list for method input_type 12, // 35: protowire.IbdBlockLocatorMessage.blockLocatorHashes:type_name -> protowire.Hash
34, // [34:34] is the sub-list for extension type_name 12, // 36: protowire.IbdBlockLocatorHighestHashMessage.highestHash:type_name -> protowire.Hash
34, // [34:34] is the sub-list for extension extendee 11, // 37: protowire.BlockHeadersMessage.blockHeaders:type_name -> protowire.BlockHeaderMessage
0, // [0:34] is the sub-list for field type_name 38, // [38:38] is the sub-list for method output_type
38, // [38:38] is the sub-list for method input_type
38, // [38:38] is the sub-list for extension type_name
38, // [38:38] is the sub-list for extension extendee
0, // [0:38] is the sub-list for field type_name
} }
func init() { file_p2p_proto_init() } func init() { file_p2p_proto_init() }
@ -2757,7 +2917,7 @@ func file_p2p_proto_init() {
} }
} }
file_p2p_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { file_p2p_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RequestIBDRootUTXOSetAndBlockMessage); i { switch v := v.(*RequestPruningPointUTXOSetAndBlockMessage); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -2769,7 +2929,7 @@ func file_p2p_proto_init() {
} }
} }
file_p2p_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { file_p2p_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IbdRootUtxoSetChunkMessage); i { switch v := v.(*PruningPointUtxoSetChunkMessage); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -2781,7 +2941,7 @@ func file_p2p_proto_init() {
} }
} }
file_p2p_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { file_p2p_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RequestNextIbdRootUtxoSetChunkMessage); i { switch v := v.(*OutpointAndUtxoEntryPair); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -2793,7 +2953,7 @@ func file_p2p_proto_init() {
} }
} }
file_p2p_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { file_p2p_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DoneIbdRootUtxoSetChunksMessage); i { switch v := v.(*UtxoEntry); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -2805,7 +2965,7 @@ func file_p2p_proto_init() {
} }
} }
file_p2p_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { file_p2p_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RequestIBDBlocksMessage); i { switch v := v.(*RequestNextPruningPointUtxoSetChunkMessage); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -2817,7 +2977,7 @@ func file_p2p_proto_init() {
} }
} }
file_p2p_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { file_p2p_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IBDRootNotFoundMessage); i { switch v := v.(*DonePruningPointUtxoSetChunksMessage); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -2829,7 +2989,7 @@ func file_p2p_proto_init() {
} }
} }
file_p2p_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { file_p2p_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RequestIBDRootHashMessage); i { switch v := v.(*RequestIBDBlocksMessage); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -2841,7 +3001,7 @@ func file_p2p_proto_init() {
} }
} }
file_p2p_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { file_p2p_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IBDRootHashMessage); i { switch v := v.(*UnexpectedPruningPointMessage); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -2853,7 +3013,7 @@ func file_p2p_proto_init() {
} }
} }
file_p2p_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { file_p2p_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IbdBlockLocatorMessage); i { switch v := v.(*RequestPruningPointHashMessage); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -2865,7 +3025,7 @@ func file_p2p_proto_init() {
} }
} }
file_p2p_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { file_p2p_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IbdBlockLocatorHighestHashMessage); i { switch v := v.(*PruningPointHashMessage); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:
@ -2877,6 +3037,30 @@ func file_p2p_proto_init() {
} }
} }
file_p2p_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { file_p2p_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IbdBlockLocatorMessage); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_p2p_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IbdBlockLocatorHighestHashMessage); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_p2p_proto_msgTypes[40].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
@ -2895,7 +3079,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: 39, NumMessages: 41,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },

View File

@ -146,31 +146,43 @@ message RejectMessage{
string reason = 1; string reason = 1;
} }
message RequestIBDRootUTXOSetAndBlockMessage{ message RequestPruningPointUTXOSetAndBlockMessage{
Hash ibdRoot = 1; Hash pruningPointHash = 1;
} }
message IbdRootUtxoSetChunkMessage{ message PruningPointUtxoSetChunkMessage{
bytes chunk = 1; repeated OutpointAndUtxoEntryPair outpointAndUtxoEntryPairs = 1;
} }
message RequestNextIbdRootUtxoSetChunkMessage { message OutpointAndUtxoEntryPair{
Outpoint outpoint = 1;
UtxoEntry utxoEntry = 2;
} }
message DoneIbdRootUtxoSetChunksMessage { message UtxoEntry {
uint64 amount = 1;
ScriptPublicKey scriptPublicKey = 2;
uint64 blockBlueScore = 3;
bool isCoinbase = 4;
}
message RequestNextPruningPointUtxoSetChunkMessage {
}
message DonePruningPointUtxoSetChunksMessage {
} }
message RequestIBDBlocksMessage{ message RequestIBDBlocksMessage{
repeated Hash hashes = 1; repeated Hash hashes = 1;
} }
message IBDRootNotFoundMessage{ message UnexpectedPruningPointMessage{
} }
message RequestIBDRootHashMessage{ message RequestPruningPointHashMessage{
} }
message IBDRootHashMessage{ message PruningPointHashMessage{
Hash hash = 1; Hash hash = 1;
} }

View File

@ -1,12 +0,0 @@
package protowire
import "github.com/kaspanet/kaspad/app/appmessage"
func (x *KaspadMessage_DoneIbdRootUtxoSetChunks) toAppMessage() (appmessage.Message, error) {
return &appmessage.MsgDoneIBDRootUTXOSetChunks{}, nil
}
func (x *KaspadMessage_DoneIbdRootUtxoSetChunks) fromAppMessage(_ *appmessage.MsgDoneIBDRootUTXOSetChunks) error {
x.DoneIbdRootUtxoSetChunks = &DoneIbdRootUtxoSetChunksMessage{}
return nil
}

View File

@ -0,0 +1,12 @@
package protowire
import "github.com/kaspanet/kaspad/app/appmessage"
func (x *KaspadMessage_DonePruningPointUtxoSetChunks) toAppMessage() (appmessage.Message, error) {
return &appmessage.MsgDonePruningPointUTXOSetChunks{}, nil
}
func (x *KaspadMessage_DonePruningPointUtxoSetChunks) fromAppMessage(_ *appmessage.MsgDonePruningPointUTXOSetChunks) error {
x.DonePruningPointUtxoSetChunks = &DonePruningPointUtxoSetChunksMessage{}
return nil
}

View File

@ -1,19 +0,0 @@
package protowire
import "github.com/kaspanet/kaspad/app/appmessage"
func (x *KaspadMessage_IbdRootHash) toAppMessage() (appmessage.Message, error) {
hash, err := x.IbdRootHash.Hash.toDomain()
if err != nil {
return nil, err
}
return &appmessage.MsgIBDRootHashMessage{Hash: hash}, nil
}
func (x *KaspadMessage_IbdRootHash) fromAppMessage(msgIBDRootHash *appmessage.MsgIBDRootHashMessage) error {
x.IbdRootHash = &IBDRootHashMessage{
Hash: domainHashToProto(msgIBDRootHash.Hash),
}
return nil
}

View File

@ -1,11 +0,0 @@
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
}

View File

@ -1,16 +0,0 @@
package protowire
import "github.com/kaspanet/kaspad/app/appmessage"
func (x *KaspadMessage_IbdRootUtxoSetChunk) toAppMessage() (appmessage.Message, error) {
return &appmessage.MsgIBDRootUTXOSetChunk{
Chunk: x.IbdRootUtxoSetChunk.Chunk,
}, nil
}
func (x *KaspadMessage_IbdRootUtxoSetChunk) fromAppMessage(message *appmessage.MsgIBDRootUTXOSetChunk) error {
x.IbdRootUtxoSetChunk = &IbdRootUtxoSetChunkMessage{
Chunk: message.Chunk,
}
return nil
}

View File

@ -0,0 +1,19 @@
package protowire
import "github.com/kaspanet/kaspad/app/appmessage"
func (x *KaspadMessage_PruningPointHash) toAppMessage() (appmessage.Message, error) {
hash, err := x.PruningPointHash.Hash.toDomain()
if err != nil {
return nil, err
}
return &appmessage.MsgPruningPointHashMessage{Hash: hash}, nil
}
func (x *KaspadMessage_PruningPointHash) fromAppMessage(msgPruningPointHash *appmessage.MsgPruningPointHashMessage) error {
x.PruningPointHash = &PruningPointHashMessage{
Hash: domainHashToProto(msgPruningPointHash.Hash),
}
return nil
}

View File

@ -0,0 +1,71 @@
package protowire
import (
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/pkg/errors"
"math"
)
func (x *KaspadMessage_PruningPointUtxoSetChunk) toAppMessage() (appmessage.Message, error) {
outpointAndUTXOEntryPairs := make([]*appmessage.OutpointAndUTXOEntryPair, len(x.PruningPointUtxoSetChunk.OutpointAndUtxoEntryPairs))
for i, outpointAndUTXOEntryPair := range x.PruningPointUtxoSetChunk.OutpointAndUtxoEntryPairs {
transactionID, err := outpointAndUTXOEntryPair.Outpoint.TransactionId.toDomain()
if err != nil {
return nil, err
}
outpoint := &appmessage.Outpoint{
TxID: *transactionID,
Index: outpointAndUTXOEntryPair.Outpoint.Index,
}
if outpointAndUTXOEntryPair.UtxoEntry.ScriptPublicKey.Version > math.MaxUint16 {
return nil, errors.Errorf("ScriptPublicKey version is bigger then uint16.")
}
scriptPublicKey := &externalapi.ScriptPublicKey{
Script: outpointAndUTXOEntryPair.UtxoEntry.ScriptPublicKey.Script,
Version: uint16(outpointAndUTXOEntryPair.UtxoEntry.ScriptPublicKey.Version),
}
utxoEntry := &appmessage.UTXOEntry{
Amount: outpointAndUTXOEntryPair.UtxoEntry.Amount,
ScriptPublicKey: scriptPublicKey,
BlockBlueScore: outpointAndUTXOEntryPair.UtxoEntry.BlockBlueScore,
IsCoinbase: outpointAndUTXOEntryPair.UtxoEntry.IsCoinbase,
}
outpointAndUTXOEntryPairs[i] = &appmessage.OutpointAndUTXOEntryPair{
Outpoint: outpoint,
UTXOEntry: utxoEntry,
}
}
return &appmessage.MsgPruningPointUTXOSetChunk{
OutpointAndUTXOEntryPairs: outpointAndUTXOEntryPairs,
}, nil
}
func (x *KaspadMessage_PruningPointUtxoSetChunk) fromAppMessage(message *appmessage.MsgPruningPointUTXOSetChunk) error {
outpointAndUTXOEntryPairs := make([]*OutpointAndUtxoEntryPair, len(message.OutpointAndUTXOEntryPairs))
for i, outpointAndUTXOEntryPair := range message.OutpointAndUTXOEntryPairs {
transactionID := domainTransactionIDToProto(&outpointAndUTXOEntryPair.Outpoint.TxID)
outpoint := &Outpoint{
TransactionId: transactionID,
Index: outpointAndUTXOEntryPair.Outpoint.Index,
}
scriptPublicKey := &ScriptPublicKey{
Script: outpointAndUTXOEntryPair.UTXOEntry.ScriptPublicKey.Script,
Version: uint32(outpointAndUTXOEntryPair.UTXOEntry.ScriptPublicKey.Version),
}
utxoEntry := &UtxoEntry{
Amount: outpointAndUTXOEntryPair.UTXOEntry.Amount,
ScriptPublicKey: scriptPublicKey,
BlockBlueScore: outpointAndUTXOEntryPair.UTXOEntry.BlockBlueScore,
IsCoinbase: outpointAndUTXOEntryPair.UTXOEntry.IsCoinbase,
}
outpointAndUTXOEntryPairs[i] = &OutpointAndUtxoEntryPair{
Outpoint: outpoint,
UtxoEntry: utxoEntry,
}
}
x.PruningPointUtxoSetChunk = &PruningPointUtxoSetChunkMessage{
OutpointAndUtxoEntryPairs: outpointAndUTXOEntryPairs,
}
return nil
}

View File

@ -1,11 +0,0 @@
package protowire
import "github.com/kaspanet/kaspad/app/appmessage"
func (x *KaspadMessage_RequestIBDRootHash) toAppMessage() (appmessage.Message, error) {
return &appmessage.MsgRequestIBDRootHashMessage{}, nil
}
func (x *KaspadMessage_RequestIBDRootHash) fromAppMessage(_ *appmessage.MsgRequestIBDRootHashMessage) error {
return nil
}

View File

@ -1,20 +0,0 @@
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 = &RequestIBDRootUTXOSetAndBlockMessage{}
x.RequestIBDRootUTXOSetAndBlock.IbdRoot = domainHashToProto(msgRequestIBDRootUTXOSetAndBlock.IBDRoot)
return nil
}

View File

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

View File

@ -0,0 +1,12 @@
package protowire
import "github.com/kaspanet/kaspad/app/appmessage"
func (x *KaspadMessage_RequestNextPruningPointUtxoSetChunk) toAppMessage() (appmessage.Message, error) {
return &appmessage.MsgRequestNextPruningPointUTXOSetChunk{}, nil
}
func (x *KaspadMessage_RequestNextPruningPointUtxoSetChunk) fromAppMessage(_ *appmessage.MsgRequestNextPruningPointUTXOSetChunk) error {
x.RequestNextPruningPointUtxoSetChunk = &RequestNextPruningPointUtxoSetChunkMessage{}
return nil
}

View File

@ -0,0 +1,11 @@
package protowire
import "github.com/kaspanet/kaspad/app/appmessage"
func (x *KaspadMessage_RequestPruningPointHash) toAppMessage() (appmessage.Message, error) {
return &appmessage.MsgRequestPruningPointHashMessage{}, nil
}
func (x *KaspadMessage_RequestPruningPointHash) fromAppMessage(_ *appmessage.MsgRequestPruningPointHashMessage) error {
return nil
}

View File

@ -0,0 +1,19 @@
package protowire
import "github.com/kaspanet/kaspad/app/appmessage"
func (x *KaspadMessage_RequestPruningPointUTXOSetAndBlock) toAppMessage() (appmessage.Message, error) {
pruningPointHash, err := x.RequestPruningPointUTXOSetAndBlock.PruningPointHash.toDomain()
if err != nil {
return nil, err
}
return &appmessage.MsgRequestPruningPointUTXOSetAndBlock{PruningPointHash: pruningPointHash}, nil
}
func (x *KaspadMessage_RequestPruningPointUTXOSetAndBlock) fromAppMessage(
msgRequestPruningPointUTXOSetAndBlock *appmessage.MsgRequestPruningPointUTXOSetAndBlock) error {
x.RequestPruningPointUTXOSetAndBlock = &RequestPruningPointUTXOSetAndBlockMessage{}
x.RequestPruningPointUTXOSetAndBlock.PruningPointHash = domainHashToProto(msgRequestPruningPointUTXOSetAndBlock.PruningPointHash)
return nil
}

View File

@ -0,0 +1,11 @@
package protowire
import "github.com/kaspanet/kaspad/app/appmessage"
func (x *KaspadMessage_UnexpectedPruningPoint) toAppMessage() (appmessage.Message, error) {
return &appmessage.MsgUnexpectedPruningPoint{}, nil
}
func (x *KaspadMessage_UnexpectedPruningPoint) fromAppMessage(_ *appmessage.MsgUnexpectedPruningPoint) error {
return nil
}

View File

@ -195,15 +195,15 @@ func toP2PPayload(message appmessage.Message) (isKaspadMessage_Payload, error) {
return nil, err return nil, err
} }
return payload, nil return payload, nil
case *appmessage.MsgRequestIBDRootUTXOSetAndBlock: case *appmessage.MsgRequestPruningPointUTXOSetAndBlock:
payload := new(KaspadMessage_RequestIBDRootUTXOSetAndBlock) payload := new(KaspadMessage_RequestPruningPointUTXOSetAndBlock)
err := payload.fromAppMessage(message) err := payload.fromAppMessage(message)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return payload, nil return payload, nil
case *appmessage.MsgIBDRootUTXOSetChunk: case *appmessage.MsgPruningPointUTXOSetChunk:
payload := new(KaspadMessage_IbdRootUtxoSetChunk) payload := new(KaspadMessage_PruningPointUtxoSetChunk)
err := payload.fromAppMessage(message) err := payload.fromAppMessage(message)
if err != nil { if err != nil {
return nil, err return nil, err
@ -216,22 +216,22 @@ func toP2PPayload(message appmessage.Message) (isKaspadMessage_Payload, error) {
return nil, err return nil, err
} }
return payload, nil return payload, nil
case *appmessage.MsgIBDRootNotFound: case *appmessage.MsgUnexpectedPruningPoint:
payload := new(KaspadMessage_IbdRootNotFound) payload := new(KaspadMessage_UnexpectedPruningPoint)
err := payload.fromAppMessage(message) err := payload.fromAppMessage(message)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return payload, nil return payload, nil
case *appmessage.MsgRequestIBDRootHashMessage: case *appmessage.MsgRequestPruningPointHashMessage:
payload := new(KaspadMessage_RequestIBDRootHash) payload := new(KaspadMessage_RequestPruningPointHash)
err := payload.fromAppMessage(message) err := payload.fromAppMessage(message)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return payload, nil return payload, nil
case *appmessage.MsgIBDRootHashMessage: case *appmessage.MsgPruningPointHashMessage:
payload := new(KaspadMessage_IbdRootHash) payload := new(KaspadMessage_PruningPointHash)
err := payload.fromAppMessage(message) err := payload.fromAppMessage(message)
if err != nil { if err != nil {
return nil, err return nil, err
@ -258,15 +258,15 @@ func toP2PPayload(message appmessage.Message) (isKaspadMessage_Payload, error) {
return nil, err return nil, err
} }
return payload, nil return payload, nil
case *appmessage.MsgRequestNextIBDRootUTXOSetChunk: case *appmessage.MsgRequestNextPruningPointUTXOSetChunk:
payload := new(KaspadMessage_RequestNextIbdRootUtxoSetChunk) payload := new(KaspadMessage_RequestNextPruningPointUtxoSetChunk)
err := payload.fromAppMessage(message) err := payload.fromAppMessage(message)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return payload, nil return payload, nil
case *appmessage.MsgDoneIBDRootUTXOSetChunks: case *appmessage.MsgDonePruningPointUTXOSetChunks:
payload := new(KaspadMessage_DoneIbdRootUtxoSetChunks) payload := new(KaspadMessage_DonePruningPointUtxoSetChunks)
err := payload.fromAppMessage(message) err := payload.fromAppMessage(message)
if err != nil { if err != nil {
return nil, err return nil, err