mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-11-23 22:15:54 +00:00
Revalidate transactions before rebroadcast
This commit is contained in:
parent
4f4a8934e7
commit
903fa58957
@ -80,7 +80,11 @@ func (f *FlowContext) broadcastTransactionsAfterBlockAdded(
|
|||||||
|
|
||||||
var txIDsToRebroadcast []*externalapi.DomainTransactionID
|
var txIDsToRebroadcast []*externalapi.DomainTransactionID
|
||||||
if f.shouldRebroadcastTransactions() {
|
if f.shouldRebroadcastTransactions() {
|
||||||
txIDsToRebroadcast = f.txIDsToRebroadcast()
|
var err error
|
||||||
|
txIDsToRebroadcast, err = f.txIDsToRebroadcast()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
txIDsToBroadcast := make([]*externalapi.DomainTransactionID, len(transactionsAcceptedToMempool)+len(txIDsToRebroadcast))
|
txIDsToBroadcast := make([]*externalapi.DomainTransactionID, len(transactionsAcceptedToMempool)+len(txIDsToRebroadcast))
|
||||||
|
|||||||
@ -44,17 +44,25 @@ func (f *FlowContext) shouldRebroadcastTransactions() bool {
|
|||||||
return time.Since(f.lastRebroadcastTime) > rebroadcastInterval
|
return time.Since(f.lastRebroadcastTime) > rebroadcastInterval
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FlowContext) txIDsToRebroadcast() []*externalapi.DomainTransactionID {
|
func (f *FlowContext) txIDsToRebroadcast() ([]*externalapi.DomainTransactionID, error) {
|
||||||
f.transactionsToRebroadcastLock.Lock()
|
f.transactionsToRebroadcastLock.Lock()
|
||||||
defer f.transactionsToRebroadcastLock.Unlock()
|
defer f.transactionsToRebroadcastLock.Unlock()
|
||||||
|
|
||||||
txIDs := make([]*externalapi.DomainTransactionID, len(f.transactionsToRebroadcast))
|
txIDs := make([]*externalapi.DomainTransactionID, 0, len(f.transactionsToRebroadcast))
|
||||||
i := 0
|
i := 0
|
||||||
for _, tx := range f.transactionsToRebroadcast {
|
for _, tx := range f.transactionsToRebroadcast {
|
||||||
txIDs[i] = consensushashing.TransactionID(tx)
|
isValid, err := f.Domain().MiningManager().RevalidateTransaction(tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !isValid {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
txIDs = append(txIDs, consensushashing.TransactionID(tx))
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
return txIDs
|
return txIDs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SharedRequestedTransactions returns a *transactionrelay.SharedRequestedTransactions for sharing
|
// SharedRequestedTransactions returns a *transactionrelay.SharedRequestedTransactions for sharing
|
||||||
|
|||||||
1
domain/miningmanager/mempool/expiration_heap.go
Normal file
1
domain/miningmanager/mempool/expiration_heap.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package mempool
|
||||||
@ -7,22 +7,19 @@ package mempool
|
|||||||
import (
|
import (
|
||||||
"container/list"
|
"container/list"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/kaspanet/kaspad/domain/dagconfig"
|
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/infrastructure/logger"
|
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
|
||||||
|
|
||||||
consensusexternalapi "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
consensusexternalapi "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||||
|
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
|
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
|
||||||
|
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
||||||
|
"github.com/kaspanet/kaspad/domain/dagconfig"
|
||||||
miningmanagermodel "github.com/kaspanet/kaspad/domain/miningmanager/model"
|
miningmanagermodel "github.com/kaspanet/kaspad/domain/miningmanager/model"
|
||||||
|
"github.com/kaspanet/kaspad/infrastructure/logger"
|
||||||
"github.com/kaspanet/kaspad/util"
|
"github.com/kaspanet/kaspad/util"
|
||||||
"github.com/kaspanet/kaspad/util/mstime"
|
"github.com/kaspanet/kaspad/util/mstime"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -164,6 +161,10 @@ type txDescriptor struct {
|
|||||||
// one that is accepted to pool, but cannot be mined in next block because it
|
// one that is accepted to pool, but cannot be mined in next block because it
|
||||||
// depends on outputs of accepted, but still not mined transaction
|
// depends on outputs of accepted, but still not mined transaction
|
||||||
depCount int
|
depCount int
|
||||||
|
|
||||||
|
// expirationDAAScore is the virtual DAA score at which this transaction is expired
|
||||||
|
// if expirationDAAScore == 0 - the transaction never expires.
|
||||||
|
expirationDAAScore uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// orphanTx is normal transaction that references an ancestor transaction
|
// orphanTx is normal transaction that references an ancestor transaction
|
||||||
@ -411,6 +412,13 @@ type transactionAndOutpoint struct {
|
|||||||
outpoint *consensusexternalapi.DomainOutpoint
|
outpoint *consensusexternalapi.DomainOutpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mp *mempool) removeTransactionAndItsChainedTransactionsWithLock(transaction *consensusexternalapi.DomainTransaction) error {
|
||||||
|
mp.mtx.Lock()
|
||||||
|
defer mp.mtx.Unlock()
|
||||||
|
|
||||||
|
return mp.removeTransactionAndItsChainedTransactions(transaction)
|
||||||
|
}
|
||||||
|
|
||||||
// removeTransactionAndItsChainedTransactions removes a transaction and all of its chained transaction from the mempool.
|
// removeTransactionAndItsChainedTransactions removes a transaction and all of its chained transaction from the mempool.
|
||||||
// This function MUST be called with the mempool lock held (for writes).
|
// This function MUST be called with the mempool lock held (for writes).
|
||||||
func (mp *mempool) removeTransactionAndItsChainedTransactions(transaction *consensusexternalapi.DomainTransaction) error {
|
func (mp *mempool) removeTransactionAndItsChainedTransactions(transaction *consensusexternalapi.DomainTransaction) error {
|
||||||
@ -899,7 +907,9 @@ func (mp *mempool) processOrphans(acceptedTx *consensusexternalapi.DomainTransac
|
|||||||
// the passed one being accepted.
|
// the passed one being accepted.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *mempool) ValidateAndInsertTransaction(tx *consensusexternalapi.DomainTransaction, allowOrphan bool) error {
|
func (mp *mempool) ValidateAndInsertTransaction(
|
||||||
|
tx *consensusexternalapi.DomainTransaction, expirationDAAScore uint64, allowOrphan bool) error {
|
||||||
|
|
||||||
log.Tracef("Processing transaction %s", consensushashing.TransactionID(tx))
|
log.Tracef("Processing transaction %s", consensushashing.TransactionID(tx))
|
||||||
|
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
@ -1042,3 +1052,25 @@ func (mp *mempool) RemoveTransactions(txs []*consensusexternalapi.DomainTransact
|
|||||||
|
|
||||||
return mp.removeTransactionsFromPool(txs)
|
return mp.removeTransactionsFromPool(txs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RevalidateTransaction revalidates given transaction, and removes from mempool if it isn't valid
|
||||||
|
func (mp *mempool) RevalidateTransaction(tx *consensusexternalapi.DomainTransaction) (isValid bool, err error) {
|
||||||
|
tx = tx.Clone()
|
||||||
|
|
||||||
|
_ = mp.mempoolUTXOSet.populateUTXOEntries(tx)
|
||||||
|
|
||||||
|
err = mp.consensus.ValidateTransactionAndPopulateWithConsensusData(tx)
|
||||||
|
if err != nil {
|
||||||
|
if errors.As(err, &ruleerrors.RuleError{}) {
|
||||||
|
log.Debugf("Transaction %s was found invalid during revalidate and therefore is being removed from mempool",
|
||||||
|
consensushashing.TransactionID(tx))
|
||||||
|
err := mp.removeTransactionAndItsChainedTransactionsWithLock(tx)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ type MiningManager interface {
|
|||||||
TransactionCount() int
|
TransactionCount() int
|
||||||
HandleNewBlockTransactions(txs []*consensusexternalapi.DomainTransaction) ([]*consensusexternalapi.DomainTransaction, error)
|
HandleNewBlockTransactions(txs []*consensusexternalapi.DomainTransaction) ([]*consensusexternalapi.DomainTransaction, error)
|
||||||
ValidateAndInsertTransaction(transaction *consensusexternalapi.DomainTransaction, allowOrphan bool) error
|
ValidateAndInsertTransaction(transaction *consensusexternalapi.DomainTransaction, allowOrphan bool) error
|
||||||
|
RevalidateTransaction(tx *consensusexternalapi.DomainTransaction) (isValid bool, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type miningManager struct {
|
type miningManager struct {
|
||||||
@ -51,3 +52,7 @@ func (mm *miningManager) AllTransactions() []*consensusexternalapi.DomainTransac
|
|||||||
func (mm *miningManager) TransactionCount() int {
|
func (mm *miningManager) TransactionCount() int {
|
||||||
return mm.mempool.TransactionCount()
|
return mm.mempool.TransactionCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mm *miningManager) RevalidateTransaction(tx *consensusexternalapi.DomainTransaction) (isValid bool, err error) {
|
||||||
|
return mm.mempool.RevalidateTransaction(tx)
|
||||||
|
}
|
||||||
|
|||||||
@ -14,4 +14,5 @@ type Mempool interface {
|
|||||||
GetTransaction(transactionID *consensusexternalapi.DomainTransactionID) (*consensusexternalapi.DomainTransaction, bool)
|
GetTransaction(transactionID *consensusexternalapi.DomainTransactionID) (*consensusexternalapi.DomainTransaction, bool)
|
||||||
AllTransactions() []*consensusexternalapi.DomainTransaction
|
AllTransactions() []*consensusexternalapi.DomainTransaction
|
||||||
TransactionCount() int
|
TransactionCount() int
|
||||||
|
RevalidateTransaction(tx *consensusexternalapi.DomainTransaction) (isValid bool, err error)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user