mirror of
https://github.com/kaspanet/kaspad.git
synced 2026-02-23 11:58:22 +00:00
Compare commits
2 Commits
v0.8.10-de
...
v0.8.9-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b8eda2226 | ||
|
|
15785da628 |
1
.github/workflows/go-race.yml
vendored
1
.github/workflows/go-race.yml
vendored
@@ -9,7 +9,6 @@ jobs:
|
||||
race_test:
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
branch: [ master, latest ]
|
||||
name: Race detection on ${{ matrix.branch }}
|
||||
|
||||
9
.github/workflows/go.yml
vendored
9
.github/workflows/go.yml
vendored
@@ -11,7 +11,6 @@ jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-16.04, macos-10.15 ]
|
||||
name: Testing on on ${{ matrix.os }}
|
||||
@@ -35,7 +34,7 @@ jobs:
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
go-version: 1.15
|
||||
|
||||
|
||||
# Source: https://github.com/actions/cache/blob/main/examples.md#go---modules
|
||||
@@ -49,7 +48,7 @@ jobs:
|
||||
|
||||
- name: Test
|
||||
shell: bash
|
||||
run: ./build_and_test.sh -v
|
||||
run: ./build_and_test.sh
|
||||
|
||||
coverage:
|
||||
runs-on: ubuntu-20.04
|
||||
@@ -61,10 +60,10 @@ jobs:
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
go-version: 1.15
|
||||
|
||||
- name: Create coverage file
|
||||
run: go test -v -covermode=atomic -coverpkg=./... -coverprofile coverage.txt ./...
|
||||
run: go test -covermode=atomic -coverpkg=./... -coverprofile coverage.txt ./...
|
||||
|
||||
- name: Upload coverage file
|
||||
run: bash <(curl -s https://codecov.io/bash)
|
||||
@@ -18,7 +18,7 @@ Kaspa is an attempt at a proof-of-work cryptocurrency with instant confirmations
|
||||
|
||||
## Requirements
|
||||
|
||||
Go 1.16 or later.
|
||||
Go 1.15 or later.
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
@@ -132,11 +132,6 @@ const (
|
||||
CmdUnbanResponseMessage
|
||||
CmdGetInfoRequestMessage
|
||||
CmdGetInfoResponseMessage
|
||||
CmdNotifyPruningPointUTXOSetOverrideRequestMessage
|
||||
CmdNotifyPruningPointUTXOSetOverrideResponseMessage
|
||||
CmdPruningPointUTXOSetOverrideNotificationMessage
|
||||
CmdStopNotifyingPruningPointUTXOSetOverrideRequestMessage
|
||||
CmdStopNotifyingPruningPointUTXOSetOverrideResponseMessage
|
||||
)
|
||||
|
||||
// ProtocolMessageCommandToString maps all MessageCommands to their string representation
|
||||
@@ -241,13 +236,8 @@ var RPCMessageCommandToString = map[MessageCommand]string{
|
||||
CmdBanResponseMessage: "BanResponse",
|
||||
CmdUnbanRequestMessage: "UnbanRequest",
|
||||
CmdUnbanResponseMessage: "UnbanResponse",
|
||||
CmdGetInfoRequestMessage: "GetInfoRequest",
|
||||
CmdGetInfoResponseMessage: "GeInfoResponse",
|
||||
CmdNotifyPruningPointUTXOSetOverrideRequestMessage: "NotifyPruningPointUTXOSetOverrideRequest",
|
||||
CmdNotifyPruningPointUTXOSetOverrideResponseMessage: "NotifyPruningPointUTXOSetOverrideResponse",
|
||||
CmdPruningPointUTXOSetOverrideNotificationMessage: "PruningPointUTXOSetOverrideNotification",
|
||||
CmdStopNotifyingPruningPointUTXOSetOverrideRequestMessage: "StopNotifyingPruningPointUTXOSetOverrideRequest",
|
||||
CmdStopNotifyingPruningPointUTXOSetOverrideResponseMessage: "StopNotifyingPruningPointUTXOSetOverrideResponse",
|
||||
CmdGetInfoRequestMessage: "GetInfoRequestMessage",
|
||||
CmdGetInfoResponseMessage: "GeInfoResponseMessage",
|
||||
}
|
||||
|
||||
// Message is an interface that describes a kaspa message. A type that
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
package appmessage
|
||||
|
||||
// NotifyPruningPointUTXOSetOverrideRequestMessage is an appmessage corresponding to
|
||||
// its respective RPC message
|
||||
type NotifyPruningPointUTXOSetOverrideRequestMessage struct {
|
||||
baseMessage
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message
|
||||
func (msg *NotifyPruningPointUTXOSetOverrideRequestMessage) Command() MessageCommand {
|
||||
return CmdNotifyPruningPointUTXOSetOverrideRequestMessage
|
||||
}
|
||||
|
||||
// NewNotifyPruningPointUTXOSetOverrideRequestMessage returns a instance of the message
|
||||
func NewNotifyPruningPointUTXOSetOverrideRequestMessage() *NotifyPruningPointUTXOSetOverrideRequestMessage {
|
||||
return &NotifyPruningPointUTXOSetOverrideRequestMessage{}
|
||||
}
|
||||
|
||||
// NotifyPruningPointUTXOSetOverrideResponseMessage is an appmessage corresponding to
|
||||
// its respective RPC message
|
||||
type NotifyPruningPointUTXOSetOverrideResponseMessage struct {
|
||||
baseMessage
|
||||
Error *RPCError
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message
|
||||
func (msg *NotifyPruningPointUTXOSetOverrideResponseMessage) Command() MessageCommand {
|
||||
return CmdNotifyPruningPointUTXOSetOverrideResponseMessage
|
||||
}
|
||||
|
||||
// NewNotifyPruningPointUTXOSetOverrideResponseMessage returns a instance of the message
|
||||
func NewNotifyPruningPointUTXOSetOverrideResponseMessage() *NotifyPruningPointUTXOSetOverrideResponseMessage {
|
||||
return &NotifyPruningPointUTXOSetOverrideResponseMessage{}
|
||||
}
|
||||
|
||||
// PruningPointUTXOSetOverrideNotificationMessage is an appmessage corresponding to
|
||||
// its respective RPC message
|
||||
type PruningPointUTXOSetOverrideNotificationMessage struct {
|
||||
baseMessage
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message
|
||||
func (msg *PruningPointUTXOSetOverrideNotificationMessage) Command() MessageCommand {
|
||||
return CmdPruningPointUTXOSetOverrideNotificationMessage
|
||||
}
|
||||
|
||||
// NewPruningPointUTXOSetOverrideNotificationMessage returns a instance of the message
|
||||
func NewPruningPointUTXOSetOverrideNotificationMessage() *PruningPointUTXOSetOverrideNotificationMessage {
|
||||
return &PruningPointUTXOSetOverrideNotificationMessage{}
|
||||
}
|
||||
|
||||
// StopNotifyingPruningPointUTXOSetOverrideRequestMessage is an appmessage corresponding to
|
||||
// its respective RPC message
|
||||
type StopNotifyingPruningPointUTXOSetOverrideRequestMessage struct {
|
||||
baseMessage
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message
|
||||
func (msg *StopNotifyingPruningPointUTXOSetOverrideRequestMessage) Command() MessageCommand {
|
||||
return CmdNotifyPruningPointUTXOSetOverrideRequestMessage
|
||||
}
|
||||
|
||||
// NewStopNotifyingPruningPointUTXOSetOverrideRequestMessage returns a instance of the message
|
||||
func NewStopNotifyingPruningPointUTXOSetOverrideRequestMessage() *StopNotifyingPruningPointUTXOSetOverrideRequestMessage {
|
||||
return &StopNotifyingPruningPointUTXOSetOverrideRequestMessage{}
|
||||
}
|
||||
|
||||
// StopNotifyingPruningPointUTXOSetOverrideResponseMessage is an appmessage corresponding to
|
||||
// its respective RPC message
|
||||
type StopNotifyingPruningPointUTXOSetOverrideResponseMessage struct {
|
||||
baseMessage
|
||||
Error *RPCError
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message
|
||||
func (msg *StopNotifyingPruningPointUTXOSetOverrideResponseMessage) Command() MessageCommand {
|
||||
return CmdNotifyPruningPointUTXOSetOverrideResponseMessage
|
||||
}
|
||||
|
||||
// NewStopNotifyingPruningPointUTXOSetOverrideResponseMessage returns a instance of the message
|
||||
func NewStopNotifyingPruningPointUTXOSetOverrideResponseMessage() *StopNotifyingPruningPointUTXOSetOverrideResponseMessage {
|
||||
return &StopNotifyingPruningPointUTXOSetOverrideResponseMessage{}
|
||||
}
|
||||
@@ -97,11 +97,7 @@ func NewComponentManager(cfg *config.Config, db infrastructuredatabase.Database,
|
||||
|
||||
var utxoIndex *utxoindex.UTXOIndex
|
||||
if cfg.UTXOIndex {
|
||||
utxoIndex, err = utxoindex.New(domain.Consensus(), db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
utxoIndex = utxoindex.New(domain.Consensus(), db)
|
||||
log.Infof("UTXO index started")
|
||||
}
|
||||
|
||||
@@ -148,7 +144,6 @@ func setupRPC(
|
||||
shutDownChan,
|
||||
)
|
||||
protocolManager.SetOnBlockAddedToDAGHandler(rpcManager.NotifyBlockAddedToDAG)
|
||||
protocolManager.SetOnPruningPointUTXOSetOverrideHandler(rpcManager.NotifyPruningPointUTXOSetOverride)
|
||||
|
||||
return rpcManager
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package flowcontext
|
||||
|
||||
import (
|
||||
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
|
||||
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
@@ -57,15 +56,6 @@ func (f *FlowContext) OnNewBlock(block *externalapi.DomainBlock,
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnPruningPointUTXOSetOverride calls the handler function whenever the UTXO set
|
||||
// resets due to pruning point change via IBD.
|
||||
func (f *FlowContext) OnPruningPointUTXOSetOverride() error {
|
||||
if f.onPruningPointUTXOSetOverrideHandler != nil {
|
||||
return f.onPruningPointUTXOSetOverrideHandler()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FlowContext) broadcastTransactionsAfterBlockAdded(
|
||||
block *externalapi.DomainBlock, transactionsAcceptedToMempool []*externalapi.DomainTransaction) error {
|
||||
|
||||
@@ -108,10 +98,6 @@ func (f *FlowContext) SharedRequestedBlocks() *blockrelay.SharedRequestedBlocks
|
||||
|
||||
// AddBlock adds the given block to the DAG and propagates it.
|
||||
func (f *FlowContext) AddBlock(block *externalapi.DomainBlock) error {
|
||||
if len(block.Transactions) == 0 {
|
||||
return protocolerrors.Errorf(false, "cannot add header only block")
|
||||
}
|
||||
|
||||
blockInsertionResult, err := f.Domain().Consensus().ValidateAndInsertBlock(block)
|
||||
if err != nil {
|
||||
if errors.As(err, &ruleerrors.RuleError{}) {
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
func (*FlowContext) HandleError(err error, flowName string, isStopping *uint32, errChan chan<- error) {
|
||||
isErrRouteClosed := errors.Is(err, router.ErrRouteClosed)
|
||||
if !isErrRouteClosed {
|
||||
if protocolErr := (protocolerrors.ProtocolError{}); !errors.As(err, &protocolErr) {
|
||||
if protocolErr := &(protocolerrors.ProtocolError{}); !errors.As(err, &protocolErr) {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,6 @@ import (
|
||||
// when a block is added to the DAG
|
||||
type OnBlockAddedToDAGHandler func(block *externalapi.DomainBlock, blockInsertionResult *externalapi.BlockInsertionResult) error
|
||||
|
||||
// OnPruningPointUTXOSetOverrideHandler is a handle function that's triggered whenever the UTXO set
|
||||
// resets due to pruning point change via IBD.
|
||||
type OnPruningPointUTXOSetOverrideHandler func() error
|
||||
|
||||
// OnTransactionAddedToMempoolHandler is a handler function that's triggered
|
||||
// when a transaction is added to the mempool
|
||||
type OnTransactionAddedToMempoolHandler func()
|
||||
@@ -42,9 +38,8 @@ type FlowContext struct {
|
||||
|
||||
timeStarted int64
|
||||
|
||||
onBlockAddedToDAGHandler OnBlockAddedToDAGHandler
|
||||
onPruningPointUTXOSetOverrideHandler OnPruningPointUTXOSetOverrideHandler
|
||||
onTransactionAddedToMempoolHandler OnTransactionAddedToMempoolHandler
|
||||
onBlockAddedToDAGHandler OnBlockAddedToDAGHandler
|
||||
onTransactionAddedToMempoolHandler OnTransactionAddedToMempoolHandler
|
||||
|
||||
transactionsToRebroadcastLock sync.Mutex
|
||||
transactionsToRebroadcast map[externalapi.DomainTransactionID]*externalapi.DomainTransaction
|
||||
@@ -87,11 +82,6 @@ func (f *FlowContext) SetOnBlockAddedToDAGHandler(onBlockAddedToDAGHandler OnBlo
|
||||
f.onBlockAddedToDAGHandler = onBlockAddedToDAGHandler
|
||||
}
|
||||
|
||||
// SetOnPruningPointUTXOSetOverrideHandler sets the onPruningPointUTXOSetOverrideHandler handler
|
||||
func (f *FlowContext) SetOnPruningPointUTXOSetOverrideHandler(onPruningPointUTXOSetOverrideHandler OnPruningPointUTXOSetOverrideHandler) {
|
||||
f.onPruningPointUTXOSetOverrideHandler = onPruningPointUTXOSetOverrideHandler
|
||||
}
|
||||
|
||||
// SetOnTransactionAddedToMempoolHandler sets the onTransactionAddedToMempool handler
|
||||
func (f *FlowContext) SetOnTransactionAddedToMempoolHandler(onTransactionAddedToMempoolHandler OnTransactionAddedToMempoolHandler) {
|
||||
f.onTransactionAddedToMempoolHandler = onTransactionAddedToMempoolHandler
|
||||
|
||||
@@ -24,7 +24,6 @@ type RelayInvsContext interface {
|
||||
Domain() domain.Domain
|
||||
Config() *config.Config
|
||||
OnNewBlock(block *externalapi.DomainBlock, blockInsertionResult *externalapi.BlockInsertionResult) error
|
||||
OnPruningPointUTXOSetOverride() error
|
||||
SharedRequestedBlocks() *SharedRequestedBlocks
|
||||
Broadcast(message appmessage.Message) error
|
||||
AddOrphan(orphanBlock *externalapi.DomainBlock)
|
||||
@@ -105,11 +104,6 @@ func (flow *handleRelayInvsFlow) start() error {
|
||||
continue
|
||||
}
|
||||
|
||||
err = flow.banIfBlockIsHeaderOnly(block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("Processing block %s", inv.Hash)
|
||||
missingParents, blockInsertionResult, err := flow.processBlock(block)
|
||||
if err != nil {
|
||||
@@ -146,15 +140,6 @@ func (flow *handleRelayInvsFlow) start() error {
|
||||
}
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) banIfBlockIsHeaderOnly(block *externalapi.DomainBlock) error {
|
||||
if len(block.Transactions) == 0 {
|
||||
return protocolerrors.Errorf(true, "sent header of %s block where expected block with body",
|
||||
consensushashing.BlockHash(block))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) readInv() (*appmessage.MsgInvRelayBlock, error) {
|
||||
if len(flow.invsQueue) > 0 {
|
||||
var inv *appmessage.MsgInvRelayBlock
|
||||
|
||||
@@ -410,11 +410,6 @@ func (flow *handleRelayInvsFlow) fetchMissingUTXOSet(pruningPointHash *externala
|
||||
return false, protocolerrors.ConvertToBanningProtocolErrorIfRuleError(err, "error with pruning point UTXO set")
|
||||
}
|
||||
|
||||
err = flow.OnPruningPointUTXOSetOverride()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -538,11 +533,6 @@ func (flow *handleRelayInvsFlow) syncMissingBlockBodies(highHash *externalapi.Do
|
||||
return protocolerrors.Errorf(true, "expected block %s but got %s", expectedHash, blockHash)
|
||||
}
|
||||
|
||||
err = flow.banIfBlockIsHeaderOnly(block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
blockInsertionResult, err := flow.Domain().Consensus().ValidateAndInsertBlock(block)
|
||||
if err != nil {
|
||||
if errors.Is(err, ruleerrors.ErrDuplicateBlock) {
|
||||
|
||||
@@ -107,7 +107,7 @@ func handleError(err error, flowName string, isStopping *uint32, errChan chan er
|
||||
return
|
||||
}
|
||||
|
||||
if protocolErr := (protocolerrors.ProtocolError{}); errors.As(err, &protocolErr) {
|
||||
if protocolErr := &(protocolerrors.ProtocolError{}); errors.As(err, &protocolErr) {
|
||||
log.Errorf("Handshake protocol error from %s: %s", flowName, err)
|
||||
if atomic.AddUint32(isStopping, 1) == 1 {
|
||||
errChan <- err
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
|
||||
"github.com/pkg/errors"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func checkFlowError(t *testing.T, err error, isProtocolError bool, shouldBan bool, contains string) {
|
||||
pErr := protocolerrors.ProtocolError{}
|
||||
pErr := &protocolerrors.ProtocolError{}
|
||||
if errors.As(err, &pErr) != isProtocolError {
|
||||
t.Fatalf("Unexepcted error %+v", err)
|
||||
}
|
||||
|
||||
@@ -24,19 +24,6 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var headerOnlyBlock = &externalapi.DomainBlock{
|
||||
Header: blockheader.NewImmutableBlockHeader(
|
||||
constants.MaxBlockVersion,
|
||||
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
|
||||
&externalapi.DomainHash{},
|
||||
&externalapi.DomainHash{},
|
||||
&externalapi.DomainHash{},
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
),
|
||||
}
|
||||
|
||||
var orphanBlock = &externalapi.DomainBlock{
|
||||
Header: blockheader.NewImmutableBlockHeader(
|
||||
constants.MaxBlockVersion,
|
||||
@@ -48,7 +35,6 @@ var orphanBlock = &externalapi.DomainBlock{
|
||||
0,
|
||||
0,
|
||||
),
|
||||
Transactions: []*externalapi.DomainTransaction{{}},
|
||||
}
|
||||
|
||||
var validPruningPointBlock = &externalapi.DomainBlock{
|
||||
@@ -62,7 +48,6 @@ var validPruningPointBlock = &externalapi.DomainBlock{
|
||||
0,
|
||||
0,
|
||||
),
|
||||
Transactions: []*externalapi.DomainTransaction{{}},
|
||||
}
|
||||
|
||||
var invalidPruningPointBlock = &externalapi.DomainBlock{
|
||||
@@ -76,7 +61,6 @@ var invalidPruningPointBlock = &externalapi.DomainBlock{
|
||||
0,
|
||||
0,
|
||||
),
|
||||
Transactions: []*externalapi.DomainTransaction{{}},
|
||||
}
|
||||
|
||||
var unexpectedIBDBlock = &externalapi.DomainBlock{
|
||||
@@ -90,7 +74,6 @@ var unexpectedIBDBlock = &externalapi.DomainBlock{
|
||||
0,
|
||||
0,
|
||||
),
|
||||
Transactions: []*externalapi.DomainTransaction{{}},
|
||||
}
|
||||
|
||||
var invalidBlock = &externalapi.DomainBlock{
|
||||
@@ -104,7 +87,6 @@ var invalidBlock = &externalapi.DomainBlock{
|
||||
0,
|
||||
0,
|
||||
),
|
||||
Transactions: []*externalapi.DomainTransaction{{}},
|
||||
}
|
||||
|
||||
var unknownBlockHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})
|
||||
@@ -113,7 +95,6 @@ var validPruningPointHash = consensushashing.BlockHash(validPruningPointBlock)
|
||||
var invalidBlockHash = consensushashing.BlockHash(invalidBlock)
|
||||
var invalidPruningPointHash = consensushashing.BlockHash(invalidPruningPointBlock)
|
||||
var orphanBlockHash = consensushashing.BlockHash(orphanBlock)
|
||||
var headerOnlyBlockHash = consensushashing.BlockHash(headerOnlyBlock)
|
||||
|
||||
type fakeRelayInvsContext struct {
|
||||
testName string
|
||||
@@ -129,14 +110,6 @@ type fakeRelayInvsContext struct {
|
||||
rwLock sync.RWMutex
|
||||
}
|
||||
|
||||
func (f *fakeRelayInvsContext) OnPruningPointUTXOSetOverride() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeRelayInvsContext) GetVirtualUTXOs(expectedVirtualParents []*externalapi.DomainHash, fromOutpoint *externalapi.DomainOutpoint, limit int) ([]*externalapi.OutpointAndUTXOEntryPair, error) {
|
||||
panic(errors.Errorf("called unimplemented function from test '%s'", f.testName))
|
||||
}
|
||||
|
||||
func (f *fakeRelayInvsContext) Anticone(blockHash *externalapi.DomainHash) ([]*externalapi.DomainHash, error) {
|
||||
panic(errors.Errorf("called unimplemented function from test '%s'", f.testName))
|
||||
}
|
||||
@@ -477,29 +450,6 @@ func TestHandleRelayInvs(t *testing.T) {
|
||||
expectsBan: true,
|
||||
expectsErrToContain: "got unrequested block",
|
||||
},
|
||||
{
|
||||
name: "sending header only block on relay",
|
||||
funcToExecute: func(t *testing.T, incomingRoute, outgoingRoute *router.Route, context *fakeRelayInvsContext) {
|
||||
err := incomingRoute.Enqueue(appmessage.NewMsgInvBlock(headerOnlyBlockHash))
|
||||
if err != nil {
|
||||
t.Fatalf("Enqueue: %+v", err)
|
||||
}
|
||||
|
||||
msg, err := outgoingRoute.DequeueWithTimeout(time.Second)
|
||||
if err != nil {
|
||||
t.Fatalf("DequeueWithTimeout: %+v", err)
|
||||
}
|
||||
_ = msg.(*appmessage.MsgRequestRelayBlocks)
|
||||
|
||||
err = incomingRoute.Enqueue(appmessage.DomainBlockToMsgBlock(headerOnlyBlock))
|
||||
if err != nil {
|
||||
t.Fatalf("Enqueue: %+v", err)
|
||||
}
|
||||
},
|
||||
expectsProtocolError: true,
|
||||
expectsBan: true,
|
||||
expectsErrToContain: "block where expected block with body",
|
||||
},
|
||||
{
|
||||
name: "sending invalid block",
|
||||
funcToExecute: func(t *testing.T, incomingRoute, outgoingRoute *router.Route, context *fakeRelayInvsContext) {
|
||||
|
||||
@@ -69,11 +69,6 @@ func (m *Manager) SetOnBlockAddedToDAGHandler(onBlockAddedToDAGHandler flowconte
|
||||
m.context.SetOnBlockAddedToDAGHandler(onBlockAddedToDAGHandler)
|
||||
}
|
||||
|
||||
// SetOnPruningPointUTXOSetOverrideHandler sets the OnPruningPointUTXOSetOverride handler
|
||||
func (m *Manager) SetOnPruningPointUTXOSetOverrideHandler(onPruningPointUTXOSetOverrideHandler flowcontext.OnPruningPointUTXOSetOverrideHandler) {
|
||||
m.context.SetOnPruningPointUTXOSetOverrideHandler(onPruningPointUTXOSetOverrideHandler)
|
||||
}
|
||||
|
||||
// SetOnTransactionAddedToMempoolHandler sets the onTransactionAddedToMempool handler
|
||||
func (m *Manager) SetOnTransactionAddedToMempoolHandler(onTransactionAddedToMempoolHandler flowcontext.OnTransactionAddedToMempoolHandler) {
|
||||
m.context.SetOnTransactionAddedToMempoolHandler(onTransactionAddedToMempoolHandler)
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/protocol/flows/rejects"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/connmanager"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/app/protocol/flows/addressexchange"
|
||||
@@ -76,7 +75,7 @@ func (m *Manager) routerInitializer(router *routerpkg.Router, netConnection *net
|
||||
}
|
||||
|
||||
func (m *Manager) handleError(err error, netConnection *netadapter.NetConnection, outgoingRoute *routerpkg.Route) {
|
||||
if protocolErr := (protocolerrors.ProtocolError{}); errors.As(err, &protocolErr) {
|
||||
if protocolErr := &(protocolerrors.ProtocolError{}); errors.As(err, &protocolErr) {
|
||||
if !m.context.Config().DisableBanning && protocolErr.ShouldBan {
|
||||
log.Warnf("Banning %s (reason: %s)", netConnection, protocolErr.Cause)
|
||||
|
||||
@@ -90,7 +89,7 @@ func (m *Manager) handleError(err error, netConnection *netadapter.NetConnection
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
log.Infof("Disconnecting from %s (reason: %s)", netConnection, protocolErr.Cause)
|
||||
log.Debugf("Disconnecting from %s (reason: %s)", netConnection, protocolErr.Cause)
|
||||
netConnection.Disconnect()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -12,19 +12,19 @@ type ProtocolError struct {
|
||||
Cause error
|
||||
}
|
||||
|
||||
func (e ProtocolError) Error() string {
|
||||
func (e *ProtocolError) Error() string {
|
||||
return e.Cause.Error()
|
||||
}
|
||||
|
||||
// Unwrap returns the cause of ProtocolError, to be used with `errors.Unwrap()`
|
||||
func (e ProtocolError) Unwrap() error {
|
||||
func (e *ProtocolError) Unwrap() error {
|
||||
return e.Cause
|
||||
}
|
||||
|
||||
// Errorf formats according to a format specifier and returns the string
|
||||
// as a ProtocolError.
|
||||
func Errorf(shouldBan bool, format string, args ...interface{}) error {
|
||||
return ProtocolError{
|
||||
return &ProtocolError{
|
||||
ShouldBan: shouldBan,
|
||||
Cause: errors.Errorf(format, args...),
|
||||
}
|
||||
@@ -33,7 +33,7 @@ func Errorf(shouldBan bool, format string, args ...interface{}) error {
|
||||
// New returns a ProtocolError with the supplied message.
|
||||
// New also records the stack trace at the point it was called.
|
||||
func New(shouldBan bool, message string) error {
|
||||
return ProtocolError{
|
||||
return &ProtocolError{
|
||||
ShouldBan: shouldBan,
|
||||
Cause: errors.New(message),
|
||||
}
|
||||
@@ -41,7 +41,7 @@ func New(shouldBan bool, message string) error {
|
||||
|
||||
// Wrap wraps the given error and returns it as a ProtocolError.
|
||||
func Wrap(shouldBan bool, err error, message string) error {
|
||||
return ProtocolError{
|
||||
return &ProtocolError{
|
||||
ShouldBan: shouldBan,
|
||||
Cause: errors.Wrap(err, message),
|
||||
}
|
||||
@@ -49,7 +49,7 @@ func Wrap(shouldBan bool, err error, message string) error {
|
||||
|
||||
// Wrapf wraps the given error with the given format and returns it as a ProtocolError.
|
||||
func Wrapf(shouldBan bool, err error, format string, args ...interface{}) error {
|
||||
return ProtocolError{
|
||||
return &ProtocolError{
|
||||
ShouldBan: shouldBan,
|
||||
Cause: errors.Wrapf(err, format, args...),
|
||||
}
|
||||
|
||||
@@ -78,22 +78,6 @@ func (m *Manager) NotifyBlockAddedToDAG(block *externalapi.DomainBlock, blockIns
|
||||
return m.context.NotificationManager.NotifyBlockAdded(blockAddedNotification)
|
||||
}
|
||||
|
||||
// NotifyPruningPointUTXOSetOverride notifies the manager whenever the UTXO index
|
||||
// resets due to pruning point change via IBD.
|
||||
func (m *Manager) NotifyPruningPointUTXOSetOverride() error {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyPruningPointUTXOSetOverride")
|
||||
defer onEnd()
|
||||
|
||||
if m.context.Config.UTXOIndex {
|
||||
err := m.notifyPruningPointUTXOSetOverride()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NotifyFinalityConflict notifies the manager that there's a finality conflict in the DAG
|
||||
func (m *Manager) NotifyFinalityConflict(violatingBlockHash string) error {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyFinalityConflict")
|
||||
@@ -116,25 +100,13 @@ func (m *Manager) notifyUTXOsChanged(blockInsertionResult *externalapi.BlockInse
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyUTXOsChanged")
|
||||
defer onEnd()
|
||||
|
||||
utxoIndexChanges, err := m.context.UTXOIndex.Update(blockInsertionResult)
|
||||
utxoIndexChanges, err := m.context.UTXOIndex.Update(blockInsertionResult.VirtualSelectedParentChainChanges)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return m.context.NotificationManager.NotifyUTXOsChanged(utxoIndexChanges)
|
||||
}
|
||||
|
||||
func (m *Manager) notifyPruningPointUTXOSetOverride() error {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.notifyPruningPointUTXOSetOverride")
|
||||
defer onEnd()
|
||||
|
||||
err := m.context.UTXOIndex.Reset()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return m.context.NotificationManager.NotifyPruningPointUTXOSetOverride()
|
||||
}
|
||||
|
||||
func (m *Manager) notifyVirtualSelectedParentBlueScoreChanged() error {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyVirtualSelectedParentBlueScoreChanged")
|
||||
defer onEnd()
|
||||
|
||||
@@ -42,8 +42,6 @@ var handlers = map[appmessage.MessageCommand]handler{
|
||||
appmessage.CmdBanRequestMessage: rpchandlers.HandleBan,
|
||||
appmessage.CmdUnbanRequestMessage: rpchandlers.HandleUnban,
|
||||
appmessage.CmdGetInfoRequestMessage: rpchandlers.HandleGetInfo,
|
||||
appmessage.CmdNotifyPruningPointUTXOSetOverrideRequestMessage: rpchandlers.HandleNotifyPruningPointUTXOSetOverrideRequest,
|
||||
appmessage.CmdStopNotifyingPruningPointUTXOSetOverrideRequestMessage: rpchandlers.HandleStopNotifyingPruningPointUTXOSetOverrideRequest,
|
||||
}
|
||||
|
||||
func (m *Manager) routerInitializer(router *router.Router, netConnection *netadapter.NetConnection) {
|
||||
|
||||
@@ -30,7 +30,6 @@ type NotificationListener struct {
|
||||
propagateFinalityConflictResolvedNotifications bool
|
||||
propagateUTXOsChangedNotifications bool
|
||||
propagateVirtualSelectedParentBlueScoreChangedNotifications bool
|
||||
propagatePruningPointUTXOSetOverrideNotifications bool
|
||||
|
||||
propagateUTXOsChangedNotificationAddresses map[utxoindex.ScriptPublicKeyString]*UTXOsChangedNotificationAddress
|
||||
}
|
||||
@@ -181,23 +180,6 @@ func (nm *NotificationManager) NotifyVirtualSelectedParentBlueScoreChanged(
|
||||
return nil
|
||||
}
|
||||
|
||||
// NotifyPruningPointUTXOSetOverride notifies the notification manager that the UTXO index
|
||||
// reset due to pruning point change via IBD.
|
||||
func (nm *NotificationManager) NotifyPruningPointUTXOSetOverride() error {
|
||||
nm.RLock()
|
||||
defer nm.RUnlock()
|
||||
|
||||
for router, listener := range nm.listeners {
|
||||
if listener.propagatePruningPointUTXOSetOverrideNotifications {
|
||||
err := router.OutgoingRoute().Enqueue(appmessage.NewPruningPointUTXOSetOverrideNotificationMessage())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newNotificationListener() *NotificationListener {
|
||||
return &NotificationListener{
|
||||
propagateBlockAddedNotifications: false,
|
||||
@@ -206,7 +188,6 @@ func newNotificationListener() *NotificationListener {
|
||||
propagateFinalityConflictResolvedNotifications: false,
|
||||
propagateUTXOsChangedNotifications: false,
|
||||
propagateVirtualSelectedParentBlueScoreChangedNotifications: false,
|
||||
propagatePruningPointUTXOSetOverrideNotifications: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,15 +288,3 @@ func (nl *NotificationListener) convertUTXOChangesToUTXOsChangedNotification(
|
||||
func (nl *NotificationListener) PropagateVirtualSelectedParentBlueScoreChangedNotifications() {
|
||||
nl.propagateVirtualSelectedParentBlueScoreChangedNotifications = true
|
||||
}
|
||||
|
||||
// PropagatePruningPointUTXOSetOverrideNotifications instructs the listener to send pruning point UTXO set override notifications
|
||||
// to the remote listener.
|
||||
func (nl *NotificationListener) PropagatePruningPointUTXOSetOverrideNotifications() {
|
||||
nl.propagatePruningPointUTXOSetOverrideNotifications = true
|
||||
}
|
||||
|
||||
// StopPropagatingPruningPointUTXOSetOverrideNotifications instructs the listener to stop sending pruning
|
||||
// point UTXO set override notifications to the remote listener.
|
||||
func (nl *NotificationListener) StopPropagatingPruningPointUTXOSetOverrideNotifications() {
|
||||
nl.propagatePruningPointUTXOSetOverrideNotifications = false
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
package rpchandlers
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/app/rpc/rpccontext"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
)
|
||||
|
||||
// HandleNotifyPruningPointUTXOSetOverrideRequest handles the respectively named RPC command
|
||||
func HandleNotifyPruningPointUTXOSetOverrideRequest(context *rpccontext.Context, router *router.Router, _ appmessage.Message) (appmessage.Message, error) {
|
||||
listener, err := context.NotificationManager.Listener(router)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
listener.PropagatePruningPointUTXOSetOverrideNotifications()
|
||||
|
||||
response := appmessage.NewNotifyPruningPointUTXOSetOverrideResponseMessage()
|
||||
return response, nil
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package rpchandlers
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/app/rpc/rpccontext"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
)
|
||||
|
||||
// HandleStopNotifyingPruningPointUTXOSetOverrideRequest handles the respectively named RPC command
|
||||
func HandleStopNotifyingPruningPointUTXOSetOverrideRequest(context *rpccontext.Context, router *router.Router, _ appmessage.Message) (appmessage.Message, error) {
|
||||
listener, err := context.NotificationManager.Listener(router)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
listener.StopPropagatingPruningPointUTXOSetOverrideNotifications()
|
||||
|
||||
response := appmessage.NewStopNotifyingPruningPointUTXOSetOverrideResponseMessage()
|
||||
return response, nil
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package rpchandlers
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
|
||||
"github.com/kaspanet/kaspad/app/rpc/rpccontext"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
@@ -26,11 +25,9 @@ func HandleSubmitBlock(context *rpccontext.Context, _ *router.Router, request ap
|
||||
|
||||
err := context.ProtocolManager.AddBlock(domainBlock)
|
||||
if err != nil {
|
||||
isProtocolOrRuleError := errors.As(err, &ruleerrors.RuleError{}) || errors.As(err, &protocolerrors.ProtocolError{})
|
||||
if !isProtocolOrRuleError {
|
||||
if !errors.As(err, &ruleerrors.RuleError{}) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &appmessage.SubmitBlockResponseMessage{
|
||||
Error: appmessage.RPCErrorf("Block rejected. Reason: %s", err),
|
||||
RejectReason: appmessage.RejectReasonBlockInvalid,
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
Kaspad v0.8.10 - 2021-02-25
|
||||
===========================
|
||||
|
||||
[*] Fix bug where invalid mempool transactions were not removed (#1551)
|
||||
[*] Add RPC reconnection to the miner (#1552)
|
||||
[*] Remove virtual diff parents - only selectedTip is virtualDiffParent now (#1550)
|
||||
[*] Fix UTXO index (#1548)
|
||||
[*] Prevent fast failing (#1545)
|
||||
[*] Increase the sleep time in kaspaminer when the node is not synced (#1544)
|
||||
[*] Disallow header only blocks on RPC, relay and when requesting IBD full blocks (#1537)
|
||||
[*] Make templateManager hold a DomainBlock and isSynced bool instead of a GetBlockTemplateResponseMessage (#1538)
|
||||
@@ -4,7 +4,7 @@ kaspactl is an RPC client for kaspad
|
||||
|
||||
## Requirements
|
||||
|
||||
Go 1.16 or later.
|
||||
Go 1.15 or later.
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -- multistage docker build: stage #1: build stage
|
||||
FROM golang:1.16-alpine AS build
|
||||
FROM golang:1.15-alpine AS build
|
||||
|
||||
RUN mkdir -p /go/src/github.com/kaspanet/kaspad
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Kaspaminer is a CPU-based miner for kaspad
|
||||
|
||||
## Requirements
|
||||
|
||||
Go 1.16 or later.
|
||||
Go 1.15 or later.
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
@@ -5,95 +5,42 @@ import (
|
||||
"github.com/kaspanet/kaspad/infrastructure/logger"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/rpcclient"
|
||||
"github.com/pkg/errors"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
const minerTimeout = 10 * time.Second
|
||||
|
||||
type minerClient struct {
|
||||
isReconnecting uint32
|
||||
clientLock sync.RWMutex
|
||||
rpcClient *rpcclient.RPCClient
|
||||
*rpcclient.RPCClient
|
||||
|
||||
cfg *configFlags
|
||||
blockAddedNotificationChan chan struct{}
|
||||
}
|
||||
|
||||
func (mc *minerClient) safeRPCClient() *rpcclient.RPCClient {
|
||||
mc.clientLock.RLock()
|
||||
defer mc.clientLock.RUnlock()
|
||||
return mc.rpcClient
|
||||
}
|
||||
|
||||
func (mc *minerClient) reconnect() {
|
||||
swapped := atomic.CompareAndSwapUint32(&mc.isReconnecting, 0, 1)
|
||||
if !swapped {
|
||||
return
|
||||
}
|
||||
|
||||
defer atomic.StoreUint32(&mc.isReconnecting, 0)
|
||||
|
||||
mc.clientLock.Lock()
|
||||
defer mc.clientLock.Unlock()
|
||||
|
||||
retryDuration := time.Second
|
||||
const maxRetryDuration = time.Minute
|
||||
log.Infof("Reconnecting RPC connection")
|
||||
for {
|
||||
err := mc.connect()
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if retryDuration < time.Minute {
|
||||
retryDuration *= 2
|
||||
} else {
|
||||
retryDuration = maxRetryDuration
|
||||
}
|
||||
|
||||
log.Errorf("Got error '%s' while reconnecting. Trying again in %s", err, retryDuration)
|
||||
time.Sleep(retryDuration)
|
||||
}
|
||||
}
|
||||
|
||||
func (mc *minerClient) connect() error {
|
||||
rpcAddress, err := mc.cfg.NetParams().NormalizeRPCServerAddress(mc.cfg.RPCServer)
|
||||
func newMinerClient(cfg *configFlags) (*minerClient, error) {
|
||||
rpcAddress, err := cfg.NetParams().NormalizeRPCServerAddress(cfg.RPCServer)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
mc.rpcClient, err = rpcclient.NewRPCClient(rpcAddress)
|
||||
rpcClient, err := rpcclient.NewRPCClient(rpcAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
mc.rpcClient.SetTimeout(minerTimeout)
|
||||
mc.rpcClient.SetLogger(backendLog, logger.LevelTrace)
|
||||
rpcClient.SetTimeout(minerTimeout)
|
||||
rpcClient.SetLogger(backendLog, logger.LevelTrace)
|
||||
|
||||
err = mc.rpcClient.RegisterForBlockAddedNotifications(func(_ *appmessage.BlockAddedNotificationMessage) {
|
||||
minerClient := &minerClient{
|
||||
RPCClient: rpcClient,
|
||||
blockAddedNotificationChan: make(chan struct{}),
|
||||
}
|
||||
|
||||
err = rpcClient.RegisterForBlockAddedNotifications(func(_ *appmessage.BlockAddedNotificationMessage) {
|
||||
select {
|
||||
case mc.blockAddedNotificationChan <- struct{}{}:
|
||||
case minerClient.blockAddedNotificationChan <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error requesting block-added notifications")
|
||||
}
|
||||
|
||||
log.Infof("Connected to %s", rpcAddress)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func newMinerClient(cfg *configFlags) (*minerClient, error) {
|
||||
minerClient := &minerClient{
|
||||
cfg: cfg,
|
||||
blockAddedNotificationChan: make(chan struct{}),
|
||||
}
|
||||
|
||||
err := minerClient.connect()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrapf(err, "error requesting block-added notifications")
|
||||
}
|
||||
|
||||
return minerClient, nil
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -- multistage docker build: stage #1: build stage
|
||||
FROM golang:1.16-alpine AS build
|
||||
FROM golang:1.15-alpine AS build
|
||||
|
||||
RUN mkdir -p /go/src/github.com/kaspanet/kaspad
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ func main() {
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "error connecting to the RPC server"))
|
||||
}
|
||||
defer client.safeRPCClient().Disconnect()
|
||||
defer client.Disconnect()
|
||||
|
||||
miningAddr, err := util.DecodeAddress(cfg.MiningAddr, cfg.ActiveNetParams.Prefix)
|
||||
if err != nil {
|
||||
|
||||
@@ -2,13 +2,12 @@ package main
|
||||
|
||||
import (
|
||||
nativeerrors "errors"
|
||||
"math/rand"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/kaspanet/kaspad/cmd/kaspaminer/templatemanager"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/pow"
|
||||
"github.com/kaspanet/kaspad/util/difficulty"
|
||||
"math/rand"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
|
||||
@@ -113,13 +112,12 @@ func logHashRate() {
|
||||
|
||||
func handleFoundBlock(client *minerClient, block *externalapi.DomainBlock) error {
|
||||
blockHash := consensushashing.BlockHash(block)
|
||||
log.Infof("Submitting block %s to %s", blockHash, client.safeRPCClient().Address())
|
||||
log.Infof("Submitting block %s to %s", blockHash, client.Address())
|
||||
|
||||
rejectReason, err := client.safeRPCClient().SubmitBlock(block)
|
||||
rejectReason, err := client.SubmitBlock(block)
|
||||
if err != nil {
|
||||
if nativeerrors.Is(err, router.ErrTimeout) {
|
||||
log.Warnf("Got timeout while submitting block %s to %s: %s", blockHash, client.safeRPCClient().Address(), err)
|
||||
client.reconnect()
|
||||
log.Warnf("Got timeout while submitting block %s to %s: %s", blockHash, client.Address(), err)
|
||||
return nil
|
||||
}
|
||||
if rejectReason == appmessage.RejectReasonIsInIBD {
|
||||
@@ -128,7 +126,7 @@ func handleFoundBlock(client *minerClient, block *externalapi.DomainBlock) error
|
||||
time.Sleep(waitTime)
|
||||
return nil
|
||||
}
|
||||
return errors.Wrapf(err, "Error submitting block %s to %s", blockHash, client.safeRPCClient().Address())
|
||||
return errors.Errorf("Error submitting block %s to %s: %s", blockHash, client.Address(), err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -157,15 +155,11 @@ func mineNextBlock(mineWhenNotSynced bool) *externalapi.DomainBlock {
|
||||
|
||||
func getBlockForMining(mineWhenNotSynced bool) *externalapi.DomainBlock {
|
||||
tryCount := 0
|
||||
|
||||
const sleepTime = 500 * time.Millisecond
|
||||
const sleepTimeWhenNotSynced = 5 * time.Second
|
||||
|
||||
for {
|
||||
tryCount++
|
||||
|
||||
const sleepTime = 500 * time.Millisecond
|
||||
shouldLog := (tryCount-1)%10 == 0
|
||||
template, isSynced := templatemanager.Get()
|
||||
template := templatemanager.Get()
|
||||
if template == nil {
|
||||
if shouldLog {
|
||||
log.Info("Waiting for the initial template")
|
||||
@@ -173,28 +167,27 @@ func getBlockForMining(mineWhenNotSynced bool) *externalapi.DomainBlock {
|
||||
time.Sleep(sleepTime)
|
||||
continue
|
||||
}
|
||||
if !isSynced && !mineWhenNotSynced {
|
||||
if !template.IsSynced && !mineWhenNotSynced {
|
||||
if shouldLog {
|
||||
log.Warnf("Kaspad is not synced. Skipping current block template")
|
||||
}
|
||||
time.Sleep(sleepTimeWhenNotSynced)
|
||||
time.Sleep(sleepTime)
|
||||
continue
|
||||
}
|
||||
|
||||
return template
|
||||
return appmessage.MsgBlockToDomainBlock(template.MsgBlock)
|
||||
}
|
||||
}
|
||||
|
||||
func templatesLoop(client *minerClient, miningAddr util.Address, errChan chan error) {
|
||||
getBlockTemplate := func() {
|
||||
template, err := client.safeRPCClient().GetBlockTemplate(miningAddr.String())
|
||||
template, err := client.GetBlockTemplate(miningAddr.String())
|
||||
if nativeerrors.Is(err, router.ErrTimeout) {
|
||||
log.Warnf("Got timeout while requesting block template from %s: %s", client.safeRPCClient().Address(), err)
|
||||
client.reconnect()
|
||||
log.Warnf("Got timeout while requesting block template from %s: %s", client.Address(), err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
errChan <- errors.Wrapf(err, "Error getting block template from %s", client.safeRPCClient().Address())
|
||||
errChan <- errors.Errorf("Error getting block template from %s: %s", client.Address(), err)
|
||||
return
|
||||
}
|
||||
templatemanager.Set(template)
|
||||
|
||||
@@ -2,31 +2,22 @@ package templatemanager
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var currentTemplate *externalapi.DomainBlock
|
||||
var isSynced bool
|
||||
var currentTemplate *appmessage.GetBlockTemplateResponseMessage
|
||||
var lock = &sync.Mutex{}
|
||||
|
||||
// Get returns the template to work on
|
||||
func Get() (*externalapi.DomainBlock, bool) {
|
||||
func Get() *appmessage.GetBlockTemplateResponseMessage {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
// Shallow copy the block so when the user replaces the header it won't affect the template here.
|
||||
if currentTemplate == nil {
|
||||
return nil, false
|
||||
}
|
||||
block := *currentTemplate
|
||||
return &block, isSynced
|
||||
return currentTemplate
|
||||
}
|
||||
|
||||
// Set sets the current template to work on
|
||||
func Set(template *appmessage.GetBlockTemplateResponseMessage) {
|
||||
block := appmessage.MsgBlockToDomainBlock(template.MsgBlock)
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
currentTemplate = block
|
||||
isSynced = template.IsSynced
|
||||
currentTemplate = template
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ It is capable of generating wallet key-pairs, printing a wallet's current balanc
|
||||
|
||||
## Requirements
|
||||
|
||||
Go 1.16 or later.
|
||||
Go 1.15 or later.
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -- multistage docker build: stage #1: build stage
|
||||
FROM golang:1.16-alpine AS build
|
||||
FROM golang:1.15-alpine AS build
|
||||
|
||||
RUN mkdir -p /go/src/github.com/kaspanet/kaspad
|
||||
|
||||
@@ -16,12 +16,9 @@ RUN go get -u golang.org/x/lint/golint \
|
||||
COPY go.mod .
|
||||
COPY go.sum .
|
||||
|
||||
# Cache kaspad dependencies
|
||||
RUN go mod download
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN ./build_and_test.sh
|
||||
RUN NO_PARALLEL=1 ./build_and_test.sh
|
||||
|
||||
# --- multistage docker build: stage #2: runtime image
|
||||
FROM alpine
|
||||
|
||||
@@ -223,30 +223,6 @@ func (s *consensus) GetPruningPointUTXOs(expectedPruningPointHash *externalapi.D
|
||||
return pruningPointUTXOs, nil
|
||||
}
|
||||
|
||||
func (s *consensus) GetVirtualUTXOs(expectedVirtualParents []*externalapi.DomainHash,
|
||||
fromOutpoint *externalapi.DomainOutpoint, limit int) ([]*externalapi.OutpointAndUTXOEntryPair, error) {
|
||||
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
virtualParents, err := s.dagTopologyManager.Parents(model.VirtualBlockHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !externalapi.HashesEqual(expectedVirtualParents, virtualParents) {
|
||||
return nil, errors.Wrapf(ruleerrors.ErrGetVirtualUTXOsWrongVirtualParents, "expected virtual parents %s but got %s",
|
||||
expectedVirtualParents,
|
||||
virtualParents)
|
||||
}
|
||||
|
||||
virtualUTXOs, err := s.consensusStateStore.VirtualUTXOs(s.databaseContext, fromOutpoint, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return virtualUTXOs, nil
|
||||
}
|
||||
|
||||
func (s *consensus) PruningPoint() (*externalapi.DomainHash, error) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
@@ -1,21 +1,6 @@
|
||||
package consensus
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"math/big"
|
||||
"time"
|
||||
)
|
||||
import "github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
|
||||
// GHOSTDAGManagerConstructor is the function signature for a constructor of a type implementing model.GHOSTDAGManager
|
||||
type GHOSTDAGManagerConstructor func(model.DBReader, model.DAGTopologyManager,
|
||||
model.GHOSTDAGDataStore, model.BlockHeaderStore, model.KType) model.GHOSTDAGManager
|
||||
|
||||
// DifficultyManagerConstructor is the function signature for a constructor of a type implementing model.DifficultyManager
|
||||
type DifficultyManagerConstructor func(model.DBReader, model.GHOSTDAGManager, model.GHOSTDAGDataStore,
|
||||
model.BlockHeaderStore, model.DAGTopologyManager, model.DAGTraversalManager, *big.Int, int, bool, time.Duration,
|
||||
*externalapi.DomainHash) model.DifficultyManager
|
||||
|
||||
// PastMedianTimeManagerConstructor is the function signature for a constructor of a type implementing model.PastMedianTimeManager
|
||||
type PastMedianTimeManagerConstructor func(int, model.DBReader, model.DAGTraversalManager, model.BlockHeaderStore,
|
||||
model.GHOSTDAGDataStore) model.PastMedianTimeManager
|
||||
type GHOSTDAGManagerConstructor func(model.DBReader, model.DAGTopologyManager, model.GHOSTDAGDataStore, model.BlockHeaderStore, model.KType) model.GHOSTDAGManager
|
||||
|
||||
@@ -1520,6 +1520,53 @@ func (x *DbTips) GetTips() []*DbHash {
|
||||
return nil
|
||||
}
|
||||
|
||||
type DbVirtualDiffParents struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
VirtualDiffParents []*DbHash `protobuf:"bytes,1,rep,name=virtualDiffParents,proto3" json:"virtualDiffParents,omitempty"`
|
||||
}
|
||||
|
||||
func (x *DbVirtualDiffParents) Reset() {
|
||||
*x = DbVirtualDiffParents{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_dbobjects_proto_msgTypes[25]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DbVirtualDiffParents) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DbVirtualDiffParents) ProtoMessage() {}
|
||||
|
||||
func (x *DbVirtualDiffParents) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_dbobjects_proto_msgTypes[25]
|
||||
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 DbVirtualDiffParents.ProtoReflect.Descriptor instead.
|
||||
func (*DbVirtualDiffParents) Descriptor() ([]byte, []int) {
|
||||
return file_dbobjects_proto_rawDescGZIP(), []int{25}
|
||||
}
|
||||
|
||||
func (x *DbVirtualDiffParents) GetVirtualDiffParents() []*DbHash {
|
||||
if x != nil {
|
||||
return x.VirtualDiffParents
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DbBlockCount struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -1531,7 +1578,7 @@ type DbBlockCount struct {
|
||||
func (x *DbBlockCount) Reset() {
|
||||
*x = DbBlockCount{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_dbobjects_proto_msgTypes[25]
|
||||
mi := &file_dbobjects_proto_msgTypes[26]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -1544,7 +1591,7 @@ func (x *DbBlockCount) String() string {
|
||||
func (*DbBlockCount) ProtoMessage() {}
|
||||
|
||||
func (x *DbBlockCount) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_dbobjects_proto_msgTypes[25]
|
||||
mi := &file_dbobjects_proto_msgTypes[26]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -1557,7 +1604,7 @@ func (x *DbBlockCount) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use DbBlockCount.ProtoReflect.Descriptor instead.
|
||||
func (*DbBlockCount) Descriptor() ([]byte, []int) {
|
||||
return file_dbobjects_proto_rawDescGZIP(), []int{25}
|
||||
return file_dbobjects_proto_rawDescGZIP(), []int{26}
|
||||
}
|
||||
|
||||
func (x *DbBlockCount) GetCount() uint64 {
|
||||
@@ -1578,7 +1625,7 @@ type DbBlockHeaderCount struct {
|
||||
func (x *DbBlockHeaderCount) Reset() {
|
||||
*x = DbBlockHeaderCount{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_dbobjects_proto_msgTypes[26]
|
||||
mi := &file_dbobjects_proto_msgTypes[27]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -1591,7 +1638,7 @@ func (x *DbBlockHeaderCount) String() string {
|
||||
func (*DbBlockHeaderCount) ProtoMessage() {}
|
||||
|
||||
func (x *DbBlockHeaderCount) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_dbobjects_proto_msgTypes[26]
|
||||
mi := &file_dbobjects_proto_msgTypes[27]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -1604,7 +1651,7 @@ func (x *DbBlockHeaderCount) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use DbBlockHeaderCount.ProtoReflect.Descriptor instead.
|
||||
func (*DbBlockHeaderCount) Descriptor() ([]byte, []int) {
|
||||
return file_dbobjects_proto_rawDescGZIP(), []int{26}
|
||||
return file_dbobjects_proto_rawDescGZIP(), []int{27}
|
||||
}
|
||||
|
||||
func (x *DbBlockHeaderCount) GetCount() uint64 {
|
||||
@@ -1844,15 +1891,21 @@ var file_dbobjects_proto_rawDesc = []byte{
|
||||
0x62, 0x54, 0x69, 0x70, 0x73, 0x12, 0x29, 0x0a, 0x04, 0x74, 0x69, 0x70, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68, 0x52, 0x04, 0x74, 0x69, 0x70, 0x73,
|
||||
0x22, 0x24, 0x0a, 0x0c, 0x44, 0x62, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
|
||||
0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x2a, 0x0a, 0x12, 0x44, 0x62, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x42, 0x2a, 0x5a, 0x28, 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, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x22, 0x5d, 0x0a, 0x14, 0x44, 0x62, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x44, 0x69, 0x66,
|
||||
0x66, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x45, 0x0a, 0x12, 0x76, 0x69, 0x72, 0x74,
|
||||
0x75, 0x61, 0x6c, 0x44, 0x69, 0x66, 0x66, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68, 0x52, 0x12, 0x76, 0x69, 0x72,
|
||||
0x74, 0x75, 0x61, 0x6c, 0x44, 0x69, 0x66, 0x66, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22,
|
||||
0x24, 0x0a, 0x0c, 0x44, 0x62, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x2a, 0x0a, 0x12, 0x44, 0x62, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
|
||||
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x42, 0x2a, 0x5a, 0x28, 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,
|
||||
0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -1867,7 +1920,7 @@ func file_dbobjects_proto_rawDescGZIP() []byte {
|
||||
return file_dbobjects_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_dbobjects_proto_msgTypes = make([]protoimpl.MessageInfo, 27)
|
||||
var file_dbobjects_proto_msgTypes = make([]protoimpl.MessageInfo, 28)
|
||||
var file_dbobjects_proto_goTypes = []interface{}{
|
||||
(*DbBlock)(nil), // 0: serialization.DbBlock
|
||||
(*DbBlockHeader)(nil), // 1: serialization.DbBlockHeader
|
||||
@@ -1894,8 +1947,9 @@ var file_dbobjects_proto_goTypes = []interface{}{
|
||||
(*DbReachabilityInterval)(nil), // 22: serialization.DbReachabilityInterval
|
||||
(*DbUtxoDiff)(nil), // 23: serialization.DbUtxoDiff
|
||||
(*DbTips)(nil), // 24: serialization.DbTips
|
||||
(*DbBlockCount)(nil), // 25: serialization.DbBlockCount
|
||||
(*DbBlockHeaderCount)(nil), // 26: serialization.DbBlockHeaderCount
|
||||
(*DbVirtualDiffParents)(nil), // 25: serialization.DbVirtualDiffParents
|
||||
(*DbBlockCount)(nil), // 26: serialization.DbBlockCount
|
||||
(*DbBlockHeaderCount)(nil), // 27: serialization.DbBlockHeaderCount
|
||||
}
|
||||
var file_dbobjects_proto_depIdxs = []int32{
|
||||
1, // 0: serialization.DbBlock.header:type_name -> serialization.DbBlockHeader
|
||||
@@ -1934,11 +1988,12 @@ var file_dbobjects_proto_depIdxs = []int32{
|
||||
18, // 33: serialization.DbUtxoDiff.toAdd:type_name -> serialization.DbUtxoCollectionItem
|
||||
18, // 34: serialization.DbUtxoDiff.toRemove:type_name -> serialization.DbUtxoCollectionItem
|
||||
2, // 35: serialization.DbTips.tips:type_name -> serialization.DbHash
|
||||
36, // [36:36] is the sub-list for method output_type
|
||||
36, // [36:36] is the sub-list for method input_type
|
||||
36, // [36:36] is the sub-list for extension type_name
|
||||
36, // [36:36] is the sub-list for extension extendee
|
||||
0, // [0:36] is the sub-list for field type_name
|
||||
2, // 36: serialization.DbVirtualDiffParents.virtualDiffParents:type_name -> serialization.DbHash
|
||||
37, // [37:37] is the sub-list for method output_type
|
||||
37, // [37:37] is the sub-list for method input_type
|
||||
37, // [37:37] is the sub-list for extension type_name
|
||||
37, // [37:37] is the sub-list for extension extendee
|
||||
0, // [0:37] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_dbobjects_proto_init() }
|
||||
@@ -2248,7 +2303,7 @@ func file_dbobjects_proto_init() {
|
||||
}
|
||||
}
|
||||
file_dbobjects_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DbBlockCount); i {
|
||||
switch v := v.(*DbVirtualDiffParents); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -2260,6 +2315,18 @@ func file_dbobjects_proto_init() {
|
||||
}
|
||||
}
|
||||
file_dbobjects_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DbBlockCount); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_dbobjects_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DbBlockHeaderCount); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -2278,7 +2345,7 @@ func file_dbobjects_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_dbobjects_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 27,
|
||||
NumMessages: 28,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -143,6 +143,10 @@ message DbTips {
|
||||
repeated DbHash tips = 1;
|
||||
}
|
||||
|
||||
message DbVirtualDiffParents {
|
||||
repeated DbHash virtualDiffParents = 1;
|
||||
}
|
||||
|
||||
message DbBlockCount {
|
||||
uint64 count = 1;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package serialization
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
|
||||
)
|
||||
|
||||
func utxoCollectionToDBUTXOCollection(utxoCollection externalapi.UTXOCollection) ([]*DbUtxoCollectionItem, error) {
|
||||
func utxoCollectionToDBUTXOCollection(utxoCollection model.UTXOCollection) ([]*DbUtxoCollectionItem, error) {
|
||||
items := make([]*DbUtxoCollectionItem, utxoCollection.Len())
|
||||
i := 0
|
||||
utxoIterator := utxoCollection.Iterator()
|
||||
@@ -25,7 +26,7 @@ func utxoCollectionToDBUTXOCollection(utxoCollection externalapi.UTXOCollection)
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func dbUTXOCollectionToUTXOCollection(items []*DbUtxoCollectionItem) (externalapi.UTXOCollection, error) {
|
||||
func dbUTXOCollectionToUTXOCollection(items []*DbUtxoCollectionItem) (model.UTXOCollection, error) {
|
||||
utxoMap := make(map[externalapi.DomainOutpoint]externalapi.UTXOEntry, len(items))
|
||||
for _, item := range items {
|
||||
outpoint, err := DbOutpointToDomainOutpoint(item.Outpoint)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package serialization
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
|
||||
)
|
||||
|
||||
// UTXODiffToDBUTXODiff converts UTXODiff to DbUtxoDiff
|
||||
func UTXODiffToDBUTXODiff(diff externalapi.UTXODiff) (*DbUtxoDiff, error) {
|
||||
func UTXODiffToDBUTXODiff(diff model.UTXODiff) (*DbUtxoDiff, error) {
|
||||
toAdd, err := utxoCollectionToDBUTXOCollection(diff.ToAdd())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -24,7 +24,7 @@ func UTXODiffToDBUTXODiff(diff externalapi.UTXODiff) (*DbUtxoDiff, error) {
|
||||
}
|
||||
|
||||
// DBUTXODiffToUTXODiff converts DbUtxoDiff to UTXODiff
|
||||
func DBUTXODiffToUTXODiff(diff *DbUtxoDiff) (externalapi.UTXODiff, error) {
|
||||
func DBUTXODiffToUTXODiff(diff *DbUtxoDiff) (model.UTXODiff, error) {
|
||||
toAdd, err := dbUTXOCollectionToUTXOCollection(diff.ToAdd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package serialization
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
// VirtualDiffParentsToDBHeaderVirtualDiffParents converts a slice of hashes to DbVirtualDiffParents
|
||||
func VirtualDiffParentsToDBHeaderVirtualDiffParents(tips []*externalapi.DomainHash) *DbVirtualDiffParents {
|
||||
return &DbVirtualDiffParents{
|
||||
VirtualDiffParents: DomainHashesToDbHashes(tips),
|
||||
}
|
||||
}
|
||||
|
||||
// DBVirtualDiffParentsToVirtualDiffParents converts DbHeaderTips to a slice of hashes
|
||||
func DBVirtualDiffParentsToVirtualDiffParents(dbVirtualDiffParents *DbVirtualDiffParents) ([]*externalapi.DomainHash, error) {
|
||||
return DbHashesToDomainHashes(dbVirtualDiffParents.VirtualDiffParents)
|
||||
}
|
||||
@@ -8,12 +8,14 @@ import (
|
||||
|
||||
// consensusStateStore represents a store for the current consensus state
|
||||
type consensusStateStore struct {
|
||||
tipsStaging []*externalapi.DomainHash
|
||||
virtualUTXODiffStaging externalapi.UTXODiff
|
||||
tipsStaging []*externalapi.DomainHash
|
||||
virtualDiffParentsStaging []*externalapi.DomainHash
|
||||
virtualUTXODiffStaging model.UTXODiff
|
||||
|
||||
virtualUTXOSetCache *utxolrucache.LRUCache
|
||||
|
||||
tipsCache []*externalapi.DomainHash
|
||||
tipsCache []*externalapi.DomainHash
|
||||
virtualDiffParentsCache []*externalapi.DomainHash
|
||||
}
|
||||
|
||||
// New instantiates a new ConsensusStateStore
|
||||
@@ -26,6 +28,7 @@ func New(utxoSetCacheSize int, preallocate bool) model.ConsensusStateStore {
|
||||
func (css *consensusStateStore) Discard() {
|
||||
css.tipsStaging = nil
|
||||
css.virtualUTXODiffStaging = nil
|
||||
css.virtualDiffParentsStaging = nil
|
||||
}
|
||||
|
||||
func (css *consensusStateStore) Commit(dbTx model.DBTransaction) error {
|
||||
@@ -33,6 +36,10 @@ func (css *consensusStateStore) Commit(dbTx model.DBTransaction) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = css.commitVirtualDiffParents(dbTx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = css.commitVirtualUTXODiff(dbTx)
|
||||
if err != nil {
|
||||
@@ -46,5 +53,6 @@ func (css *consensusStateStore) Commit(dbTx model.DBTransaction) error {
|
||||
|
||||
func (css *consensusStateStore) IsStaged() bool {
|
||||
return css.tipsStaging != nil ||
|
||||
css.virtualDiffParentsStaging != nil ||
|
||||
css.virtualUTXODiffStaging != nil
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func utxoKey(outpoint *externalapi.DomainOutpoint) (model.DBKey, error) {
|
||||
return utxoSetBucket.Key(serializedOutpoint), nil
|
||||
}
|
||||
|
||||
func (css *consensusStateStore) StageVirtualUTXODiff(virtualUTXODiff externalapi.UTXODiff) {
|
||||
func (css *consensusStateStore) StageVirtualUTXODiff(virtualUTXODiff model.UTXODiff) {
|
||||
css.virtualUTXODiffStaging = virtualUTXODiff
|
||||
}
|
||||
|
||||
@@ -149,43 +149,7 @@ func (css *consensusStateStore) hasUTXOByOutpointFromStagedVirtualUTXODiff(dbCon
|
||||
return dbContext.Has(key)
|
||||
}
|
||||
|
||||
func (css *consensusStateStore) VirtualUTXOs(dbContext model.DBReader,
|
||||
fromOutpoint *externalapi.DomainOutpoint, limit int) ([]*externalapi.OutpointAndUTXOEntryPair, error) {
|
||||
|
||||
cursor, err := dbContext.Cursor(utxoSetBucket)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if fromOutpoint != nil {
|
||||
serializedFromOutpoint, err := serializeOutpoint(fromOutpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
seekKey := utxoSetBucket.Key(serializedFromOutpoint)
|
||||
err = cursor.Seek(seekKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
iterator := newCursorUTXOSetIterator(cursor)
|
||||
|
||||
outpointAndUTXOEntryPairs := make([]*externalapi.OutpointAndUTXOEntryPair, 0, limit)
|
||||
for len(outpointAndUTXOEntryPairs) < limit && iterator.Next() {
|
||||
outpoint, utxoEntry, err := iterator.Get()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outpointAndUTXOEntryPairs = append(outpointAndUTXOEntryPairs, &externalapi.OutpointAndUTXOEntryPair{
|
||||
Outpoint: outpoint,
|
||||
UTXOEntry: utxoEntry,
|
||||
})
|
||||
}
|
||||
return outpointAndUTXOEntryPairs, nil
|
||||
}
|
||||
|
||||
func (css *consensusStateStore) VirtualUTXOSetIterator(dbContext model.DBReader) (externalapi.ReadOnlyUTXOSetIterator, error) {
|
||||
func (css *consensusStateStore) VirtualUTXOSetIterator(dbContext model.DBReader) (model.ReadOnlyUTXOSetIterator, error) {
|
||||
cursor, err := dbContext.Cursor(utxoSetBucket)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -203,7 +167,7 @@ type utxoSetIterator struct {
|
||||
cursor model.DBCursor
|
||||
}
|
||||
|
||||
func newCursorUTXOSetIterator(cursor model.DBCursor) externalapi.ReadOnlyUTXOSetIterator {
|
||||
func newCursorUTXOSetIterator(cursor model.DBCursor) model.ReadOnlyUTXOSetIterator {
|
||||
return &utxoSetIterator{cursor: cursor}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package consensusstatestore
|
||||
|
||||
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 virtualDiffParentsKey = database.MakeBucket(nil).Key([]byte("virtual-diff-parents"))
|
||||
|
||||
func (css *consensusStateStore) VirtualDiffParents(dbContext model.DBReader) ([]*externalapi.DomainHash, error) {
|
||||
if css.virtualDiffParentsStaging != nil {
|
||||
return externalapi.CloneHashes(css.virtualDiffParentsStaging), nil
|
||||
}
|
||||
|
||||
if css.virtualDiffParentsCache != nil {
|
||||
return externalapi.CloneHashes(css.virtualDiffParentsCache), nil
|
||||
}
|
||||
|
||||
virtualDiffParentsBytes, err := dbContext.Get(virtualDiffParentsKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
virtualDiffParents, err := css.deserializeVirtualDiffParents(virtualDiffParentsBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
css.virtualDiffParentsCache = virtualDiffParents
|
||||
return externalapi.CloneHashes(virtualDiffParents), nil
|
||||
}
|
||||
|
||||
func (css *consensusStateStore) StageVirtualDiffParents(tipHashes []*externalapi.DomainHash) {
|
||||
css.virtualDiffParentsStaging = externalapi.CloneHashes(tipHashes)
|
||||
}
|
||||
|
||||
func (css *consensusStateStore) commitVirtualDiffParents(dbTx model.DBTransaction) error {
|
||||
if css.virtualDiffParentsStaging == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
virtualDiffParentsBytes, err := css.serializeVirtualDiffParents(css.virtualDiffParentsStaging)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = dbTx.Put(virtualDiffParentsKey, virtualDiffParentsBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
css.virtualDiffParentsCache = css.virtualDiffParentsStaging
|
||||
|
||||
// Note: we don't discard the staging here since that's
|
||||
// being done at the end of Commit()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (css *consensusStateStore) serializeVirtualDiffParents(virtualDiffParentsBytes []*externalapi.DomainHash) ([]byte, error) {
|
||||
virtualDiffParents := serialization.VirtualDiffParentsToDBHeaderVirtualDiffParents(virtualDiffParentsBytes)
|
||||
return proto.Marshal(virtualDiffParents)
|
||||
}
|
||||
|
||||
func (css *consensusStateStore) deserializeVirtualDiffParents(virtualDiffParentsBytes []byte) ([]*externalapi.DomainHash,
|
||||
error) {
|
||||
|
||||
dbVirtualDiffParents := &serialization.DbVirtualDiffParents{}
|
||||
err := proto.Unmarshal(virtualDiffParentsBytes, dbVirtualDiffParents)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return serialization.DBVirtualDiffParentsToVirtualDiffParents(dbVirtualDiffParents)
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package consensusstatestore
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/database"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -22,7 +21,7 @@ func (css *consensusStateStore) FinishImportingPruningPointUTXOSet(dbContext mod
|
||||
}
|
||||
|
||||
func (css *consensusStateStore) ImportPruningPointUTXOSetIntoVirtualUTXOSet(dbContext model.DBWriter,
|
||||
pruningPointUTXOSetIterator externalapi.ReadOnlyUTXOSetIterator) error {
|
||||
pruningPointUTXOSetIterator model.ReadOnlyUTXOSetIterator) error {
|
||||
|
||||
if css.virtualUTXODiffStaging != nil {
|
||||
return errors.New("cannot import virtual UTXO set while virtual UTXO diff is staged")
|
||||
|
||||
@@ -51,7 +51,7 @@ func (ps *pruningStore) AppendImportedPruningPointUTXOs(dbTx model.DBTransaction
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ps *pruningStore) ImportedPruningPointUTXOIterator(dbContext model.DBReader) (externalapi.ReadOnlyUTXOSetIterator, error) {
|
||||
func (ps *pruningStore) ImportedPruningPointUTXOIterator(dbContext model.DBReader) (model.ReadOnlyUTXOSetIterator, error) {
|
||||
cursor, err := dbContext.Cursor(importedPruningPointUTXOsBucket)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -63,7 +63,7 @@ type utxoSetIterator struct {
|
||||
cursor model.DBCursor
|
||||
}
|
||||
|
||||
func (ps *pruningStore) newCursorUTXOSetIterator(cursor model.DBCursor) externalapi.ReadOnlyUTXOSetIterator {
|
||||
func (ps *pruningStore) newCursorUTXOSetIterator(cursor model.DBCursor) model.ReadOnlyUTXOSetIterator {
|
||||
return &utxoSetIterator{cursor: cursor}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ func (ps *pruningStore) Commit(dbTx model.DBTransaction) error {
|
||||
}
|
||||
|
||||
func (ps *pruningStore) UpdatePruningPointUTXOSet(dbContext model.DBWriter,
|
||||
utxoSetIterator externalapi.ReadOnlyUTXOSetIterator) error {
|
||||
utxoSetIterator model.ReadOnlyUTXOSetIterator) error {
|
||||
|
||||
// Delete all the old UTXOs from the database
|
||||
deleteCursor, err := dbContext.Cursor(pruningPointUTXOSetBucket)
|
||||
|
||||
@@ -15,7 +15,7 @@ var utxoDiffChildBucket = database.MakeBucket([]byte("utxo-diff-children"))
|
||||
|
||||
// utxoDiffStore represents a store of UTXODiffs
|
||||
type utxoDiffStore struct {
|
||||
utxoDiffStaging map[externalapi.DomainHash]externalapi.UTXODiff
|
||||
utxoDiffStaging map[externalapi.DomainHash]model.UTXODiff
|
||||
utxoDiffChildStaging map[externalapi.DomainHash]*externalapi.DomainHash
|
||||
toDelete map[externalapi.DomainHash]struct{}
|
||||
utxoDiffCache *lrucache.LRUCache
|
||||
@@ -25,7 +25,7 @@ type utxoDiffStore struct {
|
||||
// New instantiates a new UTXODiffStore
|
||||
func New(cacheSize int, preallocate bool) model.UTXODiffStore {
|
||||
return &utxoDiffStore{
|
||||
utxoDiffStaging: make(map[externalapi.DomainHash]externalapi.UTXODiff),
|
||||
utxoDiffStaging: make(map[externalapi.DomainHash]model.UTXODiff),
|
||||
utxoDiffChildStaging: make(map[externalapi.DomainHash]*externalapi.DomainHash),
|
||||
toDelete: make(map[externalapi.DomainHash]struct{}),
|
||||
utxoDiffCache: lrucache.New(cacheSize, preallocate),
|
||||
@@ -34,7 +34,7 @@ func New(cacheSize int, preallocate bool) model.UTXODiffStore {
|
||||
}
|
||||
|
||||
// Stage stages the given utxoDiff for the given blockHash
|
||||
func (uds *utxoDiffStore) Stage(blockHash *externalapi.DomainHash, utxoDiff externalapi.UTXODiff, utxoDiffChild *externalapi.DomainHash) {
|
||||
func (uds *utxoDiffStore) Stage(blockHash *externalapi.DomainHash, utxoDiff model.UTXODiff, utxoDiffChild *externalapi.DomainHash) {
|
||||
uds.utxoDiffStaging[*blockHash] = utxoDiff
|
||||
|
||||
if utxoDiffChild != nil {
|
||||
@@ -55,7 +55,7 @@ func (uds *utxoDiffStore) IsBlockHashStaged(blockHash *externalapi.DomainHash) b
|
||||
}
|
||||
|
||||
func (uds *utxoDiffStore) Discard() {
|
||||
uds.utxoDiffStaging = make(map[externalapi.DomainHash]externalapi.UTXODiff)
|
||||
uds.utxoDiffStaging = make(map[externalapi.DomainHash]model.UTXODiff)
|
||||
uds.utxoDiffChildStaging = make(map[externalapi.DomainHash]*externalapi.DomainHash)
|
||||
uds.toDelete = make(map[externalapi.DomainHash]struct{})
|
||||
}
|
||||
@@ -107,13 +107,13 @@ func (uds *utxoDiffStore) Commit(dbTx model.DBTransaction) error {
|
||||
}
|
||||
|
||||
// UTXODiff gets the utxoDiff associated with the given blockHash
|
||||
func (uds *utxoDiffStore) UTXODiff(dbContext model.DBReader, blockHash *externalapi.DomainHash) (externalapi.UTXODiff, error) {
|
||||
func (uds *utxoDiffStore) UTXODiff(dbContext model.DBReader, blockHash *externalapi.DomainHash) (model.UTXODiff, error) {
|
||||
if utxoDiff, ok := uds.utxoDiffStaging[*blockHash]; ok {
|
||||
return utxoDiff, nil
|
||||
}
|
||||
|
||||
if utxoDiff, ok := uds.utxoDiffCache.Get(blockHash); ok {
|
||||
return utxoDiff.(externalapi.UTXODiff), nil
|
||||
return utxoDiff.(model.UTXODiff), nil
|
||||
}
|
||||
|
||||
utxoDiffBytes, err := dbContext.Get(uds.utxoDiffHashAsKey(blockHash))
|
||||
@@ -187,7 +187,7 @@ func (uds *utxoDiffStore) utxoDiffChildHashAsKey(hash *externalapi.DomainHash) m
|
||||
return utxoDiffChildBucket.Key(hash.ByteSlice())
|
||||
}
|
||||
|
||||
func (uds *utxoDiffStore) serializeUTXODiff(utxoDiff externalapi.UTXODiff) ([]byte, error) {
|
||||
func (uds *utxoDiffStore) serializeUTXODiff(utxoDiff model.UTXODiff) ([]byte, error) {
|
||||
dbUtxoDiff, err := serialization.UTXODiffToDBUTXODiff(utxoDiff)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -201,7 +201,7 @@ func (uds *utxoDiffStore) serializeUTXODiff(utxoDiff externalapi.UTXODiff) ([]by
|
||||
return bytes, nil
|
||||
}
|
||||
|
||||
func (uds *utxoDiffStore) deserializeUTXODiff(utxoDiffBytes []byte) (externalapi.UTXODiff, error) {
|
||||
func (uds *utxoDiffStore) deserializeUTXODiff(utxoDiffBytes []byte) (model.UTXODiff, error) {
|
||||
dbUTXODiff := &serialization.DbUtxoDiff{}
|
||||
err := proto.Unmarshal(utxoDiffBytes, dbUTXODiff)
|
||||
if err != nil {
|
||||
|
||||
@@ -63,25 +63,19 @@ type Factory interface {
|
||||
SetTestGHOSTDAGManager(ghostdagConstructor GHOSTDAGManagerConstructor)
|
||||
SetTestLevelDBCacheSize(cacheSizeMiB int)
|
||||
SetTestPreAllocateCache(preallocateCaches bool)
|
||||
SetTestPastMedianTimeManager(medianTimeConstructor PastMedianTimeManagerConstructor)
|
||||
SetTestDifficultyManager(difficultyConstructor DifficultyManagerConstructor)
|
||||
}
|
||||
|
||||
type factory struct {
|
||||
dataDir string
|
||||
ghostdagConstructor GHOSTDAGManagerConstructor
|
||||
pastMedianTimeConsructor PastMedianTimeManagerConstructor
|
||||
difficultyConstructor DifficultyManagerConstructor
|
||||
cacheSizeMiB *int
|
||||
preallocateCaches *bool
|
||||
dataDir string
|
||||
ghostdagConstructor GHOSTDAGManagerConstructor
|
||||
cacheSizeMiB *int
|
||||
preallocateCaches *bool
|
||||
}
|
||||
|
||||
// NewFactory creates a new Consensus factory
|
||||
func NewFactory() Factory {
|
||||
return &factory{
|
||||
ghostdagConstructor: ghostdagmanager.New,
|
||||
pastMedianTimeConsructor: pastmediantimemanager.New,
|
||||
difficultyConstructor: difficultymanager.New,
|
||||
ghostdagConstructor: ghostdagmanager.New,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +144,7 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat
|
||||
reachabilityDataStore,
|
||||
ghostdagManager,
|
||||
consensusStateStore)
|
||||
pastMedianTimeManager := f.pastMedianTimeConsructor(
|
||||
pastMedianTimeManager := pastmediantimemanager.New(
|
||||
dagParams.TimestampDeviationTolerance,
|
||||
dbManager,
|
||||
dagTraversalManager,
|
||||
@@ -165,7 +159,7 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat
|
||||
dbManager,
|
||||
pastMedianTimeManager,
|
||||
ghostdagDataStore)
|
||||
difficultyManager := f.difficultyConstructor(
|
||||
difficultyManager := difficultymanager.New(
|
||||
dbManager,
|
||||
ghostdagManager,
|
||||
ghostdagDataStore,
|
||||
@@ -472,15 +466,6 @@ func (f *factory) SetTestGHOSTDAGManager(ghostdagConstructor GHOSTDAGManagerCons
|
||||
f.ghostdagConstructor = ghostdagConstructor
|
||||
}
|
||||
|
||||
func (f *factory) SetTestPastMedianTimeManager(medianTimeConstructor PastMedianTimeManagerConstructor) {
|
||||
f.pastMedianTimeConsructor = medianTimeConstructor
|
||||
}
|
||||
|
||||
// SetTestDifficultyManager is a setter for the difficultyManager field on the factory.
|
||||
func (f *factory) SetTestDifficultyManager(difficultyConstructor DifficultyManagerConstructor) {
|
||||
f.difficultyConstructor = difficultyConstructor
|
||||
}
|
||||
|
||||
func (f *factory) SetTestLevelDBCacheSize(cacheSizeMiB int) {
|
||||
f.cacheSizeMiB = &cacheSizeMiB
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ type Consensus interface {
|
||||
GetHashesBetween(lowHash, highHash *DomainHash, maxBlueScoreDifference uint64) ([]*DomainHash, error)
|
||||
GetMissingBlockBodyHashes(highHash *DomainHash) ([]*DomainHash, error)
|
||||
GetPruningPointUTXOs(expectedPruningPointHash *DomainHash, fromOutpoint *DomainOutpoint, limit int) ([]*OutpointAndUTXOEntryPair, error)
|
||||
GetVirtualUTXOs(expectedVirtualParents []*DomainHash, fromOutpoint *DomainOutpoint, limit int) ([]*OutpointAndUTXOEntryPair, error)
|
||||
PruningPoint() (*DomainHash, error)
|
||||
ClearImportedPruningPointData() error
|
||||
AppendImportedPruningPointUTXOs(outpointAndUTXOEntryPairs []*OutpointAndUTXOEntryPair) error
|
||||
|
||||
@@ -3,8 +3,6 @@ package externalapi
|
||||
// BlockInsertionResult is auxiliary data returned from ValidateAndInsertBlock
|
||||
type BlockInsertionResult struct {
|
||||
VirtualSelectedParentChainChanges *SelectedChainPath
|
||||
VirtualUTXODiff UTXODiff
|
||||
VirtualParents []*DomainHash
|
||||
}
|
||||
|
||||
// SelectedChainPath is a path the of the selected chains between two blocks.
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package externalapi
|
||||
|
||||
// ReadOnlyUTXOSetIterator is an iterator over all entries in a
|
||||
// ReadOnlyUTXOSet
|
||||
type ReadOnlyUTXOSetIterator interface {
|
||||
First() bool
|
||||
Next() bool
|
||||
Get() (outpoint *DomainOutpoint, utxoEntry UTXOEntry, err error)
|
||||
}
|
||||
@@ -7,18 +7,19 @@ type ConsensusStateStore interface {
|
||||
Store
|
||||
IsStaged() bool
|
||||
|
||||
StageVirtualUTXODiff(virtualUTXODiff externalapi.UTXODiff)
|
||||
StageVirtualUTXODiff(virtualUTXODiff UTXODiff)
|
||||
UTXOByOutpoint(dbContext DBReader, outpoint *externalapi.DomainOutpoint) (externalapi.UTXOEntry, error)
|
||||
HasUTXOByOutpoint(dbContext DBReader, outpoint *externalapi.DomainOutpoint) (bool, error)
|
||||
VirtualUTXOSetIterator(dbContext DBReader) (externalapi.ReadOnlyUTXOSetIterator, error)
|
||||
VirtualUTXOs(dbContext DBReader,
|
||||
fromOutpoint *externalapi.DomainOutpoint, limit int) ([]*externalapi.OutpointAndUTXOEntryPair, error)
|
||||
VirtualUTXOSetIterator(dbContext DBReader) (ReadOnlyUTXOSetIterator, error)
|
||||
|
||||
StageVirtualDiffParents(virtualDiffParents []*externalapi.DomainHash)
|
||||
VirtualDiffParents(dbContext DBReader) ([]*externalapi.DomainHash, error)
|
||||
|
||||
StageTips(tipHashes []*externalapi.DomainHash)
|
||||
Tips(dbContext DBReader) ([]*externalapi.DomainHash, error)
|
||||
|
||||
StartImportingPruningPointUTXOSet(dbContext DBWriter) error
|
||||
HadStartedImportingPruningPointUTXOSet(dbContext DBWriter) (bool, error)
|
||||
ImportPruningPointUTXOSetIntoVirtualUTXOSet(dbContext DBWriter, pruningPointUTXOSetIterator externalapi.ReadOnlyUTXOSetIterator) error
|
||||
ImportPruningPointUTXOSetIntoVirtualUTXOSet(dbContext DBWriter, pruningPointUTXOSetIterator ReadOnlyUTXOSetIterator) error
|
||||
FinishImportingPruningPointUTXOSet(dbContext DBWriter) error
|
||||
}
|
||||
|
||||
@@ -16,11 +16,11 @@ type PruningStore interface {
|
||||
StageStartUpdatingPruningPointUTXOSet()
|
||||
HadStartedUpdatingPruningPointUTXOSet(dbContext DBWriter) (bool, error)
|
||||
FinishUpdatingPruningPointUTXOSet(dbContext DBWriter) error
|
||||
UpdatePruningPointUTXOSet(dbContext DBWriter, utxoSetIterator externalapi.ReadOnlyUTXOSetIterator) error
|
||||
UpdatePruningPointUTXOSet(dbContext DBWriter, utxoSetIterator ReadOnlyUTXOSetIterator) error
|
||||
|
||||
ClearImportedPruningPointUTXOs(dbContext DBWriter) error
|
||||
AppendImportedPruningPointUTXOs(dbTx DBTransaction, outpointAndUTXOEntryPairs []*externalapi.OutpointAndUTXOEntryPair) error
|
||||
ImportedPruningPointUTXOIterator(dbContext DBReader) (externalapi.ReadOnlyUTXOSetIterator, error)
|
||||
ImportedPruningPointUTXOIterator(dbContext DBReader) (ReadOnlyUTXOSetIterator, error)
|
||||
ClearImportedPruningPointMultiset(dbContext DBWriter) error
|
||||
ImportedPruningPointMultiset(dbContext DBReader) (Multiset, error)
|
||||
UpdateImportedPruningPointMultiset(dbTx DBTransaction, multiset Multiset) error
|
||||
|
||||
@@ -5,9 +5,9 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
// UTXODiffStore represents a store of UTXODiffs
|
||||
type UTXODiffStore interface {
|
||||
Store
|
||||
Stage(blockHash *externalapi.DomainHash, utxoDiff externalapi.UTXODiff, utxoDiffChild *externalapi.DomainHash)
|
||||
Stage(blockHash *externalapi.DomainHash, utxoDiff UTXODiff, utxoDiffChild *externalapi.DomainHash)
|
||||
IsStaged() bool
|
||||
UTXODiff(dbContext DBReader, blockHash *externalapi.DomainHash) (externalapi.UTXODiff, error)
|
||||
UTXODiff(dbContext DBReader, blockHash *externalapi.DomainHash) (UTXODiff, error)
|
||||
UTXODiffChild(dbContext DBReader, blockHash *externalapi.DomainHash) (*externalapi.DomainHash, error)
|
||||
HasUTXODiffChild(dbContext DBReader, blockHash *externalapi.DomainHash) (bool, error)
|
||||
Delete(blockHash *externalapi.DomainHash)
|
||||
|
||||
@@ -4,11 +4,11 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
|
||||
// ConsensusStateManager manages the node's consensus state
|
||||
type ConsensusStateManager interface {
|
||||
AddBlock(blockHash *externalapi.DomainHash) (*externalapi.SelectedChainPath, externalapi.UTXODiff, error)
|
||||
AddBlock(blockHash *externalapi.DomainHash) (*externalapi.SelectedChainPath, error)
|
||||
PopulateTransactionWithUTXOEntries(transaction *externalapi.DomainTransaction) error
|
||||
ImportPruningPoint(newPruningPoint *externalapi.DomainBlock) error
|
||||
RestorePastUTXOSetIterator(blockHash *externalapi.DomainHash) (externalapi.ReadOnlyUTXOSetIterator, error)
|
||||
CalculatePastUTXOAndAcceptanceData(blockHash *externalapi.DomainHash) (externalapi.UTXODiff, externalapi.AcceptanceData, Multiset, error)
|
||||
RestorePastUTXOSetIterator(blockHash *externalapi.DomainHash) (ReadOnlyUTXOSetIterator, error)
|
||||
CalculatePastUTXOAndAcceptanceData(blockHash *externalapi.DomainHash) (UTXODiff, externalapi.AcceptanceData, Multiset, error)
|
||||
GetVirtualSelectedParentChainFromBlock(blockHash *externalapi.DomainHash) (*externalapi.SelectedChainPath, error)
|
||||
RecoverUTXOIfRequired() error
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ type DAGTraversalManager interface {
|
||||
// from lowHash (exclusive) to highHash (inclusive) over highHash's selected parent chain
|
||||
SelectedChildIterator(highHash, lowHash *externalapi.DomainHash) (BlockIterator, error)
|
||||
Anticone(blockHash *externalapi.DomainHash) ([]*externalapi.DomainHash, error)
|
||||
BlockWindow(highHash *externalapi.DomainHash, windowSize int) ([]*externalapi.DomainHash, error)
|
||||
BlueWindow(highHash *externalapi.DomainHash, windowSize int) ([]*externalapi.DomainHash, error)
|
||||
NewDownHeap() BlockHeap
|
||||
NewUpHeap() BlockHeap
|
||||
CalculateChainPath(
|
||||
|
||||
17
domain/consensus/model/readonlyutxoset.go
Normal file
17
domain/consensus/model/readonlyutxoset.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package model
|
||||
|
||||
import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
|
||||
// ReadOnlyUTXOSet represents a UTXOSet that can only be read from
|
||||
type ReadOnlyUTXOSet interface {
|
||||
Iterator() ReadOnlyUTXOSetIterator
|
||||
Entry(outpoint *externalapi.DomainOutpoint) externalapi.UTXOEntry
|
||||
}
|
||||
|
||||
// ReadOnlyUTXOSetIterator is an iterator over all entries in a
|
||||
// ReadOnlyUTXOSet
|
||||
type ReadOnlyUTXOSetIterator interface {
|
||||
First() bool
|
||||
Next() bool
|
||||
Get() (outpoint *externalapi.DomainOutpoint, utxoEntry externalapi.UTXOEntry, err error)
|
||||
}
|
||||
@@ -12,7 +12,7 @@ type TestBlockBuilder interface {
|
||||
// BuildBlockWithParents builds a block with provided parents, coinbaseData and transactions,
|
||||
// and returns the block together with its past UTXO-diff from the virtual.
|
||||
BuildBlockWithParents(parentHashes []*externalapi.DomainHash, coinbaseData *externalapi.DomainCoinbaseData,
|
||||
transactions []*externalapi.DomainTransaction) (*externalapi.DomainBlock, externalapi.UTXODiff, error)
|
||||
transactions []*externalapi.DomainTransaction) (*externalapi.DomainBlock, model.UTXODiff, error)
|
||||
|
||||
BuildUTXOInvalidHeader(parentHashes []*externalapi.DomainHash) (externalapi.BlockHeader, error)
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ type TestConsensus interface {
|
||||
Database() database.Database
|
||||
|
||||
BuildBlockWithParents(parentHashes []*externalapi.DomainHash, coinbaseData *externalapi.DomainCoinbaseData,
|
||||
transactions []*externalapi.DomainTransaction) (*externalapi.DomainBlock, externalapi.UTXODiff, error)
|
||||
transactions []*externalapi.DomainTransaction) (*externalapi.DomainBlock, model.UTXODiff, error)
|
||||
|
||||
BuildHeaderWithParents(parentHashes []*externalapi.DomainHash) (externalapi.BlockHeader, error)
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package externalapi
|
||||
package model
|
||||
|
||||
import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
|
||||
// UTXOCollection represents a collection of UTXO entries, indexed by their outpoint
|
||||
type UTXOCollection interface {
|
||||
Iterator() ReadOnlyUTXOSetIterator
|
||||
Get(outpoint *DomainOutpoint) (UTXOEntry, bool)
|
||||
Contains(outpoint *DomainOutpoint) bool
|
||||
Get(outpoint *externalapi.DomainOutpoint) (externalapi.UTXOEntry, bool)
|
||||
Contains(outpoint *externalapi.DomainOutpoint) bool
|
||||
Len() int
|
||||
}
|
||||
|
||||
@@ -27,5 +29,5 @@ type MutableUTXODiff interface {
|
||||
ToRemove() UTXOCollection
|
||||
|
||||
WithDiffInPlace(other UTXODiff) error
|
||||
AddTransaction(transaction *DomainTransaction, blockBlueScore uint64) error
|
||||
AddTransaction(transaction *externalapi.DomainTransaction, blockBlueScore uint64) error
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func cleanBlockPrefilledFields(block *externalapi.DomainBlock) {
|
||||
// and returns the block together with its past UTXO-diff from the virtual.
|
||||
func (bb *testBlockBuilder) BuildBlockWithParents(parentHashes []*externalapi.DomainHash,
|
||||
coinbaseData *externalapi.DomainCoinbaseData, transactions []*externalapi.DomainTransaction) (
|
||||
*externalapi.DomainBlock, externalapi.UTXODiff, error) {
|
||||
*externalapi.DomainBlock, model.UTXODiff, error) {
|
||||
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "BuildBlockWithParents")
|
||||
defer onEnd()
|
||||
@@ -117,7 +117,7 @@ func (bb *testBlockBuilder) buildHeaderWithParents(parentHashes []*externalapi.D
|
||||
), nil
|
||||
}
|
||||
|
||||
func (bb *testBlockBuilder) buildBlockWithParents(parentHashes []*externalapi.DomainHash, coinbaseData *externalapi.DomainCoinbaseData, transactions []*externalapi.DomainTransaction) (*externalapi.DomainBlock, externalapi.UTXODiff, error) {
|
||||
func (bb *testBlockBuilder) buildBlockWithParents(parentHashes []*externalapi.DomainHash, coinbaseData *externalapi.DomainCoinbaseData, transactions []*externalapi.DomainTransaction) (*externalapi.DomainBlock, model.UTXODiff, error) {
|
||||
|
||||
defer bb.testConsensus.DiscardAllStores()
|
||||
|
||||
|
||||
@@ -83,7 +83,6 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock,
|
||||
}
|
||||
|
||||
var selectedParentChainChanges *externalapi.SelectedChainPath
|
||||
var virtualUTXODiff externalapi.UTXODiff
|
||||
isHeaderOnlyBlock := isHeaderOnlyBlock(block)
|
||||
if !isHeaderOnlyBlock {
|
||||
// There's no need to update the consensus state manager when
|
||||
@@ -91,7 +90,7 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock,
|
||||
// in consensusStateManager.ImportPruningPoint
|
||||
if !isPruningPoint {
|
||||
// Attempt to add the block to the virtual
|
||||
selectedParentChainChanges, virtualUTXODiff, err = bp.consensusStateManager.AddBlock(blockHash)
|
||||
selectedParentChainChanges, err = bp.consensusStateManager.AddBlock(blockHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -144,17 +143,10 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock,
|
||||
return nil, logClosureErr
|
||||
}
|
||||
|
||||
virtualParents, err := bp.dagTopologyManager.Parents(model.VirtualBlockHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bp.blockLogger.LogBlock(block)
|
||||
|
||||
return &externalapi.BlockInsertionResult{
|
||||
VirtualSelectedParentChainChanges: selectedParentChainChanges,
|
||||
VirtualUTXODiff: virtualUTXODiff,
|
||||
VirtualParents: virtualParents,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
package blockvalidator_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/testapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/merkle"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
@@ -89,7 +84,7 @@ func TestChainedTransactions(t *testing.T) {
|
||||
func TestCheckBlockSanity(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
||||
factory := consensus.NewFactory()
|
||||
tc, teardown, err := factory.NewTestConsensus(params, false, "TestCheckBlockSanity")
|
||||
consensus, teardown, err := factory.NewTestConsensus(params, false, "TestCheckBlockSanity")
|
||||
if err != nil {
|
||||
t.Fatalf("Error setting up consensus: %+v", err)
|
||||
}
|
||||
@@ -99,17 +94,17 @@ func TestCheckBlockSanity(t *testing.T) {
|
||||
t.Fatalf("Too few transactions in block, expect at least 3, got %v", len(exampleValidBlock.Transactions))
|
||||
}
|
||||
|
||||
tc.BlockStore().Stage(blockHash, &exampleValidBlock)
|
||||
consensus.BlockStore().Stage(blockHash, &exampleValidBlock)
|
||||
|
||||
err = tc.BlockValidator().ValidateBodyInIsolation(blockHash)
|
||||
err = consensus.BlockValidator().ValidateBodyInIsolation(blockHash)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed validating block in isolation: %v", err)
|
||||
}
|
||||
|
||||
// Test with block with wrong transactions sorting order
|
||||
blockHash = consensushashing.BlockHash(&blockWithWrongTxOrder)
|
||||
tc.BlockStore().Stage(blockHash, &blockWithWrongTxOrder)
|
||||
err = tc.BlockValidator().ValidateBodyInIsolation(blockHash)
|
||||
consensus.BlockStore().Stage(blockHash, &blockWithWrongTxOrder)
|
||||
err = consensus.BlockValidator().ValidateBodyInIsolation(blockHash)
|
||||
if !errors.Is(err, ruleerrors.ErrTransactionsNotSorted) {
|
||||
t.Errorf("CheckBlockSanity: Expected ErrTransactionsNotSorted error, instead got %v", err)
|
||||
}
|
||||
@@ -117,8 +112,8 @@ func TestCheckBlockSanity(t *testing.T) {
|
||||
// Test a block with invalid parents order
|
||||
// We no longer require blocks to have ordered parents
|
||||
blockHash = consensushashing.BlockHash(&unOrderedParentsBlock)
|
||||
tc.BlockStore().Stage(blockHash, &unOrderedParentsBlock)
|
||||
err = tc.BlockValidator().ValidateBodyInIsolation(blockHash)
|
||||
consensus.BlockStore().Stage(blockHash, &unOrderedParentsBlock)
|
||||
err = consensus.BlockValidator().ValidateBodyInIsolation(blockHash)
|
||||
if err != nil {
|
||||
t.Errorf("CheckBlockSanity: Expected block to be be body in isolation valid, got error instead: %v", err)
|
||||
}
|
||||
@@ -1039,309 +1034,3 @@ func TestCheckBlockHashMerkleRoot(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestBlockSize(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
||||
|
||||
factory := consensus.NewFactory()
|
||||
tc, teardown, err := factory.NewTestConsensus(params, false, "TestBlockSize")
|
||||
if err != nil {
|
||||
t.Fatalf("Error setting up tc: %+v", err)
|
||||
}
|
||||
defer teardown(false)
|
||||
|
||||
block, _, err := initBlockWithInvalidBlockSize(params, tc)
|
||||
if err != nil {
|
||||
t.Fatalf("Error BuildBlockWithParents : %+v", err)
|
||||
}
|
||||
blockHash := consensushashing.BlockHash(block)
|
||||
tc.BlockStore().Stage(blockHash, block)
|
||||
|
||||
err = tc.BlockValidator().ValidateBodyInIsolation(blockHash)
|
||||
if err == nil || !errors.Is(err, ruleerrors.ErrBlockSizeTooHigh) {
|
||||
t.Fatalf("ValidateBodyInIsolationTest: TestBlockSize:"+
|
||||
" Unexpected error: Expected to: %v, but got : %v", ruleerrors.ErrBlockSizeTooHigh, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func initBlockWithInvalidBlockSize(params *dagconfig.Params, tc testapi.TestConsensus) (*externalapi.DomainBlock, externalapi.UTXODiff, error) {
|
||||
emptyCoinbase := externalapi.DomainCoinbaseData{
|
||||
ScriptPublicKey: &externalapi.ScriptPublicKey{
|
||||
Script: nil,
|
||||
Version: 0,
|
||||
},
|
||||
}
|
||||
prevOutTxID := &externalapi.DomainTransactionID{}
|
||||
prevOutPoint := externalapi.DomainOutpoint{TransactionID: *prevOutTxID, Index: 1}
|
||||
bigSignatureScript := bytes.Repeat([]byte("01"), 25000)
|
||||
txInput := externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: bigSignatureScript,
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
UTXOEntry: utxo.NewUTXOEntry(
|
||||
100_000_000,
|
||||
&externalapi.ScriptPublicKey{},
|
||||
true,
|
||||
uint64(5)),
|
||||
}
|
||||
tx := &externalapi.DomainTransaction{
|
||||
Version: constants.MaxTransactionVersion,
|
||||
Inputs: []*externalapi.DomainTransactionInput{&txInput},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 3}, Version: 0}}},
|
||||
PayloadHash: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
|
||||
Payload: []byte{0x01},
|
||||
}
|
||||
|
||||
return tc.BuildBlockWithParents([]*externalapi.DomainHash{params.GenesisHash}, &emptyCoinbase, []*externalapi.DomainTransaction{tx})
|
||||
}
|
||||
|
||||
func TestCheckBlockDuplicateTransactions(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
||||
|
||||
factory := consensus.NewFactory()
|
||||
tc, teardown, err := factory.NewTestConsensus(params, false, "TestCheckBlockDuplicateTransactions")
|
||||
if err != nil {
|
||||
t.Fatalf("Error setting up tc: %+v", err)
|
||||
}
|
||||
defer teardown(false)
|
||||
|
||||
block, _, err := initBlockWithDuplicateTransaction(params, tc)
|
||||
if err != nil {
|
||||
t.Fatalf("Error BuildBlockWithParents : %+v", err)
|
||||
}
|
||||
blockHash := consensushashing.BlockHash(block)
|
||||
tc.BlockStore().Stage(blockHash, block)
|
||||
|
||||
err = tc.BlockValidator().ValidateBodyInIsolation(blockHash)
|
||||
if err == nil || !errors.Is(err, ruleerrors.ErrDuplicateTx) {
|
||||
t.Fatalf("ValidateBodyInIsolationTest: TestCheckBlockDuplicateTransactions:"+
|
||||
" Unexpected error: Expected to: %v, but got : %v", ruleerrors.ErrDuplicateTx, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func initBlockWithDuplicateTransaction(params *dagconfig.Params, tc testapi.TestConsensus) (*externalapi.DomainBlock, externalapi.UTXODiff, error) {
|
||||
emptyCoinbase := externalapi.DomainCoinbaseData{
|
||||
ScriptPublicKey: &externalapi.ScriptPublicKey{
|
||||
Script: nil,
|
||||
Version: 0,
|
||||
},
|
||||
}
|
||||
prevOutTxID := &externalapi.DomainTransactionID{}
|
||||
prevOutPoint := externalapi.DomainOutpoint{TransactionID: *prevOutTxID, Index: 1}
|
||||
txInput := externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: bytes.Repeat([]byte("01"), 10),
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
UTXOEntry: utxo.NewUTXOEntry(
|
||||
100_000_000,
|
||||
&externalapi.ScriptPublicKey{},
|
||||
true,
|
||||
uint64(5)),
|
||||
}
|
||||
tx := &externalapi.DomainTransaction{
|
||||
Version: 0,
|
||||
Inputs: []*externalapi.DomainTransactionInput{&txInput},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 3}, Version: 0}}},
|
||||
SubnetworkID: subnetworks.SubnetworkIDNative,
|
||||
}
|
||||
|
||||
return tc.BuildBlockWithParents([]*externalapi.DomainHash{params.GenesisHash}, &emptyCoinbase, []*externalapi.DomainTransaction{tx, tx})
|
||||
}
|
||||
|
||||
func TestCheckBlockContainsOnlyOneCoinbase(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
||||
|
||||
factory := consensus.NewFactory()
|
||||
tc, teardown, err := factory.NewTestConsensus(params, false, "TestCheckBlockContainsOnlyOneCoinbase")
|
||||
if err != nil {
|
||||
t.Fatalf("Error setting up tc: %+v", err)
|
||||
}
|
||||
defer teardown(false)
|
||||
|
||||
block, _, err := initBlockWithMoreThanOneCoinbase(params, tc)
|
||||
if err != nil {
|
||||
t.Fatalf("Error BuildBlockWithParents : %+v", err)
|
||||
}
|
||||
blockHash := consensushashing.BlockHash(block)
|
||||
tc.BlockStore().Stage(blockHash, block)
|
||||
|
||||
err = tc.BlockValidator().ValidateBodyInIsolation(blockHash)
|
||||
if err == nil || !errors.Is(err, ruleerrors.ErrMultipleCoinbases) {
|
||||
t.Fatalf("ValidateBodyInIsolationTest: TestCheckBlockContainsOnlyOneCoinbase:"+
|
||||
" Unexpected error: Expected to: %v, but got : %v", ruleerrors.ErrMultipleCoinbases, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func initBlockWithMoreThanOneCoinbase(params *dagconfig.Params, tc testapi.TestConsensus) (*externalapi.DomainBlock, externalapi.UTXODiff, error) {
|
||||
emptyCoinbase := externalapi.DomainCoinbaseData{
|
||||
ScriptPublicKey: &externalapi.ScriptPublicKey{
|
||||
Script: nil,
|
||||
Version: 0,
|
||||
},
|
||||
}
|
||||
prevOutTxID := &externalapi.DomainTransactionID{}
|
||||
prevOutPoint := externalapi.DomainOutpoint{TransactionID: *prevOutTxID, Index: 1}
|
||||
txInput := externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: bytes.Repeat([]byte("01"), 10),
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
UTXOEntry: utxo.NewUTXOEntry(
|
||||
100_000_000,
|
||||
&externalapi.ScriptPublicKey{},
|
||||
true,
|
||||
uint64(5)),
|
||||
}
|
||||
tx := &externalapi.DomainTransaction{
|
||||
Version: 0,
|
||||
Inputs: []*externalapi.DomainTransactionInput{&txInput},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 3}, Version: 0}}},
|
||||
SubnetworkID: subnetworks.SubnetworkIDCoinbase,
|
||||
}
|
||||
|
||||
return tc.BuildBlockWithParents([]*externalapi.DomainHash{params.GenesisHash}, &emptyCoinbase, []*externalapi.DomainTransaction{tx})
|
||||
}
|
||||
|
||||
func TestCheckBlockDoubleSpends(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
||||
|
||||
factory := consensus.NewFactory()
|
||||
tc, teardown, err := factory.NewTestConsensus(params, false, "TestCheckBlockDoubleSpends")
|
||||
if err != nil {
|
||||
t.Fatalf("Error setting up tc: %+v", err)
|
||||
}
|
||||
defer teardown(false)
|
||||
|
||||
block, _, err := initBlockWithDoubleSpends(params, tc)
|
||||
if err != nil {
|
||||
t.Fatalf("Error BuildBlockWithParents : %+v", err)
|
||||
}
|
||||
blockHash := consensushashing.BlockHash(block)
|
||||
tc.BlockStore().Stage(blockHash, block)
|
||||
|
||||
err = tc.BlockValidator().ValidateBodyInIsolation(blockHash)
|
||||
if err == nil || !errors.Is(err, ruleerrors.ErrDoubleSpendInSameBlock) {
|
||||
t.Fatalf("ValidateBodyInIsolationTest: TestCheckBlockDoubleSpends:"+
|
||||
" Unexpected error: Expected to: %v, but got : %v", ruleerrors.ErrDoubleSpendInSameBlock, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func initBlockWithDoubleSpends(params *dagconfig.Params, tc testapi.TestConsensus) (*externalapi.DomainBlock, externalapi.UTXODiff, error) {
|
||||
emptyCoinbase := externalapi.DomainCoinbaseData{
|
||||
ScriptPublicKey: &externalapi.ScriptPublicKey{
|
||||
Script: nil,
|
||||
Version: 0,
|
||||
},
|
||||
}
|
||||
prevOutTxID := &externalapi.DomainTransactionID{}
|
||||
prevOutPoint := externalapi.DomainOutpoint{TransactionID: *prevOutTxID, Index: 1}
|
||||
txInput := externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: bytes.Repeat([]byte("01"), 10),
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
UTXOEntry: utxo.NewUTXOEntry(
|
||||
100_000_000,
|
||||
&externalapi.ScriptPublicKey{},
|
||||
true,
|
||||
uint64(5)),
|
||||
}
|
||||
tx := &externalapi.DomainTransaction{
|
||||
Version: 0,
|
||||
Inputs: []*externalapi.DomainTransactionInput{&txInput},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 3}, Version: 0}}},
|
||||
SubnetworkID: subnetworks.SubnetworkIDNative,
|
||||
}
|
||||
txInputSameOutpoint := externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: bytes.Repeat([]byte("02"), 10),
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
UTXOEntry: utxo.NewUTXOEntry(
|
||||
100_000_000,
|
||||
&externalapi.ScriptPublicKey{},
|
||||
true,
|
||||
uint64(4)),
|
||||
}
|
||||
txSameOutpoint := &externalapi.DomainTransaction{
|
||||
Version: 0,
|
||||
Inputs: []*externalapi.DomainTransactionInput{&txInputSameOutpoint},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 3}, Version: 0}}},
|
||||
SubnetworkID: subnetworks.SubnetworkIDNative,
|
||||
}
|
||||
|
||||
return tc.BuildBlockWithParents([]*externalapi.DomainHash{params.GenesisHash},
|
||||
&emptyCoinbase, []*externalapi.DomainTransaction{tx, txSameOutpoint})
|
||||
}
|
||||
|
||||
func TestCheckFirstBlockTransactionIsCoinbase(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
||||
|
||||
factory := consensus.NewFactory()
|
||||
tc, teardown, err := factory.NewTestConsensus(params, false, "TestCheckFirstBlockTransactionIsCoinbase")
|
||||
if err != nil {
|
||||
t.Fatalf("Error setting up tc: %+v", err)
|
||||
}
|
||||
defer teardown(false)
|
||||
|
||||
block := initBlockWithFirstTransactionDifferentThanCoinbase(params)
|
||||
blockHash := consensushashing.BlockHash(block)
|
||||
tc.BlockStore().Stage(blockHash, block)
|
||||
|
||||
err = tc.BlockValidator().ValidateBodyInIsolation(blockHash)
|
||||
if err == nil || !errors.Is(err, ruleerrors.ErrFirstTxNotCoinbase) {
|
||||
t.Fatalf("ValidateBodyInIsolationTest: TestCheckFirstBlockTransactionIsCoinbase:"+
|
||||
" Unexpected error: Expected to: %v, but got : %v", ruleerrors.ErrFirstTxNotCoinbase, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func initBlockWithFirstTransactionDifferentThanCoinbase(params *dagconfig.Params) *externalapi.DomainBlock {
|
||||
prevOutTxID := &externalapi.DomainTransactionID{}
|
||||
prevOutPoint := externalapi.DomainOutpoint{TransactionID: *prevOutTxID, Index: 1}
|
||||
txInput := externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: bytes.Repeat([]byte("01"), 10),
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
}
|
||||
tx := &externalapi.DomainTransaction{
|
||||
Version: 0,
|
||||
Inputs: []*externalapi.DomainTransactionInput{&txInput},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 2}, Version: 0}}, {uint64(0xFFFF),
|
||||
&externalapi.ScriptPublicKey{Script: []byte{1, 3}, Version: 0}}},
|
||||
SubnetworkID: subnetworks.SubnetworkIDNative,
|
||||
}
|
||||
|
||||
return &externalapi.DomainBlock{
|
||||
Header: blockheader.NewImmutableBlockHeader(
|
||||
constants.MaxBlockVersion,
|
||||
[]*externalapi.DomainHash{params.GenesisHash},
|
||||
merkle.CalculateHashMerkleRoot([]*externalapi.DomainTransaction{tx}),
|
||||
&externalapi.DomainHash{},
|
||||
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
|
||||
0x80, 0xf7, 0x00, 0xe3, 0x16, 0x3d, 0x04, 0x95,
|
||||
0x5b, 0x7e, 0xaf, 0x84, 0x7e, 0x1b, 0x6b, 0x06,
|
||||
0x4e, 0x06, 0xba, 0x64, 0xd7, 0x61, 0xda, 0x25,
|
||||
0x1a, 0x0e, 0x21, 0xd4, 0x64, 0x49, 0x02, 0xa2,
|
||||
}),
|
||||
0x5cd18053000,
|
||||
0x207fffff,
|
||||
0x1),
|
||||
Transactions: []*externalapi.DomainTransaction{tx},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package blockvalidator_test
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/pow"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/blockheader"
|
||||
@@ -13,8 +12,8 @@ import (
|
||||
"math"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
@@ -242,60 +241,3 @@ func TestCheckPruningPointViolation(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestValidateDifficulty verifies that in case of a block with an unexpected difficulty,
|
||||
// an appropriate error message (ErrUnexpectedDifficulty) will be returned on the
|
||||
// function ValidatePruningPointViolationAndProofOfWorkAndDifficulty. The required difficulty is
|
||||
// "calculated" by the function (dm *mocDifficultyManager) RequiredDifficulty ,
|
||||
// where mocDifficultyManager is special implementation of the type DifficultyManager for this test (defined below).
|
||||
func TestValidateDifficulty(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
||||
|
||||
factory := consensus.NewFactory()
|
||||
mocDifficulty := &mocDifficultyManager{}
|
||||
factory.SetTestDifficultyManager(func(model.DBReader, model.GHOSTDAGManager, model.GHOSTDAGDataStore,
|
||||
model.BlockHeaderStore, model.DAGTopologyManager, model.DAGTraversalManager, *big.Int, int, bool, time.Duration,
|
||||
*externalapi.DomainHash) model.DifficultyManager {
|
||||
return mocDifficulty
|
||||
})
|
||||
genesisDifficulty := params.GenesisBlock.Header.Bits()
|
||||
mocDifficulty.testDifficulty = genesisDifficulty
|
||||
mocDifficulty.testGenesisBits = genesisDifficulty
|
||||
tc, teardown, err := factory.NewTestConsensus(params, false, "TestValidateDifficulty")
|
||||
if err != nil {
|
||||
t.Fatalf("Error setting up consensus: %+v", err)
|
||||
}
|
||||
defer teardown(false)
|
||||
|
||||
emptyCoinbase := externalapi.DomainCoinbaseData{
|
||||
ScriptPublicKey: &externalapi.ScriptPublicKey{
|
||||
Script: nil,
|
||||
Version: 0,
|
||||
},
|
||||
}
|
||||
block, _, err := tc.BuildBlockWithParents([]*externalapi.DomainHash{params.GenesisHash}, &emptyCoinbase, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("TestValidateDifficulty: Failed build block with parents: %v.", err)
|
||||
}
|
||||
blockHash := consensushashing.BlockHash(block)
|
||||
tc.BlockStore().Stage(blockHash, block)
|
||||
tc.BlockHeaderStore().Stage(blockHash, block.Header)
|
||||
wrongTestDifficulty := mocDifficulty.testDifficulty + uint32(5)
|
||||
mocDifficulty.testDifficulty = wrongTestDifficulty
|
||||
|
||||
err = tc.BlockValidator().ValidatePruningPointViolationAndProofOfWorkAndDifficulty(blockHash)
|
||||
if err == nil || !errors.Is(err, ruleerrors.ErrUnexpectedDifficulty) {
|
||||
t.Fatalf("Expected block to be invalid with err: %v, instead found: %v", ruleerrors.ErrUnexpectedDifficulty, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type mocDifficultyManager struct {
|
||||
testDifficulty uint32
|
||||
testGenesisBits uint32
|
||||
}
|
||||
|
||||
// RequiredDifficulty returns the difficulty required for the test
|
||||
func (dm *mocDifficultyManager) RequiredDifficulty(*externalapi.DomainHash) (uint32, error) {
|
||||
return dm.testDifficulty, nil
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@ import (
|
||||
// AddBlock submits the given block to be added to the
|
||||
// current virtual. This process may result in a new virtual block
|
||||
// getting created
|
||||
func (csm *consensusStateManager) AddBlock(blockHash *externalapi.DomainHash) (*externalapi.SelectedChainPath, externalapi.UTXODiff, error) {
|
||||
func (csm *consensusStateManager) AddBlock(blockHash *externalapi.DomainHash) (*externalapi.SelectedChainPath, error) {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "csm.AddBlock")
|
||||
defer onEnd()
|
||||
|
||||
log.Debugf("Resolving whether the block %s is the next virtual selected parent", blockHash)
|
||||
isCandidateToBeNextVirtualSelectedParent, err := csm.isCandidateToBeNextVirtualSelectedParent(blockHash)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if isCandidateToBeNextVirtualSelectedParent {
|
||||
@@ -27,7 +27,7 @@ func (csm *consensusStateManager) AddBlock(blockHash *externalapi.DomainHash) (*
|
||||
"finality", blockHash)
|
||||
isViolatingFinality, shouldNotify, err := csm.isViolatingFinality(blockHash)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if shouldNotify {
|
||||
@@ -39,7 +39,7 @@ func (csm *consensusStateManager) AddBlock(blockHash *externalapi.DomainHash) (*
|
||||
log.Debugf("Block %s doesn't violate finality. Resolving its block status", blockHash)
|
||||
blockStatus, err := csm.resolveBlockStatus(blockHash)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugf("Block %s resolved to status `%s`", blockHash, blockStatus)
|
||||
@@ -52,17 +52,17 @@ func (csm *consensusStateManager) AddBlock(blockHash *externalapi.DomainHash) (*
|
||||
log.Debugf("Adding block %s to the DAG tips", blockHash)
|
||||
newTips, err := csm.addTip(blockHash)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
log.Debugf("After adding %s, the amount of new tips are %d", blockHash, len(newTips))
|
||||
|
||||
log.Debugf("Updating the virtual with the new tips")
|
||||
selectedParentChainChanges, virtualUTXODiff, err := csm.updateVirtual(blockHash, newTips)
|
||||
selectedParentChainChanges, err := csm.updateVirtual(blockHash, newTips)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return selectedParentChainChanges, virtualUTXODiff, nil
|
||||
return selectedParentChainChanges, nil
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) isCandidateToBeNextVirtualSelectedParent(blockHash *externalapi.DomainHash) (bool, error) {
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
package consensusstatemanager_test
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
|
||||
"testing"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/testutils"
|
||||
"github.com/kaspanet/kaspad/domain/dagconfig"
|
||||
)
|
||||
|
||||
func TestVirtualDiff(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
||||
factory := consensus.NewFactory()
|
||||
tc, teardown, err := factory.NewTestConsensus(params, false, "TestVirtualDiff")
|
||||
if err != nil {
|
||||
t.Fatalf("Error setting up tc: %+v", err)
|
||||
}
|
||||
defer teardown(false)
|
||||
|
||||
// Add block A over the genesis
|
||||
blockHash, blockInsertionResult, err := tc.AddBlock([]*externalapi.DomainHash{params.GenesisHash}, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Error adding block A: %+v", err)
|
||||
}
|
||||
|
||||
block, err := tc.BlockStore().Block(tc.DatabaseContext(), blockHash)
|
||||
if err != nil {
|
||||
t.Fatalf("Block: %+v", err)
|
||||
}
|
||||
|
||||
virtualUTXODiff := blockInsertionResult.VirtualUTXODiff
|
||||
if virtualUTXODiff.ToRemove().Len() != 0 {
|
||||
t.Fatalf("Unexpected length %d for virtualUTXODiff.ToRemove()", virtualUTXODiff.ToRemove().Len())
|
||||
}
|
||||
|
||||
if virtualUTXODiff.ToAdd().Len() != 1 {
|
||||
t.Fatalf("Unexpected length %d for virtualUTXODiff.ToAdd()", virtualUTXODiff.ToAdd().Len())
|
||||
}
|
||||
|
||||
iterator := virtualUTXODiff.ToAdd().Iterator()
|
||||
iterator.First()
|
||||
|
||||
outpoint, entry, err := iterator.Get()
|
||||
if err != nil {
|
||||
t.Fatalf("TestVirtualDiff: %+v", err)
|
||||
}
|
||||
|
||||
if !outpoint.Equal(&externalapi.DomainOutpoint{
|
||||
TransactionID: *consensushashing.TransactionID(block.Transactions[0]),
|
||||
Index: 0,
|
||||
}) {
|
||||
t.Fatalf("Unexpected outpoint %s", outpoint)
|
||||
}
|
||||
|
||||
if !entry.Equal(utxo.NewUTXOEntry(
|
||||
block.Transactions[0].Outputs[0].Value,
|
||||
block.Transactions[0].Outputs[0].ScriptPublicKey,
|
||||
true,
|
||||
2, //Expected virtual blue score
|
||||
)) {
|
||||
t.Fatalf("Unexpected entry %s", entry)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func (csm *consensusStateManager) CalculatePastUTXOAndAcceptanceData(blockHash *externalapi.DomainHash) (
|
||||
externalapi.UTXODiff, externalapi.AcceptanceData, model.Multiset, error) {
|
||||
model.UTXODiff, externalapi.AcceptanceData, model.Multiset, error) {
|
||||
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "CalculatePastUTXOAndAcceptanceData")
|
||||
defer onEnd()
|
||||
@@ -58,7 +58,7 @@ func (csm *consensusStateManager) CalculatePastUTXOAndAcceptanceData(blockHash *
|
||||
return utxoDiff.ToImmutable(), acceptanceData, multiset, nil
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) restorePastUTXO(blockHash *externalapi.DomainHash) (externalapi.MutableUTXODiff, error) {
|
||||
func (csm *consensusStateManager) restorePastUTXO(blockHash *externalapi.DomainHash) (model.MutableUTXODiff, error) {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "restorePastUTXO")
|
||||
defer onEnd()
|
||||
|
||||
@@ -67,7 +67,7 @@ func (csm *consensusStateManager) restorePastUTXO(blockHash *externalapi.DomainH
|
||||
var err error
|
||||
|
||||
log.Debugf("Collecting UTXO diffs for block %s", blockHash)
|
||||
var utxoDiffs []externalapi.UTXODiff
|
||||
var utxoDiffs []model.UTXODiff
|
||||
nextBlockHash := blockHash
|
||||
for {
|
||||
log.Debugf("Collecting UTXO diff for block %s", nextBlockHash)
|
||||
@@ -115,8 +115,8 @@ func (csm *consensusStateManager) restorePastUTXO(blockHash *externalapi.DomainH
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) applyMergeSetBlocks(blockHash *externalapi.DomainHash,
|
||||
selectedParentPastUTXODiff externalapi.MutableUTXODiff, ghostdagData *model.BlockGHOSTDAGData) (
|
||||
externalapi.AcceptanceData, externalapi.MutableUTXODiff, error) {
|
||||
selectedParentPastUTXODiff model.MutableUTXODiff, ghostdagData *model.BlockGHOSTDAGData) (
|
||||
externalapi.AcceptanceData, model.MutableUTXODiff, error) {
|
||||
|
||||
log.Debugf("applyMergeSetBlocks start for block %s", blockHash)
|
||||
defer log.Debugf("applyMergeSetBlocks end for block %s", blockHash)
|
||||
@@ -185,7 +185,7 @@ func (csm *consensusStateManager) applyMergeSetBlocks(blockHash *externalapi.Dom
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) maybeAcceptTransaction(transaction *externalapi.DomainTransaction,
|
||||
blockHash *externalapi.DomainHash, isSelectedParent bool, accumulatedUTXODiff externalapi.MutableUTXODiff,
|
||||
blockHash *externalapi.DomainHash, isSelectedParent bool, accumulatedUTXODiff model.MutableUTXODiff,
|
||||
accumulatedMassBefore uint64, selectedParentPastMedianTime int64, blockBlueScore uint64) (
|
||||
isAccepted bool, accumulatedMassAfter uint64, err error) {
|
||||
|
||||
@@ -267,9 +267,9 @@ func (csm *consensusStateManager) checkTransactionMass(
|
||||
return true, accumulatedMassAfter
|
||||
}
|
||||
|
||||
// RestorePastUTXOSetIterator restores the given block's UTXOSet iterator, and returns it as a externalapi.ReadOnlyUTXOSetIterator
|
||||
// RestorePastUTXOSetIterator restores the given block's UTXOSet iterator, and returns it as a model.ReadOnlyUTXOSetIterator
|
||||
func (csm *consensusStateManager) RestorePastUTXOSetIterator(blockHash *externalapi.DomainHash) (
|
||||
externalapi.ReadOnlyUTXOSetIterator, error) {
|
||||
model.ReadOnlyUTXOSetIterator, error) {
|
||||
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "RestorePastUTXOSetIterator")
|
||||
defer onEnd()
|
||||
|
||||
@@ -77,8 +77,14 @@ func (csm *consensusStateManager) importPruningPoint(newPruningPoint *externalap
|
||||
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")
|
||||
csm.stageDiff(newPruningPointHash, utxo.NewUTXODiff(), nil)
|
||||
err = csm.stageDiff(newPruningPointHash, utxo.NewUTXODiff(), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("Staging the new pruning point %s", newPruningPointHash)
|
||||
csm.pruningStore.StagePruningPoint(newPruningPointHash)
|
||||
|
||||
@@ -38,7 +38,8 @@ func (csm *consensusStateManager) calculateMultiset(
|
||||
isCoinbase := i == 0
|
||||
log.Tracef("Is transaction %s a coinbase transaction: %t", transactionID, isCoinbase)
|
||||
|
||||
err := addTransactionToMultiset(ms, transaction, blockGHOSTDAGData.BlueScore(), isCoinbase)
|
||||
var err error
|
||||
err = addTransactionToMultiset(ms, transaction, blockGHOSTDAGData.BlueScore(), isCoinbase)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
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"
|
||||
@@ -15,7 +16,7 @@ func (csm *consensusStateManager) PopulateTransactionWithUTXOEntries(transaction
|
||||
// from the virtual's UTXO set combined with the provided utxoDiff.
|
||||
// If utxoDiff == nil UTXO entries are taken from the virtual's UTXO set only
|
||||
func (csm *consensusStateManager) populateTransactionWithUTXOEntriesFromVirtualOrDiff(
|
||||
transaction *externalapi.DomainTransaction, utxoDiff externalapi.UTXODiff) error {
|
||||
transaction *externalapi.DomainTransaction, utxoDiff model.UTXODiff) error {
|
||||
|
||||
transactionID := consensushashing.TransactionID(transaction)
|
||||
log.Tracef("populateTransactionWithUTXOEntriesFromVirtualOrDiff start for transaction %s", transactionID)
|
||||
@@ -76,7 +77,7 @@ func (csm *consensusStateManager) populateTransactionWithUTXOEntriesFromVirtualO
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) populateTransactionWithUTXOEntriesFromUTXOSet(
|
||||
pruningPoint *externalapi.DomainBlock, iterator externalapi.ReadOnlyUTXOSetIterator) error {
|
||||
pruningPoint *externalapi.DomainBlock, iterator model.ReadOnlyUTXOSetIterator) error {
|
||||
|
||||
// Collect the required outpoints from the block
|
||||
outpointsForPopulation := make(map[externalapi.DomainOutpoint]interface{})
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
package consensusstatemanager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"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/infrastructure/logger"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (csm *consensusStateManager) resolveBlockStatus(blockHash *externalapi.DomainHash) (externalapi.BlockStatus, error) {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, fmt.Sprintf("resolveBlockStatus for %s", blockHash))
|
||||
defer onEnd()
|
||||
log.Debugf("resolveBlockStatus start for block %s", blockHash)
|
||||
defer log.Debugf("resolveBlockStatus end for block %s", blockHash)
|
||||
|
||||
log.Debugf("Getting a list of all blocks in the selected "+
|
||||
"parent chain of %s that have no yet resolved their status", blockHash)
|
||||
@@ -59,8 +56,7 @@ func (csm *consensusStateManager) resolveBlockStatus(blockHash *externalapi.Doma
|
||||
|
||||
csm.blockStatusStore.Stage(unverifiedBlockHash, blockStatus)
|
||||
selectedParentStatus = blockStatus
|
||||
log.Debugf("Block %s status resolved to `%s`, finished %d/%d of unverified blocks",
|
||||
unverifiedBlockHash, blockStatus, len(unverifiedBlocks)-i, len(unverifiedBlocks))
|
||||
log.Debugf("Block %s status resolved to `%s`, finished %d/%d of unverified blocks", unverifiedBlockHash, blockStatus, len(unverifiedBlocks)-i, len(unverifiedBlocks))
|
||||
}
|
||||
|
||||
return blockStatus, nil
|
||||
@@ -125,8 +121,8 @@ func (csm *consensusStateManager) getUnverifiedChainBlocks(
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) resolveSingleBlockStatus(blockHash *externalapi.DomainHash) (externalapi.BlockStatus, error) {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, fmt.Sprintf("resolveSingleBlockStatus for %s", blockHash))
|
||||
defer onEnd()
|
||||
log.Debugf("resolveSingleBlockStatus start for block %s", blockHash)
|
||||
defer log.Debugf("resolveSingleBlockStatus end for block %s", blockHash)
|
||||
|
||||
log.Tracef("Calculating pastUTXO and acceptance data and multiset for block %s", blockHash)
|
||||
pastUTXODiff, acceptanceData, multiset, err := csm.CalculatePastUTXOAndAcceptanceData(blockHash)
|
||||
@@ -156,63 +152,72 @@ func (csm *consensusStateManager) resolveSingleBlockStatus(blockHash *externalap
|
||||
log.Tracef("Staging the multiset of block %s", blockHash)
|
||||
csm.multisetStore.Stage(blockHash, multiset)
|
||||
|
||||
if csm.genesisHash.Equal(blockHash) {
|
||||
log.Tracef("Staging the utxoDiff of genesis")
|
||||
csm.stageDiff(blockHash, pastUTXODiff, nil)
|
||||
return externalapi.StatusUTXOValid, nil
|
||||
}
|
||||
|
||||
oldSelectedTip, err := csm.selectedTip()
|
||||
log.Tracef("Staging the utxoDiff of block %s", blockHash)
|
||||
err = csm.stageDiff(blockHash, pastUTXODiff, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
isNewSelectedTip, err := csm.isNewSelectedTip(blockHash, oldSelectedTip)
|
||||
log.Tracef("Remove block ancestors from virtual diff parents and assign %s as their diff child", blockHash)
|
||||
err = csm.removeAncestorsFromVirtualDiffParentsAndAssignDiffChild(blockHash, pastUTXODiff)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
oldSelectedTipUTXOSet, err := csm.restorePastUTXO(oldSelectedTip)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if isNewSelectedTip {
|
||||
log.Debugf("Block %s is the new SelectedTip, therefore setting it as old selectedTip's diffChild", blockHash)
|
||||
oldSelectedTipUTXOSet, err := pastUTXODiff.DiffFrom(oldSelectedTipUTXOSet.ToImmutable())
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
csm.stageDiff(oldSelectedTip, oldSelectedTipUTXOSet, blockHash)
|
||||
|
||||
log.Tracef("Staging the utxoDiff of block %s", blockHash)
|
||||
csm.stageDiff(blockHash, pastUTXODiff, nil)
|
||||
} else {
|
||||
log.Debugf("Block %s is not the new SelectedTip, therefore setting old selectedTip as it's diffChild", blockHash)
|
||||
pastUTXODiff, err = oldSelectedTipUTXOSet.DiffFrom(pastUTXODiff)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
log.Tracef("Staging the utxoDiff of block %s", blockHash)
|
||||
csm.stageDiff(blockHash, pastUTXODiff, oldSelectedTip)
|
||||
}
|
||||
|
||||
return externalapi.StatusUTXOValid, nil
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) isNewSelectedTip(blockHash, oldSelectedTip *externalapi.DomainHash) (bool, error) {
|
||||
newSelectedTip, err := csm.ghostdagManager.ChooseSelectedParent(blockHash, oldSelectedTip)
|
||||
if err != nil {
|
||||
return false, err
|
||||
func (csm *consensusStateManager) removeAncestorsFromVirtualDiffParentsAndAssignDiffChild(
|
||||
blockHash *externalapi.DomainHash, pastUTXODiff model.UTXODiff) error {
|
||||
|
||||
log.Tracef("removeAncestorsFromVirtualDiffParentsAndAssignDiffChild start for block %s", blockHash)
|
||||
defer log.Tracef("removeAncestorsFromVirtualDiffParentsAndAssignDiffChild end for block %s", blockHash)
|
||||
|
||||
if blockHash.Equal(csm.genesisHash) {
|
||||
log.Tracef("Genesis block doesn't have ancestors to remove from the virtual diff parents")
|
||||
return nil
|
||||
}
|
||||
|
||||
return blockHash.Equal(newSelectedTip), nil
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) selectedTip() (*externalapi.DomainHash, error) {
|
||||
virtualGHOSTDAGData, err := csm.ghostdagDataStore.Get(csm.databaseContext, model.VirtualBlockHash)
|
||||
virtualDiffParents, err := csm.consensusStateStore.VirtualDiffParents(csm.databaseContext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
return virtualGHOSTDAGData.SelectedParent(), nil
|
||||
for _, virtualDiffParent := range virtualDiffParents {
|
||||
if virtualDiffParent.Equal(blockHash) {
|
||||
log.Tracef("Skipping updating virtual diff parent %s "+
|
||||
"because it was updated before.", virtualDiffParent)
|
||||
continue
|
||||
}
|
||||
|
||||
isAncestorOfBlock, err := csm.dagTopologyManager.IsAncestorOf(virtualDiffParent, blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !isAncestorOfBlock {
|
||||
log.Tracef("Skipping block %s because it's not an "+
|
||||
"ancestor of %s", virtualDiffParent, blockHash)
|
||||
continue
|
||||
}
|
||||
|
||||
// parents that didn't have a utxo-diff child until now were actually virtual's diffParents.
|
||||
// Update them to have the new block as their utxo-diff child
|
||||
log.Tracef("Updating %s to be the diff child of %s", blockHash, virtualDiffParent)
|
||||
currentDiff, err := csm.utxoDiffStore.UTXODiff(csm.databaseContext, virtualDiffParent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newDiff, err := pastUTXODiff.DiffFrom(currentDiff)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = csm.stageDiff(virtualDiffParent, newDiff, blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
func (csm *consensusStateManager) updateVirtual(newBlockHash *externalapi.DomainHash,
|
||||
tips []*externalapi.DomainHash) (*externalapi.SelectedChainPath, externalapi.UTXODiff, error) {
|
||||
tips []*externalapi.DomainHash) (*externalapi.SelectedChainPath, error) {
|
||||
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "updateVirtual")
|
||||
defer onEnd()
|
||||
@@ -19,7 +19,7 @@ func (csm *consensusStateManager) updateVirtual(newBlockHash *externalapi.Domain
|
||||
if !newBlockHash.Equal(csm.genesisHash) {
|
||||
oldVirtualGHOSTDAGData, err := csm.ghostdagDataStore.Get(csm.databaseContext, model.VirtualBlockHash)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
oldVirtualSelectedParent = oldVirtualGHOSTDAGData.SelectedParent()
|
||||
}
|
||||
@@ -27,25 +27,25 @@ func (csm *consensusStateManager) updateVirtual(newBlockHash *externalapi.Domain
|
||||
log.Debugf("Picking virtual parents from tips len: %d", len(tips))
|
||||
virtualParents, err := csm.pickVirtualParents(tips)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
log.Debugf("Picked virtual parents: %s", virtualParents)
|
||||
|
||||
err = csm.dagTopologyManager.SetParents(model.VirtualBlockHash, virtualParents)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
log.Debugf("Set new parents for the virtual block hash")
|
||||
|
||||
err = csm.ghostdagManager.GHOSTDAG(model.VirtualBlockHash)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugf("Calculating past UTXO, acceptance data, and multiset for the new virtual block")
|
||||
virtualUTXODiff, virtualAcceptanceData, virtualMultiset, err := csm.CalculatePastUTXOAndAcceptanceData(model.VirtualBlockHash)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
log.Debugf("Calculated the past UTXO of the new virtual. "+
|
||||
"Diff toAdd length: %d, toRemove length: %d",
|
||||
@@ -60,10 +60,10 @@ func (csm *consensusStateManager) updateVirtual(newBlockHash *externalapi.Domain
|
||||
log.Debugf("Staging new UTXO diff for the virtual block")
|
||||
csm.consensusStateStore.StageVirtualUTXODiff(virtualUTXODiff)
|
||||
|
||||
log.Debugf("Updating the selected tip's utxo-diff after adding %s to the DAG", newBlockHash)
|
||||
err = csm.updateSelectedTipUTXODiff(virtualUTXODiff)
|
||||
log.Debugf("Updating the virtual diff parents after adding %s to the DAG", newBlockHash)
|
||||
err = csm.updateVirtualDiffParents(virtualUTXODiff)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugf("Calculating selected parent chain changes")
|
||||
@@ -71,42 +71,47 @@ func (csm *consensusStateManager) updateVirtual(newBlockHash *externalapi.Domain
|
||||
if !newBlockHash.Equal(csm.genesisHash) {
|
||||
newVirtualGHOSTDAGData, err := csm.ghostdagDataStore.Get(csm.databaseContext, model.VirtualBlockHash)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
newVirtualSelectedParent := newVirtualGHOSTDAGData.SelectedParent()
|
||||
selectedParentChainChanges, err = csm.dagTraversalManager.
|
||||
CalculateChainPath(oldVirtualSelectedParent, newVirtualSelectedParent)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
log.Debugf("Selected parent chain changes: %d blocks were removed and %d blocks were added",
|
||||
len(selectedParentChainChanges.Removed), len(selectedParentChainChanges.Added))
|
||||
}
|
||||
|
||||
return selectedParentChainChanges, virtualUTXODiff, nil
|
||||
return selectedParentChainChanges, nil
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) updateSelectedTipUTXODiff(virtualUTXODiff externalapi.UTXODiff) error {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "updateSelectedTipUTXODiff")
|
||||
defer onEnd()
|
||||
func (csm *consensusStateManager) updateVirtualDiffParents(virtualUTXODiff model.UTXODiff) error {
|
||||
log.Debugf("updateVirtualDiffParents start")
|
||||
defer log.Debugf("updateVirtualDiffParents end")
|
||||
|
||||
selectedTip, err := csm.selectedTip()
|
||||
virtualDiffParents, err := csm.consensusStateStore.VirtualDiffParents(csm.databaseContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("Calculating new UTXO diff for virtual diff parent %s", selectedTip)
|
||||
selectedTipUTXODiff, err := csm.utxoDiffStore.UTXODiff(csm.databaseContext, selectedTip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newDiff, err := virtualUTXODiff.DiffFrom(selectedTipUTXODiff)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, virtualDiffParent := range virtualDiffParents {
|
||||
log.Debugf("Calculating new UTXO diff for virtual diff parent %s", virtualDiffParent)
|
||||
virtualDiffParentUTXODiff, err := csm.utxoDiffStore.UTXODiff(csm.databaseContext, virtualDiffParent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newDiff, err := virtualUTXODiff.DiffFrom(virtualDiffParentUTXODiff)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("Staging new UTXO diff for virtual diff parent %s", selectedTip)
|
||||
csm.stageDiff(selectedTip, newDiff, nil)
|
||||
log.Debugf("Staging new UTXO diff for virtual diff parent %s", virtualDiffParent)
|
||||
err = csm.stageDiff(virtualDiffParent, newDiff, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,15 +1,83 @@
|
||||
package consensusstatemanager
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (csm *consensusStateManager) stageDiff(blockHash *externalapi.DomainHash,
|
||||
utxoDiff externalapi.UTXODiff, utxoDiffChild *externalapi.DomainHash) {
|
||||
utxoDiff model.UTXODiff, utxoDiffChild *externalapi.DomainHash) error {
|
||||
|
||||
log.Debugf("stageDiff start for block %s", blockHash)
|
||||
defer log.Debugf("stageDiff end for block %s", blockHash)
|
||||
|
||||
log.Debugf("Staging block %s as the diff child of %s", utxoDiffChild, blockHash)
|
||||
csm.utxoDiffStore.Stage(blockHash, utxoDiff, utxoDiffChild)
|
||||
|
||||
if utxoDiffChild == nil {
|
||||
log.Debugf("Adding block %s to the virtual diff parents", blockHash)
|
||||
return csm.addToVirtualDiffParents(blockHash)
|
||||
}
|
||||
|
||||
log.Debugf("Removing block %s from the virtual diff parents", blockHash)
|
||||
return csm.removeFromVirtualDiffParents(blockHash)
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) addToVirtualDiffParents(blockHash *externalapi.DomainHash) error {
|
||||
log.Debugf("addToVirtualDiffParents start for block %s", blockHash)
|
||||
defer log.Debugf("addToVirtualDiffParents end for block %s", blockHash)
|
||||
|
||||
var oldVirtualDiffParents []*externalapi.DomainHash
|
||||
if !blockHash.Equal(csm.genesisHash) {
|
||||
var err error
|
||||
oldVirtualDiffParents, err = csm.consensusStateStore.VirtualDiffParents(csm.databaseContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
isInVirtualDiffParents := false
|
||||
for _, diffParent := range oldVirtualDiffParents {
|
||||
if diffParent.Equal(blockHash) {
|
||||
isInVirtualDiffParents = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if isInVirtualDiffParents {
|
||||
log.Debugf("Block %s is already a virtual diff parent, so there's no need to add it", blockHash)
|
||||
return nil
|
||||
}
|
||||
|
||||
newVirtualDiffParents := append([]*externalapi.DomainHash{blockHash}, oldVirtualDiffParents...)
|
||||
log.Debugf("Staging virtual diff parents after adding %s to it", blockHash)
|
||||
csm.consensusStateStore.StageVirtualDiffParents(newVirtualDiffParents)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) removeFromVirtualDiffParents(blockHash *externalapi.DomainHash) error {
|
||||
log.Debugf("removeFromVirtualDiffParents start for block %s", blockHash)
|
||||
defer log.Debugf("removeFromVirtualDiffParents end for block %s", blockHash)
|
||||
|
||||
oldVirtualDiffParents, err := csm.consensusStateStore.VirtualDiffParents(csm.databaseContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newVirtualDiffParents := make([]*externalapi.DomainHash, 0, len(oldVirtualDiffParents)-1)
|
||||
for _, diffParent := range oldVirtualDiffParents {
|
||||
if !diffParent.Equal(blockHash) {
|
||||
newVirtualDiffParents = append(newVirtualDiffParents, diffParent)
|
||||
}
|
||||
}
|
||||
|
||||
if len(newVirtualDiffParents) != len(oldVirtualDiffParents)-1 {
|
||||
return errors.Errorf("expected to remove one member from virtual diff parents and "+
|
||||
"have a length of %d but got length of %d", len(oldVirtualDiffParents)-1, len(newVirtualDiffParents))
|
||||
}
|
||||
|
||||
log.Debugf("Staging virtual diff parents after removing %s from it", blockHash)
|
||||
csm.consensusStateStore.StageVirtualDiffParents(newVirtualDiffParents)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
func (csm *consensusStateManager) verifyUTXO(block *externalapi.DomainBlock, blockHash *externalapi.DomainHash,
|
||||
pastUTXODiff externalapi.UTXODiff, acceptanceData externalapi.AcceptanceData, multiset model.Multiset) error {
|
||||
pastUTXODiff model.UTXODiff, acceptanceData externalapi.AcceptanceData, multiset model.Multiset) error {
|
||||
|
||||
log.Debugf("verifyUTXO start for block %s", blockHash)
|
||||
defer log.Debugf("verifyUTXO end for block %s", blockHash)
|
||||
@@ -55,7 +55,7 @@ func (csm *consensusStateManager) verifyUTXO(block *externalapi.DomainBlock, blo
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) validateBlockTransactionsAgainstPastUTXO(block *externalapi.DomainBlock,
|
||||
pastUTXODiff externalapi.UTXODiff) error {
|
||||
pastUTXODiff model.UTXODiff) error {
|
||||
|
||||
blockHash := consensushashing.BlockHash(block)
|
||||
log.Tracef("validateBlockTransactionsAgainstPastUTXO start for block %s", blockHash)
|
||||
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
// BlockWindow returns a blockWindow of the given size that contains the
|
||||
// blocks in the past of startindNode, the sorting is unspecified.
|
||||
// If the number of blocks in the past of startingNode is less then windowSize,
|
||||
// blueBlockWindow returns a blockWindow of the given size that contains the
|
||||
// blues in the past of startindNode, the sorting is unspecified.
|
||||
// If the number of blues in the past of startingNode is less then windowSize,
|
||||
// the window will be padded by genesis blocks to achieve a size of windowSize.
|
||||
func (dtm *dagTraversalManager) BlockWindow(startingBlock *externalapi.DomainHash, windowSize int) ([]*externalapi.DomainHash, error) {
|
||||
func (dtm *dagTraversalManager) BlueWindow(startingBlock *externalapi.DomainHash, windowSize int) ([]*externalapi.DomainHash, error) {
|
||||
currentHash := startingBlock
|
||||
currentGHOSTDAGData, err := dtm.ghostdagDataStore.Get(dtm.databaseContext, currentHash)
|
||||
if err != nil {
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func TestBlockWindow(t *testing.T) {
|
||||
func TestBlueBlockWindow(t *testing.T) {
|
||||
tests := map[string][]*struct {
|
||||
parents []string
|
||||
id string //id is a virtual entity that is used only for tests so we can define relations between blocks without knowing their hash
|
||||
@@ -311,7 +311,7 @@ func TestBlockWindow(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
||||
params.K = 1
|
||||
factory := consensus.NewFactory()
|
||||
tc, tearDown, err := factory.NewTestConsensus(params, false, "TestBlockWindow")
|
||||
tc, tearDown, err := factory.NewTestConsensus(params, false, "TestBlueBlockWindow")
|
||||
if err != nil {
|
||||
t.Fatalf("NewTestConsensus: %s", err)
|
||||
}
|
||||
@@ -340,9 +340,9 @@ func TestBlockWindow(t *testing.T) {
|
||||
blockByIDMap[blockData.id] = block
|
||||
idByBlockMap[*block] = blockData.id
|
||||
|
||||
window, err := tc.DAGTraversalManager().BlockWindow(block, windowSize)
|
||||
window, err := tc.DAGTraversalManager().BlueWindow(block, windowSize)
|
||||
if err != nil {
|
||||
t.Fatalf("BlockWindow: %s", err)
|
||||
t.Fatalf("BlueWindow: %s", err)
|
||||
}
|
||||
sort.Sort(testutils.NewTestGhostDAGSorter(window, tc, t))
|
||||
if err := checkWindowIDs(window, blockData.expectedWindowWithGenesisPadding, idByBlockMap); err != nil {
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package difficultymanager
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/big"
|
||||
"sort"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/util/difficulty"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
"math/big"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type difficultyBlock struct {
|
||||
@@ -28,13 +27,13 @@ func (dm *difficultyManager) getDifficultyBlock(blockHash *externalapi.DomainHas
|
||||
}, nil
|
||||
}
|
||||
|
||||
// blockWindow returns a blockWindow of the given size that contains the
|
||||
// blocks in the past of startindNode, the sorting is unspecified.
|
||||
// If the number of blocks in the past of startingNode is less then windowSize,
|
||||
// blueBlockWindow returns a blockWindow of the given size that contains the
|
||||
// blues in the past of startindNode, the sorting is unspecified.
|
||||
// If the number of blues in the past of startingNode is less then windowSize,
|
||||
// the window will be padded by genesis blocks to achieve a size of windowSize.
|
||||
func (dm *difficultyManager) blockWindow(startingNode *externalapi.DomainHash, windowSize int) (blockWindow, error) {
|
||||
func (dm *difficultyManager) blueBlockWindow(startingNode *externalapi.DomainHash, windowSize int) (blockWindow, error) {
|
||||
window := make(blockWindow, 0, windowSize)
|
||||
windowHashes, err := dm.dagTraversalManager.BlockWindow(startingNode, windowSize)
|
||||
windowHashes, err := dm.dagTraversalManager.BlueWindow(startingNode, windowSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package difficultymanager
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/util/difficulty"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
"github.com/kaspanet/kaspad/util/difficulty"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
@@ -89,7 +88,7 @@ func (dm *difficultyManager) RequiredDifficulty(blockHash *externalapi.DomainHas
|
||||
}
|
||||
|
||||
// Fetch window of dag.difficultyAdjustmentWindowSize + 1 so we can have dag.difficultyAdjustmentWindowSize block intervals
|
||||
targetsWindow, err := dm.blockWindow(bluestParent, dm.difficultyAdjustmentWindowSize+1)
|
||||
targetsWindow, err := dm.blueBlockWindow(bluestParent, dm.difficultyAdjustmentWindowSize+1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ func (pmtm *pastMedianTimeManager) PastMedianTime(blockHash *externalapi.DomainH
|
||||
return header.TimeInMilliseconds(), nil
|
||||
}
|
||||
|
||||
window, err := pmtm.dagTraversalManager.BlockWindow(selectedParentHash, 2*pmtm.timestampDeviationTolerance-1)
|
||||
window, err := pmtm.dagTraversalManager.BlueWindow(selectedParentHash, 2*pmtm.timestampDeviationTolerance-1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -256,6 +256,11 @@ func (pm *pruningManager) deletePastBlocks(pruningPoint *externalapi.DomainHash)
|
||||
return err
|
||||
}
|
||||
|
||||
err = pm.pruneVirtualDiffParents(pruningPoint, virtualParents)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -287,6 +292,26 @@ func (pm *pruningManager) deleteBlocksDownward(queue model.BlockHeap) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pm *pruningManager) pruneVirtualDiffParents(pruningPoint *externalapi.DomainHash, virtualParents []*externalapi.DomainHash) error {
|
||||
virtualDiffParents, err := pm.consensusStateStore.VirtualDiffParents(pm.databaseContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
validVirtualDiffParents := make([]*externalapi.DomainHash, 0, len(virtualParents))
|
||||
for _, parent := range virtualDiffParents {
|
||||
isInPruningFutureOrInVirtualPast, err := pm.isInPruningFutureOrInVirtualPast(parent, pruningPoint, virtualParents)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if isInPruningFutureOrInVirtualPast {
|
||||
validVirtualDiffParents = append(validVirtualDiffParents, parent)
|
||||
}
|
||||
}
|
||||
pm.consensusStateStore.StageVirtualDiffParents(validVirtualDiffParents)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pm *pruningManager) pruneTips(pruningPoint *externalapi.DomainHash, virtualParents []*externalapi.DomainHash) (
|
||||
prunedTips []*externalapi.DomainHash, err error) {
|
||||
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
package transactionvalidator_test
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/go-secp256k1"
|
||||
"github.com/kaspanet/kaspad/domain/consensus"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/testutils"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
|
||||
"math/big"
|
||||
|
||||
"testing"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
|
||||
"github.com/kaspanet/kaspad/domain/dagconfig"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type mocPastMedianTimeManager struct {
|
||||
pastMedianTimeForTest int64
|
||||
}
|
||||
|
||||
// PastMedianTime returns the past median time for the test.
|
||||
func (mdf *mocPastMedianTimeManager) PastMedianTime(*externalapi.DomainHash) (int64, error) {
|
||||
return mdf.pastMedianTimeForTest, nil
|
||||
}
|
||||
|
||||
func TestValidateTransactionInContextAndPopulateMassAndFee(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
||||
|
||||
factory := consensus.NewFactory()
|
||||
pastMedianManager := &mocPastMedianTimeManager{}
|
||||
factory.SetTestPastMedianTimeManager(func(int, model.DBReader, model.DAGTraversalManager, model.BlockHeaderStore,
|
||||
model.GHOSTDAGDataStore) model.PastMedianTimeManager {
|
||||
return pastMedianManager
|
||||
})
|
||||
tc, tearDown, err := factory.NewTestConsensus(params, false,
|
||||
"TestValidateTransactionInContextAndPopulateMassAndFee")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed create a NewTestConsensus: %s", err)
|
||||
}
|
||||
defer tearDown(false)
|
||||
|
||||
pastMedianManager.pastMedianTimeForTest = 1
|
||||
privateKey, err := secp256k1.GeneratePrivateKey()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to generate a private key: %v", err)
|
||||
}
|
||||
publicKey, err := privateKey.SchnorrPublicKey()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to generate a public key: %v", err)
|
||||
}
|
||||
publicKeySerialized, err := publicKey.Serialize()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to serialize public key: %v", err)
|
||||
}
|
||||
addr, err := util.NewAddressPubKeyHashFromPublicKey(publicKeySerialized[:], params.Prefix)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to generate p2pkh address: %v", err)
|
||||
}
|
||||
scriptPublicKey, err := txscript.PayToAddrScript(addr)
|
||||
if err != nil {
|
||||
t.Fatalf("PayToAddrScript: unexpected error: %v", err)
|
||||
}
|
||||
prevOutTxID := &externalapi.DomainTransactionID{}
|
||||
prevOutPoint := externalapi.DomainOutpoint{TransactionID: *prevOutTxID, Index: 1}
|
||||
|
||||
txInput := externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: []byte{},
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
UTXOEntry: utxo.NewUTXOEntry(
|
||||
100_000_000, // 1 KAS
|
||||
scriptPublicKey,
|
||||
true,
|
||||
uint64(5)),
|
||||
}
|
||||
txInputWithMaxSequence := externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: []byte{},
|
||||
Sequence: constants.SequenceLockTimeIsSeconds,
|
||||
UTXOEntry: utxo.NewUTXOEntry(
|
||||
100000000, // 1 KAS
|
||||
scriptPublicKey,
|
||||
true,
|
||||
uint64(5)),
|
||||
}
|
||||
txInputWithLargeAmount := externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: prevOutPoint,
|
||||
SignatureScript: []byte{},
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
UTXOEntry: utxo.NewUTXOEntry(
|
||||
constants.MaxSompi,
|
||||
scriptPublicKey,
|
||||
true,
|
||||
uint64(5)),
|
||||
}
|
||||
|
||||
txOut := externalapi.DomainTransactionOutput{
|
||||
Value: 100000000, // 1 KAS
|
||||
ScriptPublicKey: scriptPublicKey,
|
||||
}
|
||||
txOutBigValue := externalapi.DomainTransactionOutput{
|
||||
Value: 200_000_000, // 2 KAS
|
||||
ScriptPublicKey: scriptPublicKey,
|
||||
}
|
||||
|
||||
validTx := externalapi.DomainTransaction{
|
||||
Version: constants.MaxTransactionVersion,
|
||||
Inputs: []*externalapi.DomainTransactionInput{&txInputWithMaxSequence},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{&txOut},
|
||||
SubnetworkID: subnetworks.SubnetworkIDRegistry,
|
||||
Gas: 0,
|
||||
LockTime: 0}
|
||||
txWithImmatureCoinbase := externalapi.DomainTransaction{
|
||||
Version: constants.MaxTransactionVersion,
|
||||
Inputs: []*externalapi.DomainTransactionInput{&txInput},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{&txOut},
|
||||
SubnetworkID: subnetworks.SubnetworkIDRegistry,
|
||||
Gas: 0,
|
||||
LockTime: 0}
|
||||
txWithLargeAmount := externalapi.DomainTransaction{
|
||||
Version: constants.MaxTransactionVersion,
|
||||
Inputs: []*externalapi.DomainTransactionInput{&txInput, &txInputWithLargeAmount},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{&txOut},
|
||||
SubnetworkID: subnetworks.SubnetworkIDRegistry,
|
||||
Gas: 0,
|
||||
LockTime: 0}
|
||||
txWithBigValue := externalapi.DomainTransaction{
|
||||
Version: constants.MaxTransactionVersion,
|
||||
Inputs: []*externalapi.DomainTransactionInput{&txInput},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{&txOutBigValue},
|
||||
SubnetworkID: subnetworks.SubnetworkIDRegistry,
|
||||
Gas: 0,
|
||||
LockTime: 0}
|
||||
txWithInvalidSignature := externalapi.DomainTransaction{
|
||||
Version: constants.MaxTransactionVersion,
|
||||
Inputs: []*externalapi.DomainTransactionInput{&txInput},
|
||||
Outputs: []*externalapi.DomainTransactionOutput{&txOut},
|
||||
SubnetworkID: subnetworks.SubnetworkIDRegistry,
|
||||
Gas: 0,
|
||||
LockTime: 0}
|
||||
|
||||
for i, input := range validTx.Inputs {
|
||||
signatureScript, err := txscript.SignatureScript(&validTx, i, scriptPublicKey, txscript.SigHashAll, privateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create a sigScript: %v", err)
|
||||
}
|
||||
input.SignatureScript = signatureScript
|
||||
}
|
||||
|
||||
povBlockHash := externalapi.NewDomainHashFromByteArray(&[32]byte{0x01})
|
||||
genesisHash := params.GenesisHash
|
||||
tc.GHOSTDAGDataStore().Stage(model.VirtualBlockHash, model.NewBlockGHOSTDAGData(
|
||||
params.BlockCoinbaseMaturity+txInput.UTXOEntry.BlockBlueScore(),
|
||||
new(big.Int),
|
||||
genesisHash,
|
||||
make([]*externalapi.DomainHash, 1000),
|
||||
make([]*externalapi.DomainHash, 1),
|
||||
nil))
|
||||
tc.GHOSTDAGDataStore().Stage(povBlockHash, model.NewBlockGHOSTDAGData(
|
||||
10,
|
||||
new(big.Int),
|
||||
genesisHash,
|
||||
make([]*externalapi.DomainHash, 1000),
|
||||
make([]*externalapi.DomainHash, 1),
|
||||
nil))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
tx *externalapi.DomainTransaction
|
||||
povBlockHash *externalapi.DomainHash
|
||||
selectedParentMedianTime int64
|
||||
isValid bool
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
name: "Valid transaction",
|
||||
tx: &validTx,
|
||||
povBlockHash: model.VirtualBlockHash,
|
||||
selectedParentMedianTime: 1,
|
||||
isValid: true,
|
||||
expectedError: nil,
|
||||
},
|
||||
{ // The calculated block coinbase maturity is smaller than the minimum expected blockCoinbaseMaturity.
|
||||
// The povBlockHash blue score is 10 and the UTXO blue score is 5, hence the The subtraction between
|
||||
// them will yield a smaller result than the required CoinbaseMaturity (currently set to 100).
|
||||
name: "checkTransactionCoinbaseMaturity",
|
||||
tx: &txWithImmatureCoinbase,
|
||||
povBlockHash: povBlockHash,
|
||||
selectedParentMedianTime: 1,
|
||||
isValid: false,
|
||||
expectedError: ruleerrors.ErrImmatureSpend,
|
||||
},
|
||||
{ // The total inputs amount is bigger than the allowed maximum (constants.MaxSompi)
|
||||
name: "checkTransactionInputAmounts",
|
||||
tx: &txWithLargeAmount,
|
||||
povBlockHash: model.VirtualBlockHash,
|
||||
selectedParentMedianTime: 1,
|
||||
isValid: false,
|
||||
expectedError: ruleerrors.ErrBadTxOutValue,
|
||||
},
|
||||
{ // The total SompiIn (sum of inputs amount) is smaller than the total SompiOut (sum of outputs value) and hence invalid.
|
||||
name: "checkTransactionOutputAmounts",
|
||||
tx: &txWithBigValue,
|
||||
povBlockHash: model.VirtualBlockHash,
|
||||
selectedParentMedianTime: 1,
|
||||
isValid: false,
|
||||
expectedError: ruleerrors.ErrSpendTooHigh,
|
||||
},
|
||||
{ // the selectedParentMedianTime is negative and hence invalid.
|
||||
name: "checkTransactionSequenceLock",
|
||||
tx: &validTx,
|
||||
povBlockHash: model.VirtualBlockHash,
|
||||
selectedParentMedianTime: -1,
|
||||
isValid: false,
|
||||
expectedError: ruleerrors.ErrUnfinalizedTx,
|
||||
},
|
||||
{ // The SignatureScript (in the txInput) is empty and hence invalid.
|
||||
name: "checkTransactionScripts",
|
||||
tx: &txWithInvalidSignature,
|
||||
povBlockHash: model.VirtualBlockHash,
|
||||
selectedParentMedianTime: 1,
|
||||
isValid: false,
|
||||
expectedError: ruleerrors.ErrScriptValidation,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
err := tc.TransactionValidator().ValidateTransactionInContextAndPopulateMassAndFee(test.tx,
|
||||
test.povBlockHash, test.selectedParentMedianTime)
|
||||
|
||||
if test.isValid {
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error on TestValidateTransactionInContextAndPopulateMassAndFee"+
|
||||
" on test %v: %v", test.name, err)
|
||||
}
|
||||
} else {
|
||||
if err == nil || !errors.Is(err, test.expectedError) {
|
||||
t.Fatalf("TestValidateTransactionInContextAndPopulateMassAndFee: test %v:"+
|
||||
" Unexpected error: Expected to: %v, but got : %v", test.name, test.expectedError, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -192,8 +192,6 @@ var (
|
||||
|
||||
// ErrPrunedBlock indicates that the block currently being validated had already been pruned.
|
||||
ErrPrunedBlock = newRuleError("ErrPrunedBlock")
|
||||
|
||||
ErrGetVirtualUTXOsWrongVirtualParents = newRuleError("ErrGetVirtualUTXOsWrongVirtualParents")
|
||||
)
|
||||
|
||||
// RuleError identifies a rule violation. It is used to indicate that
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/testapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
@@ -29,7 +30,7 @@ func (tc *testConsensus) DAGParams() *dagconfig.Params {
|
||||
|
||||
func (tc *testConsensus) BuildBlockWithParents(parentHashes []*externalapi.DomainHash,
|
||||
coinbaseData *externalapi.DomainCoinbaseData, transactions []*externalapi.DomainTransaction) (
|
||||
*externalapi.DomainBlock, externalapi.UTXODiff, error) {
|
||||
*externalapi.DomainBlock, model.UTXODiff, error) {
|
||||
|
||||
// Require write lock because BuildBlockWithParents stages temporary data
|
||||
tc.lock.Lock()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package utxo
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -11,7 +11,7 @@ type immutableUTXODiff struct {
|
||||
isInvalidated bool
|
||||
}
|
||||
|
||||
func (iud *immutableUTXODiff) ToAdd() externalapi.UTXOCollection {
|
||||
func (iud *immutableUTXODiff) ToAdd() model.UTXOCollection {
|
||||
if iud.isInvalidated {
|
||||
panic("Attempt to read from an invalidated UTXODiff")
|
||||
}
|
||||
@@ -19,7 +19,7 @@ func (iud *immutableUTXODiff) ToAdd() externalapi.UTXOCollection {
|
||||
return iud.mutableUTXODiff.ToAdd()
|
||||
}
|
||||
|
||||
func (iud *immutableUTXODiff) ToRemove() externalapi.UTXOCollection {
|
||||
func (iud *immutableUTXODiff) ToRemove() model.UTXOCollection {
|
||||
if iud.isInvalidated {
|
||||
panic("Attempt to read from an invalidated UTXODiff")
|
||||
}
|
||||
@@ -27,7 +27,7 @@ func (iud *immutableUTXODiff) ToRemove() externalapi.UTXOCollection {
|
||||
return iud.mutableUTXODiff.ToRemove()
|
||||
}
|
||||
|
||||
func (iud *immutableUTXODiff) WithDiff(other externalapi.UTXODiff) (externalapi.UTXODiff, error) {
|
||||
func (iud *immutableUTXODiff) WithDiff(other model.UTXODiff) (model.UTXODiff, error) {
|
||||
if iud.isInvalidated {
|
||||
panic("Attempt to read from an invalidated UTXODiff")
|
||||
}
|
||||
@@ -35,7 +35,7 @@ func (iud *immutableUTXODiff) WithDiff(other externalapi.UTXODiff) (externalapi.
|
||||
return iud.mutableUTXODiff.WithDiff(other)
|
||||
}
|
||||
|
||||
func (iud *immutableUTXODiff) DiffFrom(other externalapi.UTXODiff) (externalapi.UTXODiff, error) {
|
||||
func (iud *immutableUTXODiff) DiffFrom(other model.UTXODiff) (model.UTXODiff, error) {
|
||||
if iud.isInvalidated {
|
||||
panic("Attempt to read from an invalidated UTXODiff")
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func (iud *immutableUTXODiff) DiffFrom(other externalapi.UTXODiff) (externalapi.
|
||||
}
|
||||
|
||||
// NewUTXODiff creates an empty UTXODiff
|
||||
func NewUTXODiff() externalapi.UTXODiff {
|
||||
func NewUTXODiff() model.UTXODiff {
|
||||
return newUTXODiff()
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ func newUTXODiff() *immutableUTXODiff {
|
||||
}
|
||||
|
||||
// NewUTXODiffFromCollections returns a new UTXODiff with the given toAdd and toRemove collections
|
||||
func NewUTXODiffFromCollections(toAdd, toRemove externalapi.UTXOCollection) (externalapi.UTXODiff, error) {
|
||||
func NewUTXODiffFromCollections(toAdd, toRemove model.UTXOCollection) (model.UTXODiff, error) {
|
||||
add, ok := toAdd.(utxoCollection)
|
||||
if !ok {
|
||||
return nil, errors.New("toAdd is not of type utxoCollection")
|
||||
@@ -73,7 +73,7 @@ func NewUTXODiffFromCollections(toAdd, toRemove externalapi.UTXOCollection) (ext
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (iud *immutableUTXODiff) CloneMutable() externalapi.MutableUTXODiff {
|
||||
func (iud *immutableUTXODiff) CloneMutable() model.MutableUTXODiff {
|
||||
return iud.cloneMutable()
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package utxo
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
||||
@@ -17,7 +18,7 @@ type mutableUTXODiff struct {
|
||||
}
|
||||
|
||||
// NewMutableUTXODiff creates an empty mutable UTXO-Diff
|
||||
func NewMutableUTXODiff() externalapi.MutableUTXODiff {
|
||||
func NewMutableUTXODiff() model.MutableUTXODiff {
|
||||
return newMutableUTXODiff()
|
||||
}
|
||||
|
||||
@@ -28,7 +29,7 @@ func newMutableUTXODiff() *mutableUTXODiff {
|
||||
}
|
||||
}
|
||||
|
||||
func (mud *mutableUTXODiff) ToImmutable() externalapi.UTXODiff {
|
||||
func (mud *mutableUTXODiff) ToImmutable() model.UTXODiff {
|
||||
immutableReference := &immutableUTXODiff{
|
||||
mutableUTXODiff: mud,
|
||||
isInvalidated: false,
|
||||
@@ -47,7 +48,7 @@ func (mud *mutableUTXODiff) invalidateImmutableReferences() {
|
||||
mud.immutableReferences = nil
|
||||
}
|
||||
|
||||
func (mud *mutableUTXODiff) WithDiff(other externalapi.UTXODiff) (externalapi.UTXODiff, error) {
|
||||
func (mud *mutableUTXODiff) WithDiff(other model.UTXODiff) (model.UTXODiff, error) {
|
||||
o, ok := other.(*immutableUTXODiff)
|
||||
if !ok {
|
||||
return nil, errors.New("other is not of type *immutableUTXODiff")
|
||||
@@ -61,7 +62,7 @@ func (mud *mutableUTXODiff) WithDiff(other externalapi.UTXODiff) (externalapi.UT
|
||||
return result.ToImmutable(), nil
|
||||
}
|
||||
|
||||
func (mud *mutableUTXODiff) WithDiffInPlace(other externalapi.UTXODiff) error {
|
||||
func (mud *mutableUTXODiff) WithDiffInPlace(other model.UTXODiff) error {
|
||||
o, ok := other.(*immutableUTXODiff)
|
||||
if !ok {
|
||||
return errors.New("other is not of type *immutableUTXODiff")
|
||||
@@ -72,7 +73,7 @@ func (mud *mutableUTXODiff) WithDiffInPlace(other externalapi.UTXODiff) error {
|
||||
return withDiffInPlace(mud, o.mutableUTXODiff)
|
||||
}
|
||||
|
||||
func (mud *mutableUTXODiff) DiffFrom(other externalapi.UTXODiff) (externalapi.UTXODiff, error) {
|
||||
func (mud *mutableUTXODiff) DiffFrom(other model.UTXODiff) (model.UTXODiff, error) {
|
||||
o, ok := other.(*immutableUTXODiff)
|
||||
if !ok {
|
||||
return nil, errors.New("other is not of type *immutableUTXODiff")
|
||||
@@ -86,11 +87,11 @@ func (mud *mutableUTXODiff) DiffFrom(other externalapi.UTXODiff) (externalapi.UT
|
||||
return result.ToImmutable(), nil
|
||||
}
|
||||
|
||||
func (mud *mutableUTXODiff) ToAdd() externalapi.UTXOCollection {
|
||||
func (mud *mutableUTXODiff) ToAdd() model.UTXOCollection {
|
||||
return mud.toAdd
|
||||
}
|
||||
|
||||
func (mud *mutableUTXODiff) ToRemove() externalapi.UTXOCollection {
|
||||
func (mud *mutableUTXODiff) ToRemove() model.UTXOCollection {
|
||||
return mud.toRemove
|
||||
}
|
||||
func (mud *mutableUTXODiff) AddTransaction(transaction *externalapi.DomainTransaction, blockBlueScore uint64) error {
|
||||
|
||||
@@ -5,13 +5,15 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
type utxoCollection map[externalapi.DomainOutpoint]externalapi.UTXOEntry
|
||||
|
||||
// NewUTXOCollection creates a UTXO-Collection from the given map from outpoint to UTXOEntry
|
||||
func NewUTXOCollection(utxoMap map[externalapi.DomainOutpoint]externalapi.UTXOEntry) externalapi.UTXOCollection {
|
||||
func NewUTXOCollection(utxoMap map[externalapi.DomainOutpoint]externalapi.UTXOEntry) model.UTXOCollection {
|
||||
return utxoCollection(utxoMap)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package utxo
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -15,7 +16,7 @@ type utxoCollectionIterator struct {
|
||||
pairs []utxoOutpointEntryPair
|
||||
}
|
||||
|
||||
func (uc utxoCollection) Iterator() externalapi.ReadOnlyUTXOSetIterator {
|
||||
func (uc utxoCollection) Iterator() model.ReadOnlyUTXOSetIterator {
|
||||
pairs := make([]utxoOutpointEntryPair, len(uc))
|
||||
i := 0
|
||||
for outpoint, entry := range uc {
|
||||
@@ -43,7 +44,7 @@ func (uci *utxoCollectionIterator) Get() (outpoint *externalapi.DomainOutpoint,
|
||||
return &pair.outpoint, pair.entry, nil
|
||||
}
|
||||
|
||||
func (uci *utxoCollectionIterator) WithDiff(diff externalapi.UTXODiff) (externalapi.ReadOnlyUTXOSetIterator, error) {
|
||||
func (uci *utxoCollectionIterator) WithDiff(diff model.UTXODiff) (model.ReadOnlyUTXOSetIterator, error) {
|
||||
d, ok := diff.(*immutableUTXODiff)
|
||||
if !ok {
|
||||
return nil, errors.New("diff is not of type *immutableUTXODiff")
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
package utxo
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type readOnlyUTXOIteratorWithDiff struct {
|
||||
baseIterator externalapi.ReadOnlyUTXOSetIterator
|
||||
baseIterator model.ReadOnlyUTXOSetIterator
|
||||
diff *immutableUTXODiff
|
||||
|
||||
currentOutpoint *externalapi.DomainOutpoint
|
||||
currentUTXOEntry externalapi.UTXOEntry
|
||||
currentErr error
|
||||
|
||||
toAddIterator externalapi.ReadOnlyUTXOSetIterator
|
||||
toAddIterator model.ReadOnlyUTXOSetIterator
|
||||
}
|
||||
|
||||
// IteratorWithDiff applies a UTXODiff to given utxo iterator
|
||||
func IteratorWithDiff(iterator externalapi.ReadOnlyUTXOSetIterator, diff externalapi.UTXODiff) (externalapi.ReadOnlyUTXOSetIterator, error) {
|
||||
func IteratorWithDiff(iterator model.ReadOnlyUTXOSetIterator, diff model.UTXODiff) (model.ReadOnlyUTXOSetIterator, error) {
|
||||
d, ok := diff.(*immutableUTXODiff)
|
||||
if !ok {
|
||||
return nil, errors.New("diff is not of type *immutableUTXODiff")
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package blocktemplatebuilder
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/util/difficulty"
|
||||
"math"
|
||||
"sort"
|
||||
|
||||
"github.com/kaspanet/kaspad/util/difficulty"
|
||||
|
||||
consensusexternalapi "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
|
||||
@@ -139,13 +138,7 @@ func (btb *blockTemplateBuilder) GetBlockTemplate(coinbaseData *consensusexterna
|
||||
for _, tx := range invalidTxsErr.InvalidTransactions {
|
||||
invalidTxs = append(invalidTxs, tx.Transaction)
|
||||
}
|
||||
err = btb.mempool.RemoveTransactions(invalidTxs)
|
||||
if err != nil {
|
||||
// mempool.RemoveTransactions might return errors in situations that are perfectly fine in this context.
|
||||
// TODO: Once the mempool invariants are clear, this should be converted back `return nil, err`:
|
||||
// https://github.com/kaspanet/kaspad/issues/1553
|
||||
log.Criticalf("Error from mempool.RemoveTransactions: %+v", err)
|
||||
}
|
||||
btb.mempool.RemoveTransactions(invalidTxs)
|
||||
// We can call this recursively without worry because this should almost never happen
|
||||
return btb.GetBlockTemplate(coinbaseData)
|
||||
}
|
||||
|
||||
@@ -373,11 +373,11 @@ func (mp *mempool) haveTransaction(txID *consensusexternalapi.DomainTransactionI
|
||||
return mp.isTransactionInPool(txID) || mp.isOrphanInPool(txID)
|
||||
}
|
||||
|
||||
// removeTransactionsFromPool removes given transactions from the mempool, and move their chained mempool
|
||||
// transactions (if any) to the main pool.
|
||||
// removeBlockTransactionsFromPool removes the transactions that are found in the block
|
||||
// from the mempool, and move their chained mempool transactions (if any) to the main pool.
|
||||
//
|
||||
// This function MUST be called with the mempool lock held (for writes).
|
||||
func (mp *mempool) removeTransactionsFromPool(txs []*consensusexternalapi.DomainTransaction) error {
|
||||
func (mp *mempool) removeBlockTransactionsFromPool(txs []*consensusexternalapi.DomainTransaction) error {
|
||||
for _, tx := range txs[transactionhelper.CoinbaseTransactionIndex+1:] {
|
||||
txID := consensushashing.TransactionID(tx)
|
||||
|
||||
@@ -966,7 +966,7 @@ func (mp *mempool) HandleNewBlockTransactions(txs []*consensusexternalapi.Domain
|
||||
// no longer an orphan. Transactions which depend on a confirmed
|
||||
// transaction are NOT removed recursively because they are still
|
||||
// valid.
|
||||
err := mp.removeTransactionsFromPool(txs)
|
||||
err := mp.removeBlockTransactionsFromPool(txs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Failed removing txs from pool")
|
||||
}
|
||||
@@ -986,10 +986,16 @@ func (mp *mempool) HandleNewBlockTransactions(txs []*consensusexternalapi.Domain
|
||||
return acceptedTxs, nil
|
||||
}
|
||||
|
||||
func (mp *mempool) RemoveTransactions(txs []*consensusexternalapi.DomainTransaction) error {
|
||||
func (mp *mempool) RemoveTransactions(txs []*consensusexternalapi.DomainTransaction) {
|
||||
// Protect concurrent access.
|
||||
mp.mtx.Lock()
|
||||
defer mp.mtx.Unlock()
|
||||
|
||||
return mp.removeTransactionsFromPool(txs)
|
||||
for _, tx := range txs {
|
||||
err := mp.removeDoubleSpends(tx)
|
||||
if err != nil {
|
||||
log.Infof("Failed removing tx from mempool: %s, '%s'", consensushashing.TransactionID(tx), err)
|
||||
}
|
||||
mp.removeOrphan(tx, true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ type Mempool interface {
|
||||
HandleNewBlockTransactions(txs []*consensusexternalapi.DomainTransaction) ([]*consensusexternalapi.DomainTransaction, error)
|
||||
BlockCandidateTransactions() []*consensusexternalapi.DomainTransaction
|
||||
ValidateAndInsertTransaction(transaction *consensusexternalapi.DomainTransaction, allowOrphan bool) error
|
||||
RemoveTransactions(txs []*consensusexternalapi.DomainTransaction) error
|
||||
RemoveTransactions(txs []*consensusexternalapi.DomainTransaction)
|
||||
GetTransaction(transactionID *consensusexternalapi.DomainTransactionID) (*consensusexternalapi.DomainTransaction, bool)
|
||||
AllTransactions() []*consensusexternalapi.DomainTransaction
|
||||
}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
package utxoindex
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/database/serialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"io"
|
||||
)
|
||||
|
||||
func serializeOutpoint(outpoint *externalapi.DomainOutpoint) ([]byte, error) {
|
||||
dbOutpoint := serialization.DomainOutpointToDbOutpoint(outpoint)
|
||||
return proto.Marshal(dbOutpoint)
|
||||
}
|
||||
|
||||
func deserializeOutpoint(serializedOutpoint []byte) (*externalapi.DomainOutpoint, error) {
|
||||
var dbOutpoint serialization.DbOutpoint
|
||||
err := proto.Unmarshal(serializedOutpoint, &dbOutpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return serialization.DbOutpointToDomainOutpoint(&dbOutpoint)
|
||||
}
|
||||
|
||||
func serializeUTXOEntry(utxoEntry externalapi.UTXOEntry) ([]byte, error) {
|
||||
dbUTXOEntry := serialization.UTXOEntryToDBUTXOEntry(utxoEntry)
|
||||
return proto.Marshal(dbUTXOEntry)
|
||||
}
|
||||
|
||||
func deserializeUTXOEntry(serializedUTXOEntry []byte) (externalapi.UTXOEntry, error) {
|
||||
var dbUTXOEntry serialization.DbUtxoEntry
|
||||
err := proto.Unmarshal(serializedUTXOEntry, &dbUTXOEntry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return serialization.DBUTXOEntryToUTXOEntry(&dbUTXOEntry)
|
||||
}
|
||||
|
||||
const hashesLengthSize = 8
|
||||
|
||||
func serializeHashes(hashes []*externalapi.DomainHash) []byte {
|
||||
serializedHashes := make([]byte, hashesLengthSize+externalapi.DomainHashSize*len(hashes))
|
||||
binary.LittleEndian.PutUint64(serializedHashes[:hashesLengthSize], uint64(len(hashes)))
|
||||
for i, hash := range hashes {
|
||||
start := hashesLengthSize + externalapi.DomainHashSize*i
|
||||
end := start + externalapi.DomainHashSize
|
||||
copy(serializedHashes[start:end],
|
||||
hash.ByteSlice())
|
||||
}
|
||||
return serializedHashes
|
||||
}
|
||||
|
||||
func deserializeHashes(serializedHashes []byte) ([]*externalapi.DomainHash, error) {
|
||||
length := binary.LittleEndian.Uint64(serializedHashes[:hashesLengthSize])
|
||||
hashes := make([]*externalapi.DomainHash, length)
|
||||
for i := uint64(0); i < length; i++ {
|
||||
start := hashesLengthSize + externalapi.DomainHashSize*i
|
||||
end := start + externalapi.DomainHashSize
|
||||
|
||||
if end > uint64(len(serializedHashes)) {
|
||||
return nil, errors.Wrapf(io.ErrUnexpectedEOF, "unexpected EOF while deserializing hashes")
|
||||
}
|
||||
|
||||
var err error
|
||||
hashes[i], err = externalapi.
|
||||
NewDomainHashFromByteSlice(serializedHashes[start:end])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package utxoindex
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/database/serialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/infrastructure/db/database"
|
||||
"github.com/kaspanet/kaspad/infrastructure/logger"
|
||||
@@ -9,13 +11,11 @@ import (
|
||||
)
|
||||
|
||||
var utxoIndexBucket = database.MakeBucket([]byte("utxo-index"))
|
||||
var virtualParentsKey = database.MakeBucket([]byte("")).Key([]byte("utxo-index-virtual-parents"))
|
||||
|
||||
type utxoIndexStore struct {
|
||||
database database.Database
|
||||
toAdd map[ScriptPublicKeyString]UTXOOutpointEntryPairs
|
||||
toRemove map[ScriptPublicKeyString]UTXOOutpoints
|
||||
virtualParents []*externalapi.DomainHash
|
||||
database database.Database
|
||||
toAdd map[ScriptPublicKeyString]UTXOOutpointEntryPairs
|
||||
toRemove map[ScriptPublicKeyString]UTXOOutpoints
|
||||
}
|
||||
|
||||
func newUTXOIndexStore(database database.Database) *utxoIndexStore {
|
||||
@@ -95,14 +95,9 @@ func (uis *utxoIndexStore) remove(scriptPublicKey *externalapi.ScriptPublicKey,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) updateVirtualParents(virtualParents []*externalapi.DomainHash) {
|
||||
uis.virtualParents = virtualParents
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) discard() {
|
||||
uis.toAdd = make(map[ScriptPublicKeyString]UTXOOutpointEntryPairs)
|
||||
uis.toRemove = make(map[ScriptPublicKeyString]UTXOOutpoints)
|
||||
uis.virtualParents = nil
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) commit() error {
|
||||
@@ -138,7 +133,7 @@ func (uis *utxoIndexStore) commit() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
serializedUTXOEntry, err := serializeUTXOEntry(utxoEntryToAdd)
|
||||
serializedUTXOEntry, err := uis.serializeUTXOEntry(utxoEntryToAdd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -149,12 +144,6 @@ func (uis *utxoIndexStore) commit() error {
|
||||
}
|
||||
}
|
||||
|
||||
serializeParentHashes := serializeHashes(uis.virtualParents)
|
||||
err = dbTransaction.Put(virtualParentsKey, serializeParentHashes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = dbTransaction.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -164,31 +153,6 @@ func (uis *utxoIndexStore) commit() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) addAndCommitOutpointsWithoutTransaction(utxoPairs []*externalapi.OutpointAndUTXOEntryPair) error {
|
||||
for _, pair := range utxoPairs {
|
||||
bucket := uis.bucketForScriptPublicKey(pair.UTXOEntry.ScriptPublicKey())
|
||||
key, err := uis.convertOutpointToKey(bucket, pair.Outpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
serializedUTXOEntry, err := serializeUTXOEntry(pair.UTXOEntry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = uis.database.Put(key, serializedUTXOEntry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) updateAndCommitVirtualParentsWithoutTransaction(virtualParents []*externalapi.DomainHash) error {
|
||||
serializeParentHashes := serializeHashes(virtualParents)
|
||||
return uis.database.Put(virtualParentsKey, serializeParentHashes)
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) bucketForScriptPublicKey(scriptPublicKey *externalapi.ScriptPublicKey) *database.Bucket {
|
||||
var scriptPublicKeyBytes = make([]byte, 2+len(scriptPublicKey.Script)) // uint16
|
||||
binary.LittleEndian.PutUint16(scriptPublicKeyBytes[:2], scriptPublicKey.Version)
|
||||
@@ -197,7 +161,7 @@ func (uis *utxoIndexStore) bucketForScriptPublicKey(scriptPublicKey *externalapi
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) convertOutpointToKey(bucket *database.Bucket, outpoint *externalapi.DomainOutpoint) (*database.Key, error) {
|
||||
serializedOutpoint, err := serializeOutpoint(outpoint)
|
||||
serializedOutpoint, err := uis.serializeOutpoint(outpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -206,13 +170,40 @@ func (uis *utxoIndexStore) convertOutpointToKey(bucket *database.Bucket, outpoin
|
||||
|
||||
func (uis *utxoIndexStore) convertKeyToOutpoint(key *database.Key) (*externalapi.DomainOutpoint, error) {
|
||||
serializedOutpoint := key.Suffix()
|
||||
return deserializeOutpoint(serializedOutpoint)
|
||||
return uis.deserializeOutpoint(serializedOutpoint)
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) serializeOutpoint(outpoint *externalapi.DomainOutpoint) ([]byte, error) {
|
||||
dbOutpoint := serialization.DomainOutpointToDbOutpoint(outpoint)
|
||||
return proto.Marshal(dbOutpoint)
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) deserializeOutpoint(serializedOutpoint []byte) (*externalapi.DomainOutpoint, error) {
|
||||
var dbOutpoint serialization.DbOutpoint
|
||||
err := proto.Unmarshal(serializedOutpoint, &dbOutpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return serialization.DbOutpointToDomainOutpoint(&dbOutpoint)
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) serializeUTXOEntry(utxoEntry externalapi.UTXOEntry) ([]byte, error) {
|
||||
dbUTXOEntry := serialization.UTXOEntryToDBUTXOEntry(utxoEntry)
|
||||
return proto.Marshal(dbUTXOEntry)
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) deserializeUTXOEntry(serializedUTXOEntry []byte) (externalapi.UTXOEntry, error) {
|
||||
var dbUTXOEntry serialization.DbUtxoEntry
|
||||
err := proto.Unmarshal(serializedUTXOEntry, &dbUTXOEntry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return serialization.DBUTXOEntryToUTXOEntry(&dbUTXOEntry)
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) stagedData() (
|
||||
toAdd map[ScriptPublicKeyString]UTXOOutpointEntryPairs,
|
||||
toRemove map[ScriptPublicKeyString]UTXOOutpoints,
|
||||
virtualParents []*externalapi.DomainHash) {
|
||||
toRemove map[ScriptPublicKeyString]UTXOOutpoints) {
|
||||
|
||||
toAddClone := make(map[ScriptPublicKeyString]UTXOOutpointEntryPairs, len(uis.toAdd))
|
||||
for scriptPublicKeyString, toAddUTXOOutpointEntryPairs := range uis.toAdd {
|
||||
@@ -232,7 +223,7 @@ func (uis *utxoIndexStore) stagedData() (
|
||||
toRemoveClone[scriptPublicKeyString] = toRemoveOutpointsClone
|
||||
}
|
||||
|
||||
return toAddClone, toRemoveClone, uis.virtualParents
|
||||
return toAddClone, toRemoveClone
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) isAnythingStaged() bool {
|
||||
@@ -263,7 +254,7 @@ func (uis *utxoIndexStore) getUTXOOutpointEntryPairs(scriptPublicKey *externalap
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
utxoEntry, err := deserializeUTXOEntry(serializedUTXOEntry)
|
||||
utxoEntry, err := uis.deserializeUTXOEntry(serializedUTXOEntry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -271,43 +262,3 @@ func (uis *utxoIndexStore) getUTXOOutpointEntryPairs(scriptPublicKey *externalap
|
||||
}
|
||||
return utxoOutpointEntryPairs, nil
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) getVirtualParents() ([]*externalapi.DomainHash, error) {
|
||||
if uis.isAnythingStaged() {
|
||||
return nil, errors.Errorf("cannot get the virtual parents while staging isn't empty")
|
||||
}
|
||||
|
||||
serializedHashes, err := uis.database.Get(virtualParentsKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return deserializeHashes(serializedHashes)
|
||||
}
|
||||
|
||||
func (uis *utxoIndexStore) deleteAll() error {
|
||||
// First we delete the virtual parents, so if anything goes wrong, the UTXO index will be marked as "not synced"
|
||||
// and will be reset.
|
||||
err := uis.database.Delete(virtualParentsKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cursor, err := uis.database.Cursor(utxoIndexBucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for cursor.Next() {
|
||||
key, err := cursor.Key()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = uis.database.Delete(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@ package utxoindex
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"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/db/database"
|
||||
"github.com/kaspanet/kaspad/infrastructure/logger"
|
||||
"sync"
|
||||
@@ -16,111 +19,44 @@ type UTXOIndex struct {
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// New creates a new UTXO index.
|
||||
//
|
||||
// NOTE: While this is called no new blocks can be added to the consensus.
|
||||
func New(consensus externalapi.Consensus, database database.Database) (*UTXOIndex, error) {
|
||||
utxoIndex := &UTXOIndex{
|
||||
// New creates a new UTXO index
|
||||
func New(consensus externalapi.Consensus, database database.Database) *UTXOIndex {
|
||||
store := newUTXOIndexStore(database)
|
||||
return &UTXOIndex{
|
||||
consensus: consensus,
|
||||
store: newUTXOIndexStore(database),
|
||||
store: store,
|
||||
}
|
||||
|
||||
isSynced, err := utxoIndex.isSynced()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !isSynced {
|
||||
err = utxoIndex.Reset()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return utxoIndex, nil
|
||||
}
|
||||
|
||||
// Reset deletes the whole UTXO index and resyncs it from consensus.
|
||||
func (ui *UTXOIndex) Reset() error {
|
||||
err := ui.store.deleteAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
virtualInfo, err := ui.consensus.GetVirtualInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var fromOutpoint *externalapi.DomainOutpoint
|
||||
for {
|
||||
const step = 1000
|
||||
virtualUTXOs, err := ui.consensus.GetVirtualUTXOs(virtualInfo.ParentHashes, fromOutpoint, step)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ui.store.addAndCommitOutpointsWithoutTransaction(virtualUTXOs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(virtualUTXOs) < step {
|
||||
break
|
||||
}
|
||||
|
||||
fromOutpoint = virtualUTXOs[len(virtualUTXOs)-1].Outpoint
|
||||
}
|
||||
|
||||
// This has to be done last to mark that the reset went smoothly and no reset has to be called next time.
|
||||
return ui.store.updateAndCommitVirtualParentsWithoutTransaction(virtualInfo.ParentHashes)
|
||||
}
|
||||
|
||||
func (ui *UTXOIndex) isSynced() (bool, error) {
|
||||
utxoIndexVirtualParents, err := ui.store.getVirtualParents()
|
||||
if err != nil {
|
||||
if database.IsNotFoundError(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
virtualInfo, err := ui.consensus.GetVirtualInfo()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return externalapi.HashesEqual(virtualInfo.ParentHashes, utxoIndexVirtualParents), nil
|
||||
}
|
||||
|
||||
// Update updates the UTXO index with the given DAG selected parent chain changes
|
||||
func (ui *UTXOIndex) Update(blockInsertionResult *externalapi.BlockInsertionResult) (*UTXOChanges, error) {
|
||||
func (ui *UTXOIndex) Update(chainChanges *externalapi.SelectedChainPath) (*UTXOChanges, error) {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "UTXOIndex.Update")
|
||||
defer onEnd()
|
||||
|
||||
ui.mutex.Lock()
|
||||
defer ui.mutex.Unlock()
|
||||
|
||||
log.Tracef("Updating UTXO index with VirtualUTXODiff: %+v", blockInsertionResult.VirtualUTXODiff)
|
||||
err := ui.removeUTXOs(blockInsertionResult.VirtualUTXODiff.ToRemove())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
log.Tracef("Updating UTXO index with chainChanges: %+v", chainChanges)
|
||||
for _, removedBlockHash := range chainChanges.Removed {
|
||||
err := ui.removeBlock(removedBlockHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
for _, addedBlockHash := range chainChanges.Added {
|
||||
err := ui.addBlock(addedBlockHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = ui.addUTXOs(blockInsertionResult.VirtualUTXODiff.ToAdd())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ui.store.updateVirtualParents(blockInsertionResult.VirtualParents)
|
||||
|
||||
added, removed, _ := ui.store.stagedData()
|
||||
added, removed := ui.store.stagedData()
|
||||
utxoIndexChanges := &UTXOChanges{
|
||||
Added: added,
|
||||
Removed: removed,
|
||||
}
|
||||
|
||||
err = ui.store.commit()
|
||||
err := ui.store.commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -129,16 +65,73 @@ func (ui *UTXOIndex) Update(blockInsertionResult *externalapi.BlockInsertionResu
|
||||
return utxoIndexChanges, nil
|
||||
}
|
||||
|
||||
func (ui *UTXOIndex) addUTXOs(toAdd externalapi.UTXOCollection) error {
|
||||
iterator := toAdd.Iterator()
|
||||
for ok := iterator.First(); ok; ok = iterator.Next() {
|
||||
outpoint, entry, err := iterator.Get()
|
||||
func (ui *UTXOIndex) addBlock(blockHash *externalapi.DomainHash) error {
|
||||
log.Tracef("Adding block %s to UTXO index", blockHash)
|
||||
acceptanceData, err := ui.consensus.GetBlockAcceptanceData(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
blockInfo, err := ui.consensus.GetBlockInfo(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, blockAcceptanceData := range acceptanceData {
|
||||
for _, transactionAcceptanceData := range blockAcceptanceData.TransactionAcceptanceData {
|
||||
if !transactionAcceptanceData.IsAccepted {
|
||||
continue
|
||||
}
|
||||
err := ui.addTransaction(transactionAcceptanceData.Transaction,
|
||||
transactionAcceptanceData.TransactionInputUTXOEntries, blockInfo.BlueScore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ui *UTXOIndex) removeBlock(blockHash *externalapi.DomainHash) error {
|
||||
log.Tracef("Removing block %s from UTXO index", blockHash)
|
||||
acceptanceData, err := ui.consensus.GetBlockAcceptanceData(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, blockAcceptanceData := range acceptanceData {
|
||||
for _, transactionAcceptanceData := range blockAcceptanceData.TransactionAcceptanceData {
|
||||
if !transactionAcceptanceData.IsAccepted {
|
||||
continue
|
||||
}
|
||||
err := ui.removeTransaction(transactionAcceptanceData.Transaction,
|
||||
transactionAcceptanceData.TransactionInputUTXOEntries)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ui *UTXOIndex) addTransaction(transaction *externalapi.DomainTransaction,
|
||||
transactionInputUTXOEntries []externalapi.UTXOEntry, blockBlueScore uint64) error {
|
||||
|
||||
transactionID := consensushashing.TransactionID(transaction)
|
||||
log.Tracef("Adding transaction %s to UTXO index", transactionID)
|
||||
|
||||
isCoinbase := transactionhelper.IsCoinBase(transaction)
|
||||
for i, transactionInput := range transaction.Inputs {
|
||||
log.Tracef("Removing outpoint %s:%d from UTXO index",
|
||||
transactionInput.PreviousOutpoint.TransactionID, transactionInput.PreviousOutpoint.Index)
|
||||
inputUTXOEntry := transactionInputUTXOEntries[i]
|
||||
err := ui.store.remove(inputUTXOEntry.ScriptPublicKey(), &transactionInput.PreviousOutpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Tracef("Adding outpoint %s to UTXO index", outpoint)
|
||||
err = ui.store.add(entry.ScriptPublicKey(), outpoint, entry)
|
||||
}
|
||||
for index, transactionOutput := range transaction.Outputs {
|
||||
log.Tracef("Adding outpoint %s:%d to UTXO index", transactionID, index)
|
||||
outpoint := externalapi.NewDomainOutpoint(transactionID, uint32(index))
|
||||
utxoEntry := utxo.NewUTXOEntry(transactionOutput.Value, transactionOutput.ScriptPublicKey, isCoinbase, blockBlueScore)
|
||||
err := ui.store.add(transactionOutput.ScriptPublicKey, outpoint, utxoEntry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -146,16 +139,24 @@ func (ui *UTXOIndex) addUTXOs(toAdd externalapi.UTXOCollection) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ui *UTXOIndex) removeUTXOs(toRemove externalapi.UTXOCollection) error {
|
||||
iterator := toRemove.Iterator()
|
||||
for ok := iterator.First(); ok; ok = iterator.Next() {
|
||||
outpoint, entry, err := iterator.Get()
|
||||
func (ui *UTXOIndex) removeTransaction(transaction *externalapi.DomainTransaction,
|
||||
transactionInputUTXOEntries []externalapi.UTXOEntry) error {
|
||||
|
||||
transactionID := consensushashing.TransactionID(transaction)
|
||||
log.Tracef("Removing transaction %s from UTXO index", transactionID)
|
||||
for index, transactionOutput := range transaction.Outputs {
|
||||
log.Tracef("Removing outpoint %s:%d from UTXO index", transactionID, index)
|
||||
outpoint := externalapi.NewDomainOutpoint(transactionID, uint32(index))
|
||||
err := ui.store.remove(transactionOutput.ScriptPublicKey, outpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Tracef("Removing outpoint %s from UTXO index", outpoint)
|
||||
err = ui.store.remove(entry.ScriptPublicKey(), outpoint)
|
||||
}
|
||||
for i, transactionInput := range transaction.Inputs {
|
||||
log.Tracef("Adding outpoint %s:%d to UTXO index",
|
||||
transactionInput.PreviousOutpoint.TransactionID, transactionInput.PreviousOutpoint.Index)
|
||||
inputUTXOEntry := transactionInputUTXOEntries[i]
|
||||
err := ui.store.add(inputUTXOEntry.ScriptPublicKey(), &transactionInput.PreviousOutpoint, transactionInput.UTXOEntry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
2
go.mod
2
go.mod
@@ -1,6 +1,6 @@
|
||||
module github.com/kaspanet/kaspad
|
||||
|
||||
go 1.16
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd
|
||||
|
||||
@@ -29,7 +29,6 @@ func newNetConnection(connection server.Connection, routerInitializer RouterInit
|
||||
}
|
||||
|
||||
netConnection.connection.SetOnDisconnectedHandler(func() {
|
||||
log.Infof("Disconnected from %s", netConnection)
|
||||
// If the disconnection came because of a network error and not because of the application layer, we
|
||||
// need to close the router as well.
|
||||
if atomic.AddUint32(&netConnection.isRouterClosed, 1) == 1 {
|
||||
|
||||
@@ -37,7 +37,7 @@ func (p *p2pServer) MessageStream(stream protowire.P2P_MessageStreamServer) erro
|
||||
// Connect connects to the given address
|
||||
// This is part of the P2PServer interface
|
||||
func (p *p2pServer) Connect(address string) (server.Connection, error) {
|
||||
log.Debugf("%s Dialing to %s", p.name, address)
|
||||
log.Infof("%s Dialing to %s", p.name, address)
|
||||
|
||||
const dialTimeout = 30 * time.Second
|
||||
ctx, cancel := context.WithTimeout(context.Background(), dialTimeout)
|
||||
|
||||
@@ -129,11 +129,6 @@ type KaspadMessage struct {
|
||||
// *KaspadMessage_GetInfoResponse
|
||||
// *KaspadMessage_StopNotifyingUtxosChangedRequest
|
||||
// *KaspadMessage_StopNotifyingUtxosChangedResponse
|
||||
// *KaspadMessage_NotifyPruningPointUTXOSetOverrideRequest
|
||||
// *KaspadMessage_NotifyPruningPointUTXOSetOverrideResponse
|
||||
// *KaspadMessage_PruningPointUTXOSetOverrideNotification
|
||||
// *KaspadMessage_StopNotifyingPruningPointUTXOSetOverrideRequest
|
||||
// *KaspadMessage_StopNotifyingPruningPointUTXOSetOverrideResponse
|
||||
Payload isKaspadMessage_Payload `protobuf_oneof:"payload"`
|
||||
}
|
||||
|
||||
@@ -862,41 +857,6 @@ func (x *KaspadMessage) GetStopNotifyingUtxosChangedResponse() *StopNotifyingUtx
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage) GetNotifyPruningPointUTXOSetOverrideRequest() *NotifyPruningPointUTXOSetOverrideRequestMessage {
|
||||
if x, ok := x.GetPayload().(*KaspadMessage_NotifyPruningPointUTXOSetOverrideRequest); ok {
|
||||
return x.NotifyPruningPointUTXOSetOverrideRequest
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage) GetNotifyPruningPointUTXOSetOverrideResponse() *NotifyPruningPointUTXOSetOverrideResponseMessage {
|
||||
if x, ok := x.GetPayload().(*KaspadMessage_NotifyPruningPointUTXOSetOverrideResponse); ok {
|
||||
return x.NotifyPruningPointUTXOSetOverrideResponse
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage) GetPruningPointUTXOSetOverrideNotification() *PruningPointUTXOSetOverrideNotificationMessage {
|
||||
if x, ok := x.GetPayload().(*KaspadMessage_PruningPointUTXOSetOverrideNotification); ok {
|
||||
return x.PruningPointUTXOSetOverrideNotification
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage) GetStopNotifyingPruningPointUTXOSetOverrideRequest() *StopNotifyingPruningPointUTXOSetOverrideRequestMessage {
|
||||
if x, ok := x.GetPayload().(*KaspadMessage_StopNotifyingPruningPointUTXOSetOverrideRequest); ok {
|
||||
return x.StopNotifyingPruningPointUTXOSetOverrideRequest
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage) GetStopNotifyingPruningPointUTXOSetOverrideResponse() *StopNotifyingPruningPointUTXOSetOverrideResponseMessage {
|
||||
if x, ok := x.GetPayload().(*KaspadMessage_StopNotifyingPruningPointUTXOSetOverrideResponse); ok {
|
||||
return x.StopNotifyingPruningPointUTXOSetOverrideResponse
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isKaspadMessage_Payload interface {
|
||||
isKaspadMessage_Payload()
|
||||
}
|
||||
@@ -1293,26 +1253,6 @@ type KaspadMessage_StopNotifyingUtxosChangedResponse struct {
|
||||
StopNotifyingUtxosChangedResponse *StopNotifyingUtxosChangedResponseMessage `protobuf:"bytes,1066,opt,name=stopNotifyingUtxosChangedResponse,proto3,oneof"`
|
||||
}
|
||||
|
||||
type KaspadMessage_NotifyPruningPointUTXOSetOverrideRequest struct {
|
||||
NotifyPruningPointUTXOSetOverrideRequest *NotifyPruningPointUTXOSetOverrideRequestMessage `protobuf:"bytes,1067,opt,name=notifyPruningPointUTXOSetOverrideRequest,proto3,oneof"`
|
||||
}
|
||||
|
||||
type KaspadMessage_NotifyPruningPointUTXOSetOverrideResponse struct {
|
||||
NotifyPruningPointUTXOSetOverrideResponse *NotifyPruningPointUTXOSetOverrideResponseMessage `protobuf:"bytes,1068,opt,name=notifyPruningPointUTXOSetOverrideResponse,proto3,oneof"`
|
||||
}
|
||||
|
||||
type KaspadMessage_PruningPointUTXOSetOverrideNotification struct {
|
||||
PruningPointUTXOSetOverrideNotification *PruningPointUTXOSetOverrideNotificationMessage `protobuf:"bytes,1069,opt,name=pruningPointUTXOSetOverrideNotification,proto3,oneof"`
|
||||
}
|
||||
|
||||
type KaspadMessage_StopNotifyingPruningPointUTXOSetOverrideRequest struct {
|
||||
StopNotifyingPruningPointUTXOSetOverrideRequest *StopNotifyingPruningPointUTXOSetOverrideRequestMessage `protobuf:"bytes,1070,opt,name=stopNotifyingPruningPointUTXOSetOverrideRequest,proto3,oneof"`
|
||||
}
|
||||
|
||||
type KaspadMessage_StopNotifyingPruningPointUTXOSetOverrideResponse struct {
|
||||
StopNotifyingPruningPointUTXOSetOverrideResponse *StopNotifyingPruningPointUTXOSetOverrideResponseMessage `protobuf:"bytes,1071,opt,name=stopNotifyingPruningPointUTXOSetOverrideResponse,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*KaspadMessage_Addresses) isKaspadMessage_Payload() {}
|
||||
|
||||
func (*KaspadMessage_Block) isKaspadMessage_Payload() {}
|
||||
@@ -1509,23 +1449,13 @@ func (*KaspadMessage_StopNotifyingUtxosChangedRequest) isKaspadMessage_Payload()
|
||||
|
||||
func (*KaspadMessage_StopNotifyingUtxosChangedResponse) isKaspadMessage_Payload() {}
|
||||
|
||||
func (*KaspadMessage_NotifyPruningPointUTXOSetOverrideRequest) isKaspadMessage_Payload() {}
|
||||
|
||||
func (*KaspadMessage_NotifyPruningPointUTXOSetOverrideResponse) isKaspadMessage_Payload() {}
|
||||
|
||||
func (*KaspadMessage_PruningPointUTXOSetOverrideNotification) isKaspadMessage_Payload() {}
|
||||
|
||||
func (*KaspadMessage_StopNotifyingPruningPointUTXOSetOverrideRequest) isKaspadMessage_Payload() {}
|
||||
|
||||
func (*KaspadMessage_StopNotifyingPruningPointUTXOSetOverrideResponse) isKaspadMessage_Payload() {}
|
||||
|
||||
var File_messages_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_messages_proto_rawDesc = []byte{
|
||||
0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x12, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x1a, 0x09, 0x70, 0x32, 0x70,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x09, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x22, 0xa4, 0x55, 0x0a, 0x0d, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73,
|
||||
0x6f, 0x22, 0xeb, 0x4e, 0x0a, 0x0d, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69,
|
||||
0x72, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x4d, 0x65, 0x73, 0x73,
|
||||
@@ -2155,72 +2085,21 @@ var file_messages_proto_rawDesc = []byte{
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48,
|
||||
0x00, 0x52, 0x21, 0x73, 0x74, 0x6f, 0x70, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67,
|
||||
0x55, 0x74, 0x78, 0x6f, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x99, 0x01, 0x0a, 0x28, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x50,
|
||||
0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53,
|
||||
0x65, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x18, 0xab, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x77, 0x69, 0x72, 0x65, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x50, 0x72, 0x75, 0x6e, 0x69,
|
||||
0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x4f, 0x76,
|
||||
0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x28, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x50, 0x72,
|
||||
0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65,
|
||||
0x74, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x12, 0x9c, 0x01, 0x0a, 0x29, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x50, 0x72, 0x75, 0x6e, 0x69,
|
||||
0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x4f, 0x76,
|
||||
0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0xac,
|
||||
0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72,
|
||||
0x65, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x50, 0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50,
|
||||
0x6f, 0x69, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x72,
|
||||
0x69, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61,
|
||||
0x67, 0x65, 0x48, 0x00, 0x52, 0x29, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x50, 0x72, 0x75, 0x6e,
|
||||
0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x4f,
|
||||
0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x96, 0x01, 0x0a, 0x27, 0x70, 0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74,
|
||||
0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x4e,
|
||||
0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xad, 0x08, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x39, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x50,
|
||||
0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53,
|
||||
0x65, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69,
|
||||
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52,
|
||||
0x27, 0x70, 0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x55, 0x54, 0x58,
|
||||
0x4f, 0x53, 0x65, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x4e, 0x6f, 0x74, 0x69,
|
||||
0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0xae, 0x01, 0x0a, 0x2f, 0x73, 0x74, 0x6f,
|
||||
0x70, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x75, 0x6e, 0x69, 0x6e,
|
||||
0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x4f, 0x76, 0x65,
|
||||
0x72, 0x72, 0x69, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0xae, 0x08, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e,
|
||||
0x53, 0x74, 0x6f, 0x70, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x75,
|
||||
0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74,
|
||||
0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x2f, 0x73, 0x74, 0x6f, 0x70, 0x4e, 0x6f,
|
||||
0x74, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f,
|
||||
0x69, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69,
|
||||
0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xb1, 0x01, 0x0a, 0x30, 0x73, 0x74,
|
||||
0x6f, 0x70, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x75, 0x6e, 0x69,
|
||||
0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x4f, 0x76,
|
||||
0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0xaf,
|
||||
0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72,
|
||||
0x65, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x50,
|
||||
0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53,
|
||||
0x65, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x30, 0x73, 0x74, 0x6f,
|
||||
0x70, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x75, 0x6e, 0x69, 0x6e,
|
||||
0x67, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x4f, 0x76, 0x65,
|
||||
0x72, 0x72, 0x69, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09, 0x0a,
|
||||
0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x32, 0x50, 0x0a, 0x03, 0x50, 0x32, 0x50, 0x12,
|
||||
0x49, 0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
|
||||
0x12, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61, 0x73,
|
||||
0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x32, 0x50, 0x0a, 0x03, 0x52, 0x50,
|
||||
0x43, 0x12, 0x49, 0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65,
|
||||
0x61, 0x6d, 0x12, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4b,
|
||||
0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 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,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x32,
|
||||
0x50, 0x0a, 0x03, 0x50, 0x32, 0x50, 0x12, 0x49, 0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||
0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77,
|
||||
0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||
0x65, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61,
|
||||
0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30,
|
||||
0x01, 0x32, 0x50, 0x0a, 0x03, 0x52, 0x50, 0x43, 0x12, 0x49, 0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e,
|
||||
0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x28,
|
||||
0x01, 0x30, 0x01, 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 (
|
||||
@@ -2335,11 +2214,6 @@ var file_messages_proto_goTypes = []interface{}{
|
||||
(*GetInfoResponseMessage)(nil), // 95: protowire.GetInfoResponseMessage
|
||||
(*StopNotifyingUtxosChangedRequestMessage)(nil), // 96: protowire.StopNotifyingUtxosChangedRequestMessage
|
||||
(*StopNotifyingUtxosChangedResponseMessage)(nil), // 97: protowire.StopNotifyingUtxosChangedResponseMessage
|
||||
(*NotifyPruningPointUTXOSetOverrideRequestMessage)(nil), // 98: protowire.NotifyPruningPointUTXOSetOverrideRequestMessage
|
||||
(*NotifyPruningPointUTXOSetOverrideResponseMessage)(nil), // 99: protowire.NotifyPruningPointUTXOSetOverrideResponseMessage
|
||||
(*PruningPointUTXOSetOverrideNotificationMessage)(nil), // 100: protowire.PruningPointUTXOSetOverrideNotificationMessage
|
||||
(*StopNotifyingPruningPointUTXOSetOverrideRequestMessage)(nil), // 101: protowire.StopNotifyingPruningPointUTXOSetOverrideRequestMessage
|
||||
(*StopNotifyingPruningPointUTXOSetOverrideResponseMessage)(nil), // 102: protowire.StopNotifyingPruningPointUTXOSetOverrideResponseMessage
|
||||
}
|
||||
var file_messages_proto_depIdxs = []int32{
|
||||
1, // 0: protowire.KaspadMessage.addresses:type_name -> protowire.AddressesMessage
|
||||
@@ -2440,20 +2314,15 @@ var file_messages_proto_depIdxs = []int32{
|
||||
95, // 95: protowire.KaspadMessage.getInfoResponse:type_name -> protowire.GetInfoResponseMessage
|
||||
96, // 96: protowire.KaspadMessage.stopNotifyingUtxosChangedRequest:type_name -> protowire.StopNotifyingUtxosChangedRequestMessage
|
||||
97, // 97: protowire.KaspadMessage.stopNotifyingUtxosChangedResponse:type_name -> protowire.StopNotifyingUtxosChangedResponseMessage
|
||||
98, // 98: protowire.KaspadMessage.notifyPruningPointUTXOSetOverrideRequest:type_name -> protowire.NotifyPruningPointUTXOSetOverrideRequestMessage
|
||||
99, // 99: protowire.KaspadMessage.notifyPruningPointUTXOSetOverrideResponse:type_name -> protowire.NotifyPruningPointUTXOSetOverrideResponseMessage
|
||||
100, // 100: protowire.KaspadMessage.pruningPointUTXOSetOverrideNotification:type_name -> protowire.PruningPointUTXOSetOverrideNotificationMessage
|
||||
101, // 101: protowire.KaspadMessage.stopNotifyingPruningPointUTXOSetOverrideRequest:type_name -> protowire.StopNotifyingPruningPointUTXOSetOverrideRequestMessage
|
||||
102, // 102: protowire.KaspadMessage.stopNotifyingPruningPointUTXOSetOverrideResponse:type_name -> protowire.StopNotifyingPruningPointUTXOSetOverrideResponseMessage
|
||||
0, // 103: protowire.P2P.MessageStream:input_type -> protowire.KaspadMessage
|
||||
0, // 104: protowire.RPC.MessageStream:input_type -> protowire.KaspadMessage
|
||||
0, // 105: protowire.P2P.MessageStream:output_type -> protowire.KaspadMessage
|
||||
0, // 106: protowire.RPC.MessageStream:output_type -> protowire.KaspadMessage
|
||||
105, // [105:107] is the sub-list for method output_type
|
||||
103, // [103:105] is the sub-list for method input_type
|
||||
103, // [103:103] is the sub-list for extension type_name
|
||||
103, // [103:103] is the sub-list for extension extendee
|
||||
0, // [0:103] is the sub-list for field type_name
|
||||
0, // 98: protowire.P2P.MessageStream:input_type -> protowire.KaspadMessage
|
||||
0, // 99: protowire.RPC.MessageStream:input_type -> protowire.KaspadMessage
|
||||
0, // 100: protowire.P2P.MessageStream:output_type -> protowire.KaspadMessage
|
||||
0, // 101: protowire.RPC.MessageStream:output_type -> protowire.KaspadMessage
|
||||
100, // [100:102] is the sub-list for method output_type
|
||||
98, // [98:100] is the sub-list for method input_type
|
||||
98, // [98:98] is the sub-list for extension type_name
|
||||
98, // [98:98] is the sub-list for extension extendee
|
||||
0, // [0:98] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_messages_proto_init() }
|
||||
@@ -2576,11 +2445,6 @@ func file_messages_proto_init() {
|
||||
(*KaspadMessage_GetInfoResponse)(nil),
|
||||
(*KaspadMessage_StopNotifyingUtxosChangedRequest)(nil),
|
||||
(*KaspadMessage_StopNotifyingUtxosChangedResponse)(nil),
|
||||
(*KaspadMessage_NotifyPruningPointUTXOSetOverrideRequest)(nil),
|
||||
(*KaspadMessage_NotifyPruningPointUTXOSetOverrideResponse)(nil),
|
||||
(*KaspadMessage_PruningPointUTXOSetOverrideNotification)(nil),
|
||||
(*KaspadMessage_StopNotifyingPruningPointUTXOSetOverrideRequest)(nil),
|
||||
(*KaspadMessage_StopNotifyingPruningPointUTXOSetOverrideResponse)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
|
||||
@@ -107,11 +107,6 @@ message KaspadMessage {
|
||||
GetInfoResponseMessage getInfoResponse = 1064;
|
||||
StopNotifyingUtxosChangedRequestMessage stopNotifyingUtxosChangedRequest = 1065;
|
||||
StopNotifyingUtxosChangedResponseMessage stopNotifyingUtxosChangedResponse = 1066;
|
||||
NotifyPruningPointUTXOSetOverrideRequestMessage notifyPruningPointUTXOSetOverrideRequest = 1067;
|
||||
NotifyPruningPointUTXOSetOverrideResponseMessage notifyPruningPointUTXOSetOverrideResponse = 1068;
|
||||
PruningPointUTXOSetOverrideNotificationMessage pruningPointUTXOSetOverrideNotification = 1069;
|
||||
StopNotifyingPruningPointUTXOSetOverrideRequestMessage stopNotifyingPruningPointUTXOSetOverrideRequest = 1070;
|
||||
StopNotifyingPruningPointUTXOSetOverrideResponseMessage stopNotifyingPruningPointUTXOSetOverrideResponse = 1071;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user