mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-11-24 06:25:55 +00:00
fix mempool accessing, rewrite get_mempool_entries_by_addresses
This commit is contained in:
parent
c5aade7e7f
commit
40a10edbb7
@ -1,14 +1,9 @@
|
|||||||
package rpchandlers
|
package rpchandlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/app/appmessage"
|
"github.com/kaspanet/kaspad/app/appmessage"
|
||||||
"github.com/kaspanet/kaspad/app/rpc/rpccontext"
|
"github.com/kaspanet/kaspad/app/rpc/rpccontext"
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
|
||||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||||
"github.com/kaspanet/kaspad/util"
|
"github.com/kaspanet/kaspad/util"
|
||||||
)
|
)
|
||||||
@ -20,128 +15,77 @@ func HandleGetMempoolEntriesByAddresses(context *rpccontext.Context, _ *router.R
|
|||||||
|
|
||||||
mempoolEntriesByAddresses := make([]*appmessage.MempoolEntryByAddress, 0)
|
mempoolEntriesByAddresses := make([]*appmessage.MempoolEntryByAddress, 0)
|
||||||
|
|
||||||
if !getMempoolEntriesByAddressesRequest.FilterTransactionPool {
|
for _, addressString := range getMempoolEntriesByAddressesRequest.Addresses {
|
||||||
transactionPoolTransactions := context.Domain.MiningManager().AllTransactions()
|
|
||||||
transactionPoolEntriesByAddresses, err := extractMempoolEntriesByAddressesFromTransactions(
|
address, err := util.DecodeAddress(addressString, context.Config.NetParams().Prefix)
|
||||||
context,
|
|
||||||
getMempoolEntriesByAddressesRequest.Addresses,
|
|
||||||
transactionPoolTransactions,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rpcError := &appmessage.RPCError{}
|
errorMessage := &appmessage.GetMempoolEntriesByAddressesResponseMessage{}
|
||||||
if !errors.As(err, &rpcError) {
|
errorMessage.Error = appmessage.RPCErrorf("Could not decode address '%s': %s", addressString, err)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
errorMessage := &appmessage.GetUTXOsByAddressesResponseMessage{}
|
|
||||||
errorMessage.Error = rpcError
|
|
||||||
return errorMessage, nil
|
return errorMessage, nil
|
||||||
}
|
}
|
||||||
mempoolEntriesByAddresses = append(mempoolEntriesByAddresses, transactionPoolEntriesByAddresses...)
|
|
||||||
}
|
|
||||||
|
|
||||||
if getMempoolEntriesByAddressesRequest.IncludeOrphanPool {
|
|
||||||
|
|
||||||
orphanPoolTransactions := context.Domain.MiningManager().AllOrphanTransactions()
|
|
||||||
orphanPoolEntriesByAddresse, err := extractMempoolEntriesByAddressesFromTransactions(
|
|
||||||
context,
|
|
||||||
getMempoolEntriesByAddressesRequest.Addresses,
|
|
||||||
orphanPoolTransactions,
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
rpcError := &appmessage.RPCError{}
|
|
||||||
if !errors.As(err, &rpcError) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
errorMessage := &appmessage.GetUTXOsByAddressesResponseMessage{}
|
|
||||||
errorMessage.Error = rpcError
|
|
||||||
return errorMessage, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
mempoolEntriesByAddresses = append(mempoolEntriesByAddresses, orphanPoolEntriesByAddresse...)
|
|
||||||
}
|
|
||||||
|
|
||||||
return appmessage.NewGetMempoolEntriesByAddressesResponseMessage(mempoolEntriesByAddresses), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//TO DO: optimize extractMempoolEntriesByAddressesFromTransactions
|
|
||||||
func extractMempoolEntriesByAddressesFromTransactions(context *rpccontext.Context, addresses []string, transactions []*externalapi.DomainTransaction, areOrphans bool) ([]*appmessage.MempoolEntryByAddress, error) {
|
|
||||||
mempoolEntriesByAddresses := make([]*appmessage.MempoolEntryByAddress, 0)
|
|
||||||
for _, addressString := range addresses {
|
|
||||||
_, err := util.DecodeAddress(addressString, context.Config.ActiveNetParams.Prefix)
|
|
||||||
if err != nil {
|
|
||||||
return nil, appmessage.RPCErrorf("Could not decode address '%s': %s", addressString, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
sending := make([]*appmessage.MempoolEntry, 0)
|
sending := make([]*appmessage.MempoolEntry, 0)
|
||||||
receiving := make([]*appmessage.MempoolEntry, 0)
|
receiving := make([]*appmessage.MempoolEntry, 0)
|
||||||
|
|
||||||
for _, transaction := range transactions {
|
if !getMempoolEntriesByAddressesRequest.FilterTransactionPool {
|
||||||
|
|
||||||
for i, input := range transaction.Inputs {
|
sendingInMempool, receivingInMempool, err := context.Domain.MiningManager().GetTransactionsByAddresses()
|
||||||
// TODO: Fix this
|
if err != nil {
|
||||||
if input.UTXOEntry == nil {
|
return nil, err
|
||||||
log.Errorf("Couldn't find UTXO entry for input %d in mempool transaction %s. This is a bug and should be fixed.", i, consensushashing.TransactionID(transaction))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
_, transactionSendingAddress, err := txscript.ExtractScriptPubKeyAddress(
|
|
||||||
input.UTXOEntry.ScriptPublicKey(),
|
|
||||||
context.Config.ActiveNetParams)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if addressString == transactionSendingAddress.String() {
|
|
||||||
rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction)
|
|
||||||
sending = append(
|
|
||||||
sending,
|
|
||||||
&appmessage.MempoolEntry{
|
|
||||||
Fee: transaction.Fee,
|
|
||||||
Transaction: rpcTransaction,
|
|
||||||
IsOrphan: areOrphans,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
break //one input is enough
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, output := range transaction.Outputs {
|
if transaction, found := sendingInMempool[address]; found {
|
||||||
_, transactionReceivingAddress, err := txscript.ExtractScriptPubKeyAddress(
|
rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction)
|
||||||
output.ScriptPublicKey,
|
sending = append(sending, &appmessage.MempoolEntry{
|
||||||
context.Config.ActiveNetParams,
|
Fee: transaction.Fee,
|
||||||
)
|
Transaction: rpcTransaction,
|
||||||
if err != nil {
|
IsOrphan: false})
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if addressString == transactionReceivingAddress.String() {
|
|
||||||
rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction)
|
|
||||||
receiving = append(
|
|
||||||
receiving,
|
|
||||||
&appmessage.MempoolEntry{
|
|
||||||
Fee: transaction.Fee,
|
|
||||||
Transaction: rpcTransaction,
|
|
||||||
IsOrphan: areOrphans,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
break //one output is enough
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Only append mempoolEntriesByAddress, if at least 1 mempoolEntry for the address is found.
|
if transaction, found := receivingInMempool[address]; found {
|
||||||
//This mimics the behaviour of GetUtxosByAddresses RPC call.
|
rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction)
|
||||||
if len(sending) > 0 || len(receiving) > 0 {
|
receiving = append(receiving, &appmessage.MempoolEntry{
|
||||||
mempoolEntriesByAddresses = append(
|
Fee: transaction.Fee,
|
||||||
mempoolEntriesByAddresses,
|
Transaction: rpcTransaction,
|
||||||
&appmessage.MempoolEntryByAddress{
|
IsOrphan: false})
|
||||||
Address: addressString,
|
|
||||||
Sending: sending,
|
|
||||||
Receiving: receiving,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if getMempoolEntriesByAddressesRequest.IncludeOrphanPool {
|
||||||
|
|
||||||
|
sendingInOrphanPool, receivingInOrphanPool, err := context.Domain.MiningManager().GetOrphanTransactionsByAddresses()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if transaction, found := sendingInOrphanPool[address]; found {
|
||||||
|
rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction)
|
||||||
|
sending = append(sending, &appmessage.MempoolEntry{
|
||||||
|
Fee: transaction.Fee,
|
||||||
|
Transaction: rpcTransaction,
|
||||||
|
IsOrphan: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
if transaction, found := receivingInOrphanPool[address]; found {
|
||||||
|
rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction)
|
||||||
|
receiving = append(receiving, &appmessage.MempoolEntry{
|
||||||
|
Fee: transaction.Fee,
|
||||||
|
Transaction: rpcTransaction,
|
||||||
|
IsOrphan: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sending) > 0 || len(receiving) > 0 {
|
||||||
|
mempoolEntriesByAddresses = append(
|
||||||
|
mempoolEntriesByAddresses,
|
||||||
|
&appmessage.MempoolEntryByAddress{
|
||||||
|
Address: address.String(),
|
||||||
|
Sending: sending,
|
||||||
|
Receiving: receiving,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return mempoolEntriesByAddresses, nil
|
|
||||||
|
return appmessage.NewGetMempoolEntriesByAddressesResponseMessage(mempoolEntriesByAddresses), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,7 @@ type factory struct{}
|
|||||||
func (f *factory) NewMiningManager(consensusReference consensusreference.ConsensusReference, params *dagconfig.Params,
|
func (f *factory) NewMiningManager(consensusReference consensusreference.ConsensusReference, params *dagconfig.Params,
|
||||||
mempoolConfig *mempoolpkg.Config) MiningManager {
|
mempoolConfig *mempoolpkg.Config) MiningManager {
|
||||||
|
|
||||||
mempool := mempoolpkg.New(mempoolConfig, consensusReference)
|
mempool := mempoolpkg.New(mempoolConfig, params, consensusReference)
|
||||||
blockTemplateBuilder := blocktemplatebuilder.New(consensusReference, mempool, params.MaxBlockMass, params.CoinbasePayloadScriptPublicKeyMaxLength)
|
blockTemplateBuilder := blocktemplatebuilder.New(consensusReference, mempool, params.MaxBlockMass, params.CoinbasePayloadScriptPublicKeyMaxLength)
|
||||||
|
|
||||||
return &miningManager{
|
return &miningManager{
|
||||||
|
|||||||
@ -95,7 +95,7 @@ func TestCalcMinRequiredTxRelayFee(t *testing.T) {
|
|||||||
mempoolConfig.MinimumRelayTransactionFee = test.minimumRelayTransactionFee
|
mempoolConfig.MinimumRelayTransactionFee = test.minimumRelayTransactionFee
|
||||||
tcAsConsensus := tc.(externalapi.Consensus)
|
tcAsConsensus := tc.(externalapi.Consensus)
|
||||||
tcAsConsensusPointer := &tcAsConsensus
|
tcAsConsensusPointer := &tcAsConsensus
|
||||||
mempool := New(mempoolConfig, consensusreference.NewConsensusReference(&tcAsConsensusPointer)).(*mempool)
|
mempool := New(mempoolConfig, tc.DAGParams(), consensusreference.NewConsensusReference(&tcAsConsensusPointer)).(*mempool)
|
||||||
|
|
||||||
got := mempool.minimumRequiredTransactionRelayFee(test.size)
|
got := mempool.minimumRequiredTransactionRelayFee(test.size)
|
||||||
if got != test.want {
|
if got != test.want {
|
||||||
@ -184,7 +184,7 @@ func TestIsTransactionOutputDust(t *testing.T) {
|
|||||||
mempoolConfig.MinimumRelayTransactionFee = test.minimumRelayTransactionFee
|
mempoolConfig.MinimumRelayTransactionFee = test.minimumRelayTransactionFee
|
||||||
tcAsConsensus := tc.(externalapi.Consensus)
|
tcAsConsensus := tc.(externalapi.Consensus)
|
||||||
tcAsConsensusPointer := &tcAsConsensus
|
tcAsConsensusPointer := &tcAsConsensus
|
||||||
mempool := New(mempoolConfig, consensusreference.NewConsensusReference(&tcAsConsensusPointer)).(*mempool)
|
mempool := New(mempoolConfig, tc.DAGParams(), consensusreference.NewConsensusReference(&tcAsConsensusPointer)).(*mempool)
|
||||||
|
|
||||||
res := mempool.IsTransactionOutputDust(&test.txOut)
|
res := mempool.IsTransactionOutputDust(&test.txOut)
|
||||||
if res != test.isDust {
|
if res != test.isDust {
|
||||||
@ -306,7 +306,7 @@ func TestCheckTransactionStandardInIsolation(t *testing.T) {
|
|||||||
tcAsConsensus := tc.(externalapi.Consensus)
|
tcAsConsensus := tc.(externalapi.Consensus)
|
||||||
tcAsConsensusPointer := &tcAsConsensus
|
tcAsConsensusPointer := &tcAsConsensus
|
||||||
consensusReference := consensusreference.NewConsensusReference(&tcAsConsensusPointer)
|
consensusReference := consensusreference.NewConsensusReference(&tcAsConsensusPointer)
|
||||||
mempool := New(mempoolConfig, consensusReference).(*mempool)
|
mempool := New(mempoolConfig, tc.DAGParams(), consensusReference).(*mempool)
|
||||||
|
|
||||||
// Ensure standardness is as expected.
|
// Ensure standardness is as expected.
|
||||||
err := mempool.checkTransactionStandardInIsolation(test.tx)
|
err := mempool.checkTransactionStandardInIsolation(test.tx)
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import (
|
|||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (mp *mempool) handleNewBlockTransactions(blockTransactions []*externalapi.DomainTransaction) (
|
func (mp *mempool) handleNewBlockTransactions(blockTransactions []*externalapi.DomainTransaction, clone bool) (
|
||||||
[]*externalapi.DomainTransaction, error) {
|
[]*externalapi.DomainTransaction, error) {
|
||||||
|
|
||||||
// Skip the coinbase transaction
|
// Skip the coinbase transaction
|
||||||
@ -30,7 +30,7 @@ func (mp *mempool) handleNewBlockTransactions(blockTransactions []*externalapi.D
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
acceptedOrphansFromThisTransaction, err := mp.orphansPool.processOrphansAfterAcceptedTransaction(transaction)
|
acceptedOrphansFromThisTransaction, err := mp.orphansPool.processOrphansAfterAcceptedTransaction(transaction, clone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
package mempool
|
package mempool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/kaspanet/kaspad/domain/consensusreference"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/kaspanet/kaspad/domain/consensusreference"
|
||||||
|
"github.com/kaspanet/kaspad/domain/dagconfig"
|
||||||
|
"github.com/kaspanet/kaspad/util"
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||||
miningmanagermodel "github.com/kaspanet/kaspad/domain/miningmanager/model"
|
miningmanagermodel "github.com/kaspanet/kaspad/domain/miningmanager/model"
|
||||||
)
|
)
|
||||||
@ -12,6 +15,7 @@ type mempool struct {
|
|||||||
mtx sync.RWMutex
|
mtx sync.RWMutex
|
||||||
|
|
||||||
config *Config
|
config *Config
|
||||||
|
params *dagconfig.Params
|
||||||
consensusReference consensusreference.ConsensusReference
|
consensusReference consensusreference.ConsensusReference
|
||||||
|
|
||||||
mempoolUTXOSet *mempoolUTXOSet
|
mempoolUTXOSet *mempoolUTXOSet
|
||||||
@ -20,9 +24,10 @@ type mempool struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New constructs a new mempool
|
// New constructs a new mempool
|
||||||
func New(config *Config, consensusReference consensusreference.ConsensusReference) miningmanagermodel.Mempool {
|
func New(config *Config, params *dagconfig.Params, consensusReference consensusreference.ConsensusReference) miningmanagermodel.Mempool {
|
||||||
mp := &mempool{
|
mp := &mempool{
|
||||||
config: config,
|
config: config,
|
||||||
|
params: params,
|
||||||
consensusReference: consensusReference,
|
consensusReference: consensusReference,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,35 +44,57 @@ func (mp *mempool) ValidateAndInsertTransaction(transaction *externalapi.DomainT
|
|||||||
mp.mtx.Lock()
|
mp.mtx.Lock()
|
||||||
defer mp.mtx.Unlock()
|
defer mp.mtx.Unlock()
|
||||||
|
|
||||||
return mp.validateAndInsertTransaction(transaction, isHighPriority, allowOrphan)
|
return mp.validateAndInsertTransaction(transaction, isHighPriority, allowOrphan, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mp *mempool) GetTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) {
|
func (mp *mempool) GetTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) {
|
||||||
mp.mtx.RLock()
|
mp.mtx.RLock()
|
||||||
defer mp.mtx.RUnlock()
|
defer mp.mtx.RUnlock()
|
||||||
|
|
||||||
return mp.transactionsPool.getTransaction(transactionID)
|
return mp.transactionsPool.getTransaction(transactionID, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mp *mempool) GetTransactionsByAddresses() (
|
||||||
|
sending map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
err error,
|
||||||
|
) {
|
||||||
|
mp.mtx.RLock()
|
||||||
|
defer mp.mtx.RUnlock()
|
||||||
|
|
||||||
|
return mp.transactionsPool.getTransactionsByAddresses(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mp *mempool) AllTransactions() []*externalapi.DomainTransaction {
|
func (mp *mempool) AllTransactions() []*externalapi.DomainTransaction {
|
||||||
mp.mtx.RLock()
|
mp.mtx.RLock()
|
||||||
defer mp.mtx.RUnlock()
|
defer mp.mtx.RUnlock()
|
||||||
|
|
||||||
return mp.transactionsPool.getAllTransactions()
|
return mp.transactionsPool.getAllTransactions(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mp *mempool) GetOrphanTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) {
|
func (mp *mempool) GetOrphanTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) {
|
||||||
mp.mtx.RLock()
|
mp.mtx.RLock()
|
||||||
defer mp.mtx.RUnlock()
|
defer mp.mtx.RUnlock()
|
||||||
|
|
||||||
return mp.orphansPool.getOrphanTransaction(transactionID)
|
return mp.orphansPool.getOrphanTransaction(transactionID, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mp *mempool) GetOrphanTransactionsByAddresses() (
|
||||||
|
sending map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
err error,
|
||||||
|
) {
|
||||||
|
mp.mtx.RLock()
|
||||||
|
defer mp.mtx.RUnlock()
|
||||||
|
|
||||||
|
return mp.orphansPool.getOrphanTransactionsByAddresses(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mp *mempool) AllOrphanTransactions() []*externalapi.DomainTransaction {
|
func (mp *mempool) AllOrphanTransactions() []*externalapi.DomainTransaction {
|
||||||
mp.mtx.RLock()
|
mp.mtx.RLock()
|
||||||
defer mp.mtx.RUnlock()
|
defer mp.mtx.RUnlock()
|
||||||
|
|
||||||
return mp.orphansPool.getAllOrphanTransactions()
|
return mp.orphansPool.getAllOrphanTransactions(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mp *mempool) TransactionCount() int {
|
func (mp *mempool) TransactionCount() int {
|
||||||
@ -83,21 +110,21 @@ func (mp *mempool) HandleNewBlockTransactions(transactions []*externalapi.Domain
|
|||||||
mp.mtx.Lock()
|
mp.mtx.Lock()
|
||||||
defer mp.mtx.Unlock()
|
defer mp.mtx.Unlock()
|
||||||
|
|
||||||
return mp.handleNewBlockTransactions(transactions)
|
return mp.handleNewBlockTransactions(transactions, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mp *mempool) BlockCandidateTransactions() []*externalapi.DomainTransaction {
|
func (mp *mempool) BlockCandidateTransactions() []*externalapi.DomainTransaction {
|
||||||
mp.mtx.RLock()
|
mp.mtx.RLock()
|
||||||
defer mp.mtx.RUnlock()
|
defer mp.mtx.RUnlock()
|
||||||
|
|
||||||
return mp.transactionsPool.allReadyTransactions()
|
return mp.transactionsPool.allReadyTransactions(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mp *mempool) RevalidateHighPriorityTransactions() (validTransactions []*externalapi.DomainTransaction, err error) {
|
func (mp *mempool) RevalidateHighPriorityTransactions() (validTransactions []*externalapi.DomainTransaction, err error) {
|
||||||
mp.mtx.Lock()
|
mp.mtx.Lock()
|
||||||
defer mp.mtx.Unlock()
|
defer mp.mtx.Unlock()
|
||||||
|
|
||||||
return mp.revalidateHighPriorityTransactions()
|
return mp.revalidateHighPriorityTransactions(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mp *mempool) RemoveTransactions(transactions []*externalapi.DomainTransaction, removeRedeemers bool) error {
|
func (mp *mempool) RemoveTransactions(transactions []*externalapi.DomainTransaction, removeRedeemers bool) error {
|
||||||
|
|||||||
@ -51,7 +51,7 @@ func (mpus *mempoolUTXOSet) addTransaction(transaction *model.MempoolTransaction
|
|||||||
func (mpus *mempoolUTXOSet) removeTransaction(transaction *model.MempoolTransaction) {
|
func (mpus *mempoolUTXOSet) removeTransaction(transaction *model.MempoolTransaction) {
|
||||||
for _, input := range transaction.Transaction().Inputs {
|
for _, input := range transaction.Transaction().Inputs {
|
||||||
// If the transaction creating the output spent by this input is in the mempool - restore it's UTXO
|
// If the transaction creating the output spent by this input is in the mempool - restore it's UTXO
|
||||||
if _, ok := mpus.mempool.transactionsPool.getTransaction(&input.PreviousOutpoint.TransactionID); ok {
|
if _, ok := mpus.mempool.transactionsPool.getTransaction(&input.PreviousOutpoint.TransactionID, false); ok {
|
||||||
mpus.poolUnspentOutputs[input.PreviousOutpoint] = input.UTXOEntry
|
mpus.poolUnspentOutputs[input.PreviousOutpoint] = input.UTXOEntry
|
||||||
}
|
}
|
||||||
delete(mpus.transactionByPreviousOutpoint, input.PreviousOutpoint)
|
delete(mpus.transactionByPreviousOutpoint, input.PreviousOutpoint)
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||||
|
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
||||||
|
"github.com/kaspanet/kaspad/util"
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||||
|
|
||||||
@ -134,7 +136,7 @@ func (op *orphansPool) addOrphan(transaction *externalapi.DomainTransaction, isH
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *orphansPool) processOrphansAfterAcceptedTransaction(acceptedTransaction *externalapi.DomainTransaction) (
|
func (op *orphansPool) processOrphansAfterAcceptedTransaction(acceptedTransaction *externalapi.DomainTransaction, clone bool) (
|
||||||
acceptedOrphans []*externalapi.DomainTransaction, err error) {
|
acceptedOrphans []*externalapi.DomainTransaction, err error) {
|
||||||
|
|
||||||
acceptedOrphans = []*externalapi.DomainTransaction{}
|
acceptedOrphans = []*externalapi.DomainTransaction{}
|
||||||
@ -169,7 +171,11 @@ func (op *orphansPool) processOrphansAfterAcceptedTransaction(acceptedTransactio
|
|||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
acceptedOrphans = append(acceptedOrphans, orphan.Transaction())
|
if clone {
|
||||||
|
acceptedOrphans = append(acceptedOrphans, orphan.Transaction().Clone())
|
||||||
|
} else {
|
||||||
|
acceptedOrphans = append(acceptedOrphans, orphan.Transaction())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,17 +335,67 @@ func (op *orphansPool) randomNonHighPriorityOrphan() *model.OrphanTransaction {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *orphansPool) getOrphanTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) {
|
func (op *orphansPool) getOrphanTransaction(transactionID *externalapi.DomainTransactionID, clone bool) (*externalapi.DomainTransaction, bool) {
|
||||||
if orphanTransaction, ok := op.allOrphans[*transactionID]; ok {
|
if orphanTransaction, ok := op.allOrphans[*transactionID]; ok {
|
||||||
|
if clone {
|
||||||
|
return orphanTransaction.Transaction().Clone(), true
|
||||||
|
}
|
||||||
return orphanTransaction.Transaction(), true
|
return orphanTransaction.Transaction(), true
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op *orphansPool) getAllOrphanTransactions() []*externalapi.DomainTransaction {
|
func (op *orphansPool) getOrphanTransactionsByAddresses(clone bool) (
|
||||||
allOrphanTransactions := make([]*externalapi.DomainTransaction, 0, len(op.allOrphans))
|
sending map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
err error) {
|
||||||
|
sending = make(map[util.Address]*externalapi.DomainTransaction)
|
||||||
|
receiving = make(map[util.Address]*externalapi.DomainTransaction)
|
||||||
|
var transaction *externalapi.DomainTransaction
|
||||||
for _, mempoolTransaction := range op.allOrphans {
|
for _, mempoolTransaction := range op.allOrphans {
|
||||||
allOrphanTransactions = append(allOrphanTransactions, mempoolTransaction.Transaction())
|
if clone {
|
||||||
|
transaction = mempoolTransaction.Transaction().Clone()
|
||||||
|
} else {
|
||||||
|
transaction = mempoolTransaction.Transaction()
|
||||||
|
}
|
||||||
|
for _, input := range transaction.Inputs {
|
||||||
|
if input.UTXOEntry == nil { //this is not a bug, but a valid state of orphan transactions with missing outpoints.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_, address, err := txscript.ExtractScriptPubKeyAddress(input.UTXOEntry.ScriptPublicKey(), op.mempool.params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if address == nil { //none standard tx
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sending[address] = transaction
|
||||||
|
for _, output := range transaction.Outputs {
|
||||||
|
_, address, err := txscript.ExtractScriptPubKeyAddress(output.ScriptPublicKey, op.mempool.params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if address == nil { //none standard tx
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
receiving[address] = transaction
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sending, receiving, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (op *orphansPool) getAllOrphanTransactions(clone bool) []*externalapi.DomainTransaction {
|
||||||
|
allOrphanTransactions := make([]*externalapi.DomainTransaction, len(op.allOrphans))
|
||||||
|
i := 0
|
||||||
|
for _, mempoolTransaction := range op.allOrphans {
|
||||||
|
if clone {
|
||||||
|
allOrphanTransactions[i] = mempoolTransaction.Transaction().Clone()
|
||||||
|
} else {
|
||||||
|
allOrphanTransactions[i] = mempoolTransaction.Transaction()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return allOrphanTransactions
|
return allOrphanTransactions
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,22 +6,35 @@ import (
|
|||||||
"github.com/kaspanet/kaspad/infrastructure/logger"
|
"github.com/kaspanet/kaspad/infrastructure/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (mp *mempool) revalidateHighPriorityTransactions() ([]*externalapi.DomainTransaction, error) {
|
func (mp *mempool) revalidateHighPriorityTransactions(clone bool) ([]*externalapi.DomainTransaction, error) {
|
||||||
onEnd := logger.LogAndMeasureExecutionTime(log, "revalidateHighPriorityTransactions")
|
onEnd := logger.LogAndMeasureExecutionTime(log, "revalidateHighPriorityTransactions")
|
||||||
defer onEnd()
|
defer onEnd()
|
||||||
|
|
||||||
validTransactions := []*externalapi.DomainTransaction{}
|
validTransactions := []*externalapi.DomainTransaction{}
|
||||||
|
if !clone {
|
||||||
|
for _, transaction := range mp.transactionsPool.highPriorityTransactions {
|
||||||
|
isValid, err := mp.revalidateTransaction(transaction)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !isValid {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
for _, transaction := range mp.transactionsPool.highPriorityTransactions {
|
validTransactions = append(validTransactions, transaction.Transaction())
|
||||||
isValid, err := mp.revalidateTransaction(transaction)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !isValid {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for _, transaction := range mp.transactionsPool.highPriorityTransactions {
|
||||||
|
isValid, err := mp.revalidateTransaction(transaction)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !isValid {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
validTransactions = append(validTransactions, transaction.Transaction())
|
validTransactions = append(validTransactions, transaction.Transaction().Clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return validTransactions, nil
|
return validTransactions, nil
|
||||||
|
|||||||
@ -6,7 +6,9 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||||
|
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
||||||
"github.com/kaspanet/kaspad/domain/miningmanager/mempool/model"
|
"github.com/kaspanet/kaspad/domain/miningmanager/mempool/model"
|
||||||
|
"github.com/kaspanet/kaspad/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
type transactionsPool struct {
|
type transactionsPool struct {
|
||||||
@ -130,12 +132,16 @@ func (tp *transactionsPool) expireOldTransactions() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tp *transactionsPool) allReadyTransactions() []*externalapi.DomainTransaction {
|
func (tp *transactionsPool) allReadyTransactions(clone bool) []*externalapi.DomainTransaction {
|
||||||
result := []*externalapi.DomainTransaction{}
|
result := []*externalapi.DomainTransaction{}
|
||||||
|
|
||||||
for _, mempoolTransaction := range tp.allTransactions {
|
for _, mempoolTransaction := range tp.allTransactions {
|
||||||
if len(mempoolTransaction.ParentTransactionsInPool()) == 0 {
|
if len(mempoolTransaction.ParentTransactionsInPool()) == 0 {
|
||||||
result = append(result, mempoolTransaction.Transaction())
|
if clone {
|
||||||
|
result = append(result, mempoolTransaction.Transaction().Clone())
|
||||||
|
} else {
|
||||||
|
result = append(result, mempoolTransaction.Transaction())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,17 +210,63 @@ func (tp *transactionsPool) limitTransactionCount() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tp *transactionsPool) getTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) {
|
func (tp *transactionsPool) getTransaction(transactionID *externalapi.DomainTransactionID, clone bool) (*externalapi.DomainTransaction, bool) {
|
||||||
if mempoolTransaction, ok := tp.allTransactions[*transactionID]; ok {
|
if mempoolTransaction, ok := tp.allTransactions[*transactionID]; ok {
|
||||||
|
if clone {
|
||||||
|
return mempoolTransaction.Transaction().Clone(), true
|
||||||
|
}
|
||||||
return mempoolTransaction.Transaction(), true
|
return mempoolTransaction.Transaction(), true
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tp *transactionsPool) getAllTransactions() []*externalapi.DomainTransaction {
|
func (tp *transactionsPool) getTransactionsByAddresses(clone bool) (
|
||||||
allTransactions := make([]*externalapi.DomainTransaction, 0, len(tp.allTransactions))
|
sending map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
err error) {
|
||||||
|
sending = make(map[util.Address]*externalapi.DomainTransaction)
|
||||||
|
receiving = make(map[util.Address]*externalapi.DomainTransaction)
|
||||||
|
var transaction *externalapi.DomainTransaction
|
||||||
for _, mempoolTransaction := range tp.allTransactions {
|
for _, mempoolTransaction := range tp.allTransactions {
|
||||||
allTransactions = append(allTransactions, mempoolTransaction.Transaction())
|
if clone {
|
||||||
|
transaction = mempoolTransaction.Transaction().Clone()
|
||||||
|
} else {
|
||||||
|
transaction = mempoolTransaction.Transaction()
|
||||||
|
}
|
||||||
|
for _, input := range transaction.Inputs {
|
||||||
|
_, address, err := txscript.ExtractScriptPubKeyAddress(input.UTXOEntry.ScriptPublicKey(), tp.mempool.params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if address == nil { //ignore none-standard script
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sending[address] = transaction
|
||||||
|
for _, output := range transaction.Outputs {
|
||||||
|
_, address, err := txscript.ExtractScriptPubKeyAddress(output.ScriptPublicKey, tp.mempool.params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if address == nil { //ignore none-standard script
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
receiving[address] = transaction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sending, receiving, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tp *transactionsPool) getAllTransactions(clone bool) []*externalapi.DomainTransaction {
|
||||||
|
allTransactions := make([]*externalapi.DomainTransaction, len(tp.allTransactions))
|
||||||
|
i := 0
|
||||||
|
for _, mempoolTransaction := range tp.allTransactions {
|
||||||
|
if clone {
|
||||||
|
allTransactions[i] = mempoolTransaction.Transaction().Clone()
|
||||||
|
} else {
|
||||||
|
allTransactions[i] = mempoolTransaction.Transaction()
|
||||||
|
}
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
return allTransactions
|
return allTransactions
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (mp *mempool) validateAndInsertTransaction(transaction *externalapi.DomainTransaction, isHighPriority bool,
|
func (mp *mempool) validateAndInsertTransaction(transaction *externalapi.DomainTransaction, isHighPriority bool,
|
||||||
allowOrphan bool) (acceptedTransactions []*externalapi.DomainTransaction, err error) {
|
allowOrphan bool, clone bool) (acceptedTransactions []*externalapi.DomainTransaction, err error) {
|
||||||
|
|
||||||
onEnd := logger.LogAndMeasureExecutionTime(log,
|
onEnd := logger.LogAndMeasureExecutionTime(log,
|
||||||
fmt.Sprintf("validateAndInsertTransaction %s", consensushashing.TransactionID(transaction)))
|
fmt.Sprintf("validateAndInsertTransaction %s", consensushashing.TransactionID(transaction)))
|
||||||
@ -49,12 +49,16 @@ func (mp *mempool) validateAndInsertTransaction(transaction *externalapi.DomainT
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
acceptedOrphans, err := mp.orphansPool.processOrphansAfterAcceptedTransaction(mempoolTransaction.Transaction())
|
acceptedOrphans, err := mp.orphansPool.processOrphansAfterAcceptedTransaction(mempoolTransaction.Transaction(), clone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
acceptedTransactions = append([]*externalapi.DomainTransaction{transaction}, acceptedOrphans...)
|
if clone {
|
||||||
|
acceptedTransactions = append([]*externalapi.DomainTransaction{transaction.Clone()}, acceptedOrphans...)
|
||||||
|
} else {
|
||||||
|
acceptedTransactions = append([]*externalapi.DomainTransaction{transaction}, acceptedOrphans...)
|
||||||
|
}
|
||||||
|
|
||||||
err = mp.transactionsPool.limitTransactionCount()
|
err = mp.transactionsPool.limitTransactionCount()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||||
"github.com/kaspanet/kaspad/domain/consensusreference"
|
"github.com/kaspanet/kaspad/domain/consensusreference"
|
||||||
miningmanagermodel "github.com/kaspanet/kaspad/domain/miningmanager/model"
|
miningmanagermodel "github.com/kaspanet/kaspad/domain/miningmanager/model"
|
||||||
|
"github.com/kaspanet/kaspad/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MiningManager creates block templates for mining as well as maintaining
|
// MiningManager creates block templates for mining as well as maintaining
|
||||||
@ -16,8 +17,16 @@ type MiningManager interface {
|
|||||||
ClearBlockTemplate()
|
ClearBlockTemplate()
|
||||||
GetBlockTemplateBuilder() miningmanagermodel.BlockTemplateBuilder
|
GetBlockTemplateBuilder() miningmanagermodel.BlockTemplateBuilder
|
||||||
GetTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool)
|
GetTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool)
|
||||||
|
GetTransactionsByAddresses() (
|
||||||
|
sending map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
err error)
|
||||||
AllTransactions() []*externalapi.DomainTransaction
|
AllTransactions() []*externalapi.DomainTransaction
|
||||||
GetOrphanTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool)
|
GetOrphanTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool)
|
||||||
|
GetOrphanTransactionsByAddresses() (
|
||||||
|
sending map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
err error)
|
||||||
AllOrphanTransactions() []*externalapi.DomainTransaction
|
AllOrphanTransactions() []*externalapi.DomainTransaction
|
||||||
TransactionCount() int
|
TransactionCount() int
|
||||||
HandleNewBlockTransactions(txs []*externalapi.DomainTransaction) ([]*externalapi.DomainTransaction, error)
|
HandleNewBlockTransactions(txs []*externalapi.DomainTransaction) ([]*externalapi.DomainTransaction, error)
|
||||||
@ -118,12 +127,26 @@ func (mm *miningManager) AllTransactions() []*externalapi.DomainTransaction {
|
|||||||
return mm.mempool.AllTransactions()
|
return mm.mempool.AllTransactions()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mm *miningManager) GetTransactionsByAddresses() (
|
||||||
|
sending map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
err error) {
|
||||||
|
return mm.mempool.GetTransactionsByAddresses()
|
||||||
|
}
|
||||||
|
|
||||||
func (mm *miningManager) GetOrphanTransaction(
|
func (mm *miningManager) GetOrphanTransaction(
|
||||||
transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) {
|
transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) {
|
||||||
|
|
||||||
return mm.mempool.GetOrphanTransaction(transactionID)
|
return mm.mempool.GetOrphanTransaction(transactionID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mm *miningManager) GetOrphanTransactionsByAddresses() (
|
||||||
|
sending map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
err error) {
|
||||||
|
return mm.mempool.GetTransactionsByAddresses()
|
||||||
|
}
|
||||||
|
|
||||||
func (mm *miningManager) AllOrphanTransactions() []*externalapi.DomainTransaction {
|
func (mm *miningManager) AllOrphanTransactions() []*externalapi.DomainTransaction {
|
||||||
|
|
||||||
return mm.mempool.AllOrphanTransactions()
|
return mm.mempool.AllOrphanTransactions()
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package model
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||||
|
"github.com/kaspanet/kaspad/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Mempool maintains a set of known transactions that
|
// Mempool maintains a set of known transactions that
|
||||||
@ -13,8 +14,16 @@ type Mempool interface {
|
|||||||
acceptedTransactions []*externalapi.DomainTransaction, err error)
|
acceptedTransactions []*externalapi.DomainTransaction, err error)
|
||||||
RemoveTransactions(txs []*externalapi.DomainTransaction, removeRedeemers bool) error
|
RemoveTransactions(txs []*externalapi.DomainTransaction, removeRedeemers bool) error
|
||||||
GetTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool)
|
GetTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool)
|
||||||
|
GetTransactionsByAddresses() (
|
||||||
|
sending map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
err error)
|
||||||
AllTransactions() []*externalapi.DomainTransaction
|
AllTransactions() []*externalapi.DomainTransaction
|
||||||
GetOrphanTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool)
|
GetOrphanTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool)
|
||||||
|
GetOrphanTransactionsByAddresses() (
|
||||||
|
sending map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||||
|
err error)
|
||||||
AllOrphanTransactions() []*externalapi.DomainTransaction
|
AllOrphanTransactions() []*externalapi.DomainTransaction
|
||||||
TransactionCount() int
|
TransactionCount() int
|
||||||
RevalidateHighPriorityTransactions() (validTransactions []*externalapi.DomainTransaction, err error)
|
RevalidateHighPriorityTransactions() (validTransactions []*externalapi.DomainTransaction, err error)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user