mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
83 lines
3.1 KiB
Go
83 lines
3.1 KiB
Go
package flowcontext
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/kaspanet/kaspad/app/appmessage"
|
|
"github.com/kaspanet/kaspad/app/protocol/flows/transactionrelay"
|
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
|
)
|
|
|
|
// TransactionIDPropagationInterval is the interval between transaction IDs propagations
|
|
const TransactionIDPropagationInterval = 500 * time.Millisecond
|
|
|
|
// AddTransaction adds transaction to the mempool and propagates it.
|
|
func (f *FlowContext) AddTransaction(tx *externalapi.DomainTransaction, allowOrphan bool) error {
|
|
acceptedTransactions, err := f.Domain().MiningManager().ValidateAndInsertTransaction(tx, true, allowOrphan)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
acceptedTransactionIDs := consensushashing.TransactionIDs(acceptedTransactions)
|
|
return f.EnqueueTransactionIDsForPropagation(acceptedTransactionIDs)
|
|
}
|
|
|
|
func (f *FlowContext) shouldRebroadcastTransactions() bool {
|
|
const rebroadcastInterval = 30 * time.Second
|
|
return time.Since(f.lastRebroadcastTime) > rebroadcastInterval
|
|
}
|
|
|
|
// SharedRequestedTransactions returns a *transactionrelay.SharedRequestedTransactions for sharing
|
|
// data about requested transactions between different peers.
|
|
func (f *FlowContext) SharedRequestedTransactions() *transactionrelay.SharedRequestedTransactions {
|
|
return f.sharedRequestedTransactions
|
|
}
|
|
|
|
// OnTransactionAddedToMempool notifies the handler function that a transaction
|
|
// has been added to the mempool
|
|
func (f *FlowContext) OnTransactionAddedToMempool() {
|
|
if f.onTransactionAddedToMempoolHandler != nil {
|
|
f.onTransactionAddedToMempoolHandler()
|
|
}
|
|
}
|
|
|
|
// EnqueueTransactionIDsForPropagation add the given transactions IDs to a set of IDs to
|
|
// propagate. The IDs will be broadcast to all peers within a single transaction Inv message.
|
|
// The broadcast itself may happen only during a subsequent call to this method
|
|
func (f *FlowContext) EnqueueTransactionIDsForPropagation(transactionIDs []*externalapi.DomainTransactionID) error {
|
|
f.transactionIDPropagationLock.Lock()
|
|
defer f.transactionIDPropagationLock.Unlock()
|
|
|
|
f.transactionIDsToPropagate = append(f.transactionIDsToPropagate, transactionIDs...)
|
|
|
|
return f.maybePropagateTransactions()
|
|
}
|
|
|
|
func (f *FlowContext) maybePropagateTransactions() error {
|
|
if time.Since(f.lastTransactionIDPropagationTime) < TransactionIDPropagationInterval &&
|
|
len(f.transactionIDsToPropagate) < appmessage.MaxInvPerTxInvMsg {
|
|
return nil
|
|
}
|
|
|
|
for len(f.transactionIDsToPropagate) > 0 {
|
|
transactionIDsToBroadcast := f.transactionIDsToPropagate
|
|
if len(transactionIDsToBroadcast) > appmessage.MaxInvPerTxInvMsg {
|
|
transactionIDsToBroadcast = f.transactionIDsToPropagate[:len(transactionIDsToBroadcast)]
|
|
}
|
|
log.Debugf("Transaction propagation: broadcasting %d transactions", len(transactionIDsToBroadcast))
|
|
|
|
inv := appmessage.NewMsgInvTransaction(transactionIDsToBroadcast)
|
|
err := f.Broadcast(inv)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
f.transactionIDsToPropagate = f.transactionIDsToPropagate[len(transactionIDsToBroadcast):]
|
|
}
|
|
|
|
f.lastTransactionIDPropagationTime = time.Now()
|
|
|
|
return nil
|
|
}
|