Implement maybeAddOrphan and AddOrphan

This commit is contained in:
Mike Zak 2021-06-08 15:08:49 +03:00
parent 2402d48c3e
commit 35eb4b9d87
3 changed files with 85 additions and 28 deletions

View File

@ -11,6 +11,9 @@ const (
defaultTransactionExpireScanIntervalSeconds uint64 = 10 defaultTransactionExpireScanIntervalSeconds uint64 = 10
defaultOrphanExpireIntervalSeconds uint64 = 60 defaultOrphanExpireIntervalSeconds uint64 = 60
defaultOrphanExpireScanIntervalSeconds uint64 = 10 defaultOrphanExpireScanIntervalSeconds uint64 = 10
defaultMaximumOrphanTransactionSize = 100000
defaultMaximumOrphanTransactions = 50
) )
type config struct { type config struct {
@ -18,6 +21,7 @@ type config struct {
transactionExpireScanIntervalDAAScore uint64 transactionExpireScanIntervalDAAScore uint64
orphanExpireIntervalDAAScore uint64 orphanExpireIntervalDAAScore uint64
orphanExpireScanIntervalDAAScore uint64 orphanExpireScanIntervalDAAScore uint64
maximumOrphanTransactionSize int
} }
func defaultConfig(dagParams *dagconfig.Params) *config { func defaultConfig(dagParams *dagconfig.Params) *config {
@ -28,5 +32,6 @@ func defaultConfig(dagParams *dagconfig.Params) *config {
transactionExpireScanIntervalDAAScore: defaultTransactionExpireScanIntervalSeconds / targetBlocksPerSecond, transactionExpireScanIntervalDAAScore: defaultTransactionExpireScanIntervalSeconds / targetBlocksPerSecond,
orphanExpireIntervalDAAScore: defaultOrphanExpireIntervalSeconds / targetBlocksPerSecond, orphanExpireIntervalDAAScore: defaultOrphanExpireIntervalSeconds / targetBlocksPerSecond,
orphanExpireScanIntervalDAAScore: defaultOrphanExpireScanIntervalSeconds / targetBlocksPerSecond, orphanExpireScanIntervalDAAScore: defaultOrphanExpireScanIntervalSeconds / targetBlocksPerSecond,
maximumOrphanTransactionSize: defaultMaximumOrphanTransactionSize,
} }
} }

View File

@ -50,6 +50,7 @@ const (
RejectFinality RejectCode = 0x43 RejectFinality RejectCode = 0x43
RejectDifficulty RejectCode = 0x44 RejectDifficulty RejectCode = 0x44
RejectImmatureSpend RejectCode = 0x45 RejectImmatureSpend RejectCode = 0x45
RejectIncompatibleOrphan RejectCode = 0x64
) )
// Map of reject codes back strings for pretty printing. // Map of reject codes back strings for pretty printing.
@ -58,13 +59,14 @@ var rejectCodeStrings = map[RejectCode]string{
RejectInvalid: "REJECT_INVALID", RejectInvalid: "REJECT_INVALID",
RejectObsolete: "REJECT_OBSOLETE", RejectObsolete: "REJECT_OBSOLETE",
RejectDuplicate: "REJECT_DUPLICATE", RejectDuplicate: "REJECT_DUPLICATE",
RejectNonstandard: "REJECT_NONSTANDARD", RejectNonstandard: "REJECT_NON_STANDARD",
RejectDust: "REJECT_DUST", RejectDust: "REJECT_DUST",
RejectInsufficientFee: "REJECT_INSUFFICIENTFEE", RejectInsufficientFee: "REJECT_INSUFFICIENT_FEE",
RejectFinality: "REJECT_FINALITY", RejectFinality: "REJECT_FINALITY",
RejectDifficulty: "REJECT_DIFFICULTY", RejectDifficulty: "REJECT_DIFFICULTY",
RejectNotRequested: "REJECT_NOTREQUESTED", RejectNotRequested: "REJECT_NOT_REQUESTED",
RejectImmatureSpend: "REJECT_IMMATURESPEND", RejectImmatureSpend: "REJECT_IMMATURE_SPEND",
RejectIncompatibleOrphan: "REJECT_INCOMPATIBLE_ORPHAN",
} }
// String returns the RejectCode in human-readable form. // String returns the RejectCode in human-readable form.

View File

@ -1,7 +1,10 @@
package mempool package mempool
import ( import (
"fmt"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi" "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
"github.com/kaspanet/kaspad/domain/miningmanager/mempool/model" "github.com/kaspanet/kaspad/domain/miningmanager/mempool/model"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -25,10 +28,51 @@ func newOrphansPool(mp *mempool) *orphansPool {
} }
} }
func (op *orphansPool) maybeAddOrphan(transaction *externalapi.DomainTransaction, func (op *orphansPool) maybeAddOrphan(transaction *externalapi.DomainTransaction, isHighPriority bool) error {
missingParents []*externalapi.DomainTransactionID, isHighPriority bool) error { serializedLength := estimatedsize.TransactionEstimatedSerializedSize(transaction)
if serializedLength > uint64(op.mempool.config.maximumOrphanTransactionSize) {
str := fmt.Sprintf("orphan transaction size of %d bytes is "+
"larger than max allowed size of %d bytes",
serializedLength, op.mempool.config.maximumOrphanTransactionSize)
return txRuleError(RejectIncompatibleOrphan, str)
}
if op.mempool.config.maximumOrphanTransactionSize <= 0 {
return nil
}
for len(op.allOrphans) >= op.mempool.config.maximumOrphanTransactionSize {
// Don't remove redeemers in the case of a random eviction since
// it is quite possible it might be needed again shortly.
err := op.removeOrphan(op.randomOrphan().TransactionID(), false)
if err != nil {
return err
}
}
panic("orphansPool.maybeAddOrphan not implemented") // TODO (Mike) return op.addOrphan(transaction, isHighPriority)
}
func (op *orphansPool) addOrphan(transaction *externalapi.DomainTransaction, isHighPriority bool) error {
virtualDAAScore, err := op.mempool.virtualDAAScore()
if err != nil {
return err
}
orphanTransaction := &model.OrphanTransaction{
Transaction: transaction,
IsHighPriority: isHighPriority,
AddedAtDAAScore: virtualDAAScore,
}
op.allOrphans[*orphanTransaction.TransactionID()] = orphanTransaction
for _, input := range transaction.Inputs {
if input.UTXOEntry == nil {
if _, ok := op.orphansByPreviousOutpoint[input.PreviousOutpoint]; !ok {
op.orphansByPreviousOutpoint[input.PreviousOutpoint] = idToOrphan{}
}
op.orphansByPreviousOutpoint[input.PreviousOutpoint][*orphanTransaction.TransactionID()] = orphanTransaction
}
}
return nil
} }
func (op *orphansPool) processOrphansAfterAcceptedTransaction(acceptedTransaction *model.MempoolTransaction) ( func (op *orphansPool) processOrphansAfterAcceptedTransaction(acceptedTransaction *model.MempoolTransaction) (
@ -125,9 +169,7 @@ func (op *orphansPool) expireOrphanTransactions() error {
// Remove all transactions whose addedAtDAAScore is older then transactionExpireIntervalDAAScore // Remove all transactions whose addedAtDAAScore is older then transactionExpireIntervalDAAScore
if virtualDAAScore-orphanTransaction.AddedAtDAAScore > op.mempool.config.orphanExpireIntervalDAAScore { if virtualDAAScore-orphanTransaction.AddedAtDAAScore > op.mempool.config.orphanExpireIntervalDAAScore {
// Don't remove redeemers in the case of a random eviction since err = op.removeOrphan(orphanTransaction.TransactionID(), true)
// it is quite possible it might be needed again shortly.
err = op.removeOrphan(orphanTransaction.TransactionID(), false)
if err != nil { if err != nil {
return err return err
} }
@ -137,3 +179,11 @@ func (op *orphansPool) expireOrphanTransactions() error {
op.lastExpireScan = virtualDAAScore op.lastExpireScan = virtualDAAScore
return nil return nil
} }
func (op *orphansPool) randomOrphan() *model.OrphanTransaction {
for _, orphan := range op.allOrphans {
return orphan
}
return nil
}