mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-05-21 06:16:45 +00:00

* Added model and stubs for all main methods * Add constructors to all main objects * Implement BlockCandidateTransactions * implement expireOldTransactions and expireOrphanTransactions * Rename isHighPriority to neverExpires * Add stub for checkDoubleSpends * Revert "Rename isHighPriority to neverExpires" This reverts commit b2da9a4a00c02fb380d2518cf54fa16257bd8423. * Imeplement transactionsOrderedByFeeRate * Orphan maps should be idToOrphan * Add error.go to mempool * Invert the condition for banning when mempool rejects a transaction * Move all model objects to model package * Implement getParentsInPool * Implemented mempoolUTXOSet.addTransaction * Implement removeTransaction, remove sanity checks * Implemented mempoolUTXOSet.checkDoubleSpends * Implemented removeOrphan * Implement removeOrphan * Implement maybeAddOrphan and AddOrphan * Implemented processOrphansAfterAcceptedTransaction * Implement transactionsPool.addTransaction * Implement RemoveTransaction * If a transaction was removed from the mempool - update it's redeemers in orphan pool as well * Use maximumOrphanTransactionCount * Add allowOrphans to ValidateAndInsertTransaction stub * Implement validateTransaction functions * Implement fillInputs * Implement ValidateAndInsertTransaction * Implement HandleNewBlockTransactions * Implement missing mempool interface methods * Add comments to exported functions * Call ValidateTransactionInIsolation where needed * Implement RevalidateHighPriorityTransactions * Rewire kaspad to use new mempool, and fix compilation errors * Update rebroadcast logic to use new structure * Handle non-standard transaction errors properly * Add mutex to mempool * bugfix: GetTransaction panics when ok is false * properly calculate targetBlocksPerSecond in config.go * Fix various lint errors and tests * Fix expected text in test for duplicate transactions * Skip the coinbase transaction in HandleNewBlockTransactions * Unorphan the correct transactions * Call ValidateTransactionAndPopulateWithConsensusData on unorphanTransaction * Re-apply policy_test as check_transactions_standard_test * removeTransaction: Remove redeemers in orphan pool as well * Remove redundant check for uint64 < 0 * Export and rename isDust -> IsTransactionOutputDust to allow usage by rothschild * Add allowOrphan to SubmitTransaction RPC request * Remove all implementation from mempool.go * tidy go mod * Don't pass acceptedOrphans to handleNewBlockTransactions * Use t.Errorf in stead of t.Fatalf * Remove minimum relay fee from TestDust, as it's no longer configurable * Add separate VirtualDAASCore method for faster retrieval where it's repeated multiple times * Broadcast all transactions that were accepted * Don't re-use GetVirtualDAAScore in GetVirtualInfo - this causes a deadlock * Use real transaction count, and not Orphan * Get mempool config from outside, incorporating values received from cli * Use MinRelayFee and MaxOrphanTxs from global kaspad config * Add explanation for the seemingly redundant check for transaction version in checkTransactionStandard * Update some comment * Convert creation of acceptedTransactions to a single line * Move mempoolUTXOSet out of checkDoubleSpends * Add test for attempt to insert double spend into mempool * fillInputs: Skip check for coinbase - it's always false in mempool * Clarify comment about removeRedeemers when removing random orphan * Don't remove high-priority transactions in limitTransactionCount * Use mempool.removeTransaction in limitTransactionCount * Add mutex comment to handleNewBlockTransactions * Return error from limitTransactionCount * Pluralize the map types * mempoolUTXOSet.removeTransaction: Don't restore utxo if it was not created in mempool * Don't evacuate from orphanPool high-priority transactions * Disallow double-spends in orphan pool * Don't use exported (and locking) methods from inside mempool * Check for double spends in mempool during revalidateTransaction * Add checkOrphanDuplicate * Add orphan to acceptedOrphans, not current * Add TestHighPriorityTransactions * Fix off-by-one error in limitTransactionCount * Add TestRevalidateHighPriorityTransactions * Remove checkDoubleSpends from revalidateTransaction * Fix TestRevalidateHighPriorityTransactions * Move check for MaximumOrphanCount to beggining of maybeAddOrphan * Rename all map type to singulateToSingularMap * limitOrphanPool only after the orphan was added * TestDoubleSpendInMempool: use createChildTxWhenParentTxWasAddedByConsensus instead of createTransactionWithUTXOEntry * Fix some comments * Have separate min/max transaction versions for mempool * Add comment on defaultMaximumOrphanTransactionCount to keep it small as long as we have recursion * Fix comment * Rename: createChildTxWhenParentTxWasAddedByConsensus -> createChildTxWhereParentTxWasAddedByConsensus * Handle error from createChildTxWhereParentTxWasAddedByConsensus * Rename createChildTxWhereParentTxWasAddedByConsensus -> createChildAndParentTxsAndAddParentToConsensus * Convert all MaximumXXX constants to uint64 * Add comment * remove mutex comments
125 lines
3.9 KiB
Go
125 lines
3.9 KiB
Go
// Copyright (c) 2014-2016 The btcsuite developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package mempool
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// RuleError identifies a rule violation. It is used to indicate that
|
|
// processing of a transaction failed due to one of the many validation
|
|
// rules. The caller can use type assertions to determine if a failure was
|
|
// specifically due to a rule violation and use the Err field to access the
|
|
// underlying error, which will be either a TxRuleError or a
|
|
// ruleerrors.RuleError.
|
|
type RuleError struct {
|
|
Err error
|
|
}
|
|
|
|
// Error satisfies the error interface and prints human-readable errors.
|
|
func (e RuleError) Error() string {
|
|
if e.Err == nil {
|
|
return "<nil>"
|
|
}
|
|
return e.Err.Error()
|
|
}
|
|
|
|
// Unwrap unwraps the wrapped error
|
|
func (e RuleError) Unwrap() error {
|
|
return e.Err
|
|
}
|
|
|
|
// RejectCode represents a numeric value by which a remote peer indicates
|
|
// why a message was rejected.
|
|
type RejectCode uint8
|
|
|
|
// These constants define the various supported reject codes.
|
|
const (
|
|
RejectMalformed RejectCode = 0x01
|
|
RejectInvalid RejectCode = 0x10
|
|
RejectObsolete RejectCode = 0x11
|
|
RejectDuplicate RejectCode = 0x12
|
|
RejectNotRequested RejectCode = 0x13
|
|
RejectNonstandard RejectCode = 0x40
|
|
RejectDust RejectCode = 0x41
|
|
RejectInsufficientFee RejectCode = 0x42
|
|
RejectFinality RejectCode = 0x43
|
|
RejectDifficulty RejectCode = 0x44
|
|
RejectImmatureSpend RejectCode = 0x45
|
|
RejectBadOrphan RejectCode = 0x64
|
|
)
|
|
|
|
// Map of reject codes back strings for pretty printing.
|
|
var rejectCodeStrings = map[RejectCode]string{
|
|
RejectMalformed: "REJECT_MALFORMED",
|
|
RejectInvalid: "REJECT_INVALID",
|
|
RejectObsolete: "REJECT_OBSOLETE",
|
|
RejectDuplicate: "REJECT_DUPLICATE",
|
|
RejectNonstandard: "REJECT_NON_STANDARD",
|
|
RejectDust: "REJECT_DUST",
|
|
RejectInsufficientFee: "REJECT_INSUFFICIENT_FEE",
|
|
RejectFinality: "REJECT_FINALITY",
|
|
RejectDifficulty: "REJECT_DIFFICULTY",
|
|
RejectNotRequested: "REJECT_NOT_REQUESTED",
|
|
RejectImmatureSpend: "REJECT_IMMATURE_SPEND",
|
|
RejectBadOrphan: "REJECT_BAD_ORPHAN",
|
|
}
|
|
|
|
// String returns the RejectCode in human-readable form.
|
|
func (code RejectCode) String() string {
|
|
if s, ok := rejectCodeStrings[code]; ok {
|
|
return s
|
|
}
|
|
|
|
return fmt.Sprintf("Unknown RejectCode (%d)", uint8(code))
|
|
}
|
|
|
|
// TxRuleError identifies a rule violation. It is used to indicate that
|
|
// processing of a transaction failed due to one of the many validation
|
|
// rules. The caller can use type assertions to determine if a failure was
|
|
// specifically due to a rule violation and access the ErrorCode field to
|
|
// ascertain the specific reason for the rule violation.
|
|
type TxRuleError struct {
|
|
RejectCode RejectCode // The code to send with reject messages
|
|
Description string // Human readable description of the issue
|
|
}
|
|
|
|
// Error satisfies the error interface and prints human-readable errors.
|
|
func (e TxRuleError) Error() string {
|
|
return e.Description
|
|
}
|
|
|
|
// transactionRuleError creates an underlying TxRuleError with the given a set of
|
|
// arguments and returns a RuleError that encapsulates it.
|
|
func transactionRuleError(c RejectCode, desc string) RuleError {
|
|
return newRuleError(TxRuleError{RejectCode: c, Description: desc})
|
|
}
|
|
|
|
func newRuleError(err error) RuleError {
|
|
return RuleError{
|
|
Err: err,
|
|
}
|
|
}
|
|
|
|
// extractRejectCode attempts to return a relevant reject code for a given error
|
|
// by examining the error for known types. It will return true if a code
|
|
// was successfully extracted.
|
|
func extractRejectCode(err error) (RejectCode, bool) {
|
|
// Pull the underlying error out of a RuleError.
|
|
var ruleErr RuleError
|
|
if ok := errors.As(err, &ruleErr); ok {
|
|
err = ruleErr.Err
|
|
}
|
|
|
|
var trErr TxRuleError
|
|
if errors.As(err, &trErr) {
|
|
return trErr.RejectCode, true
|
|
}
|
|
|
|
return RejectInvalid, false
|
|
}
|