diff --git a/app/rpc/rpccontext/notificationmanager.go b/app/rpc/rpccontext/notificationmanager.go index e9b3ef98c..0ba132f17 100644 --- a/app/rpc/rpccontext/notificationmanager.go +++ b/app/rpc/rpccontext/notificationmanager.go @@ -5,6 +5,7 @@ import ( "github.com/kaspanet/kaspad/domain/dagconfig" + "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" "github.com/kaspanet/kaspad/domain/consensus/utils/txscript" "github.com/kaspanet/kaspad/app/appmessage" @@ -421,7 +422,7 @@ func (nl *NotificationListener) convertUTXOChangesToUTXOsChangedNotification( } func (nl *NotificationListener) scriptPubKeyStringToAddressString(scriptPublicKeyString utxoindex.ScriptPublicKeyString) (string, error) { - scriptPubKey := utxoindex.ConvertStringToScriptPublicKey(scriptPublicKeyString) + scriptPubKey := externalapi.NewScriptPublicKeyFromString(string(scriptPublicKeyString)) // ignore error because it is often returned when the script is of unknown type scriptType, address, err := txscript.ExtractScriptPubKeyAddress(scriptPubKey, nl.params) diff --git a/app/rpc/rpccontext/utxos_by_addresses.go b/app/rpc/rpccontext/utxos_by_addresses.go index d9ca04aed..00251589c 100644 --- a/app/rpc/rpccontext/utxos_by_addresses.go +++ b/app/rpc/rpccontext/utxos_by_addresses.go @@ -32,22 +32,6 @@ func ConvertUTXOOutpointEntryPairsToUTXOsByAddressesEntries(address string, pair return utxosByAddressesEntries } -// convertUTXOOutpointsToUTXOsByAddressesEntries converts -// UTXOOutpoints to a slice of UTXOsByAddressesEntry -func convertUTXOOutpointsToUTXOsByAddressesEntries(address string, outpoints utxoindex.UTXOOutpoints) []*appmessage.UTXOsByAddressesEntry { - utxosByAddressesEntries := make([]*appmessage.UTXOsByAddressesEntry, 0, len(outpoints)) - for outpoint := range outpoints { - utxosByAddressesEntries = append(utxosByAddressesEntries, &appmessage.UTXOsByAddressesEntry{ - Address: address, - Outpoint: &appmessage.RPCOutpoint{ - TransactionID: outpoint.TransactionID.String(), - Index: outpoint.Index, - }, - }) - } - return utxosByAddressesEntries -} - // ConvertAddressStringsToUTXOsChangedNotificationAddresses converts address strings // to UTXOsChangedNotificationAddresses func (ctx *Context) ConvertAddressStringsToUTXOsChangedNotificationAddresses( @@ -63,7 +47,7 @@ func (ctx *Context) ConvertAddressStringsToUTXOsChangedNotificationAddresses( if err != nil { return nil, errors.Errorf("Could not create a scriptPublicKey for address '%s': %s", addressString, err) } - scriptPublicKeyString := utxoindex.ConvertScriptPublicKeyToString(scriptPublicKey) + scriptPublicKeyString := utxoindex.ScriptPublicKeyString(scriptPublicKey.String()) addresses[i] = &UTXOsChangedNotificationAddress{ Address: addressString, ScriptPublicKeyString: scriptPublicKeyString, diff --git a/app/rpc/rpchandlers/get_mempool_entries_by_addresses.go b/app/rpc/rpchandlers/get_mempool_entries_by_addresses.go index e7be7e97a..0e9bf65f3 100644 --- a/app/rpc/rpchandlers/get_mempool_entries_by_addresses.go +++ b/app/rpc/rpchandlers/get_mempool_entries_by_addresses.go @@ -3,6 +3,7 @@ package rpchandlers import ( "github.com/kaspanet/kaspad/app/appmessage" "github.com/kaspanet/kaspad/app/rpc/rpccontext" + "github.com/kaspanet/kaspad/domain/consensus/utils/txscript" "github.com/kaspanet/kaspad/infrastructure/network/netadapter/router" "github.com/kaspanet/kaspad/util" @@ -32,9 +33,16 @@ func HandleGetMempoolEntriesByAddresses(context *rpccontext.Context, _ *router.R sending := make([]*appmessage.MempoolEntry, 0) receiving := make([]*appmessage.MempoolEntry, 0) + scriptPublicKey, err := txscript.PayToAddrScript(address) + if err != nil { + errorMessage := &appmessage.GetMempoolEntriesByAddressesResponseMessage{} + errorMessage.Error = appmessage.RPCErrorf("Could not extract scriptPublicKey from address '%s': %s", addressString, err) + return errorMessage, nil + } + if !getMempoolEntriesByAddressesRequest.FilterTransactionPool { - if transaction, found := sendingInTransactionPool[address.String()]; found { + if transaction, found := sendingInTransactionPool[scriptPublicKey.String()]; found { rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction) err := context.PopulateTransactionWithVerboseData(rpcTransaction, nil) if err != nil { @@ -49,7 +57,7 @@ func HandleGetMempoolEntriesByAddresses(context *rpccontext.Context, _ *router.R ) } - if transaction, found := receivingInTransactionPool[address.String()]; found { + if transaction, found := receivingInTransactionPool[scriptPublicKey.String()]; found { rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction) err := context.PopulateTransactionWithVerboseData(rpcTransaction, nil) if err != nil { @@ -66,7 +74,7 @@ func HandleGetMempoolEntriesByAddresses(context *rpccontext.Context, _ *router.R } if getMempoolEntriesByAddressesRequest.IncludeOrphanPool { - if transaction, found := sendingInOrphanPool[address.String()]; found { + if transaction, found := sendingInOrphanPool[scriptPublicKey.String()]; found { rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction) err := context.PopulateTransactionWithVerboseData(rpcTransaction, nil) if err != nil { @@ -81,7 +89,7 @@ func HandleGetMempoolEntriesByAddresses(context *rpccontext.Context, _ *router.R ) } - if transaction, found := receivingInOrphanPool[address.String()]; found { + if transaction, found := receivingInOrphanPool[scriptPublicKey.String()]; found { rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction) err := context.PopulateTransactionWithVerboseData(rpcTransaction, nil) if err != nil { diff --git a/domain/consensus/model/externalapi/transaction.go b/domain/consensus/model/externalapi/transaction.go index a64d3181a..b12baec4a 100644 --- a/domain/consensus/model/externalapi/transaction.go +++ b/domain/consensus/model/externalapi/transaction.go @@ -2,6 +2,7 @@ package externalapi import ( "bytes" + "encoding/binary" "fmt" "github.com/pkg/errors" @@ -242,6 +243,23 @@ func (spk *ScriptPublicKey) Equal(other *ScriptPublicKey) bool { return bytes.Equal(spk.Script, other.Script) } +// String stringifies a ScriptPublicKey. +func (spk *ScriptPublicKey) String() string { + var versionBytes = make([]byte, 2) // uint16 + binary.LittleEndian.PutUint16(versionBytes, spk.Version) + versionString := string(versionBytes) + scriptString := string(spk.Script) + return versionString + scriptString +} + +// NewScriptPublicKeyFromString converts the given string to a scriptPublicKey +func NewScriptPublicKeyFromString(ScriptPublicKeyString string) *ScriptPublicKey { + bytes := []byte(ScriptPublicKeyString) + version := binary.LittleEndian.Uint16(bytes[:2]) + script := bytes[2:] + return &ScriptPublicKey{Script: script, Version: version} +} + // DomainTransactionOutput represents a Kaspad transaction output type DomainTransactionOutput struct { Value uint64 diff --git a/domain/miningmanager/mempool/model/map_types.go b/domain/miningmanager/mempool/model/map_types.go index d6ca685de..ca364287b 100644 --- a/domain/miningmanager/mempool/model/map_types.go +++ b/domain/miningmanager/mempool/model/map_types.go @@ -15,3 +15,6 @@ type OutpointToUTXOEntryMap map[externalapi.DomainOutpoint]externalapi.UTXOEntry // OutpointToTransactionMap maps an outpoint to a MempoolTransaction type OutpointToTransactionMap map[externalapi.DomainOutpoint]*MempoolTransaction + +// ScriptPublicKeyStringToDomainTransaction maps an outpoint to a DomainTransaction +type ScriptPublicKeyStringToDomainTransaction map[string]*externalapi.DomainTransaction diff --git a/domain/miningmanager/mempool/orphan_pool.go b/domain/miningmanager/mempool/orphan_pool.go index 71af6402f..72338e9c3 100644 --- a/domain/miningmanager/mempool/orphan_pool.go +++ b/domain/miningmanager/mempool/orphan_pool.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/kaspanet/kaspad/domain/consensus/utils/constants" - "github.com/kaspanet/kaspad/domain/consensus/utils/txscript" "github.com/kaspanet/kaspad/domain/consensus/ruleerrors" @@ -345,11 +344,11 @@ func (op *orphansPool) getOrphanTransaction(transactionID *externalapi.DomainTra } func (op *orphansPool) getOrphanTransactionsByAddresses(clone bool) ( - sending map[string]*externalapi.DomainTransaction, - receiving map[string]*externalapi.DomainTransaction, + sending model.ScriptPublicKeyStringToDomainTransaction, + receiving model.ScriptPublicKeyStringToDomainTransaction, err error) { - sending = make(map[string]*externalapi.DomainTransaction) - receiving = make(map[string]*externalapi.DomainTransaction) + sending = make(model.ScriptPublicKeyStringToDomainTransaction) + receiving = make(model.ScriptPublicKeyStringToDomainTransaction) var transaction *externalapi.DomainTransaction for _, mempoolTransaction := range op.allOrphans { if clone { @@ -361,24 +360,11 @@ func (op *orphansPool) getOrphanTransactionsByAddresses(clone bool) ( 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.String()] = transaction + + sending[input.UTXOEntry.ScriptPublicKey().String()] = 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.String()] = transaction + receiving[output.ScriptPublicKey.String()] = transaction } } diff --git a/domain/miningmanager/mempool/transactions_pool.go b/domain/miningmanager/mempool/transactions_pool.go index 83448c8a9..e1540767f 100644 --- a/domain/miningmanager/mempool/transactions_pool.go +++ b/domain/miningmanager/mempool/transactions_pool.go @@ -7,7 +7,6 @@ import ( "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/domain/miningmanager/mempool/model" ) @@ -221,11 +220,11 @@ func (tp *transactionsPool) getTransaction(transactionID *externalapi.DomainTran } func (tp *transactionsPool) getTransactionsByAddresses(clone bool) ( - sending map[string]*externalapi.DomainTransaction, - receiving map[string]*externalapi.DomainTransaction, + sending model.ScriptPublicKeyStringToDomainTransaction, + receiving model.ScriptPublicKeyStringToDomainTransaction, err error) { - sending = make(map[string]*externalapi.DomainTransaction) - receiving = make(map[string]*externalapi.DomainTransaction) + sending = make(model.ScriptPublicKeyStringToDomainTransaction) + receiving = make(model.ScriptPublicKeyStringToDomainTransaction) var transaction *externalapi.DomainTransaction for _, mempoolTransaction := range tp.allTransactions { if clone { @@ -237,27 +236,12 @@ func (tp *transactionsPool) getTransactionsByAddresses(clone bool) ( if input.UTXOEntry == nil { //this should be fixed return nil, nil, errors.Errorf("Mempool transaction %s is missing an UTXOEntry. This should be fixed, and not happen", consensushashing.TransactionID(transaction).String()) } - _, 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.String()] = transaction + sending[input.UTXOEntry.ScriptPublicKey().String()] = 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.String()] = transaction + receiving[output.ScriptPublicKey.String()] = transaction } } - return sending, receiving, nil } diff --git a/domain/utxoindex/model.go b/domain/utxoindex/model.go index 2ceb65607..a6ffefc1d 100644 --- a/domain/utxoindex/model.go +++ b/domain/utxoindex/model.go @@ -1,7 +1,6 @@ package utxoindex import ( - "encoding/binary" "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" ) @@ -22,22 +21,3 @@ type UTXOChanges struct { Added map[ScriptPublicKeyString]UTXOOutpointEntryPairs Removed map[ScriptPublicKeyString]UTXOOutpointEntryPairs } - -// ConvertScriptPublicKeyToString converts the given scriptPublicKey to a string -func ConvertScriptPublicKeyToString(scriptPublicKey *externalapi.ScriptPublicKey) ScriptPublicKeyString { - var versionBytes = make([]byte, 2) // uint16 - binary.LittleEndian.PutUint16(versionBytes, scriptPublicKey.Version) - versionString := ScriptPublicKeyString(versionBytes) - scriptString := ScriptPublicKeyString(scriptPublicKey.Script) - return versionString + scriptString - -} - -// ConvertStringToScriptPublicKey converts the given string to a scriptPublicKey -func ConvertStringToScriptPublicKey(string ScriptPublicKeyString) *externalapi.ScriptPublicKey { - bytes := []byte(string) - version := binary.LittleEndian.Uint16(bytes[:2]) - script := bytes[2:] - return &externalapi.ScriptPublicKey{Script: script, Version: version} - -} diff --git a/domain/utxoindex/store.go b/domain/utxoindex/store.go index dbca42b7b..d42f4ac52 100644 --- a/domain/utxoindex/store.go +++ b/domain/utxoindex/store.go @@ -32,7 +32,7 @@ func newUTXOIndexStore(database database.Database) *utxoIndexStore { func (uis *utxoIndexStore) add(scriptPublicKey *externalapi.ScriptPublicKey, outpoint *externalapi.DomainOutpoint, utxoEntry externalapi.UTXOEntry) error { - key := ConvertScriptPublicKeyToString(scriptPublicKey) + key := ScriptPublicKeyString(scriptPublicKey.String()) log.Tracef("Adding outpoint %s:%d to scriptPublicKey %s", outpoint.TransactionID, outpoint.Index, key) @@ -66,7 +66,7 @@ func (uis *utxoIndexStore) add(scriptPublicKey *externalapi.ScriptPublicKey, out } func (uis *utxoIndexStore) remove(scriptPublicKey *externalapi.ScriptPublicKey, outpoint *externalapi.DomainOutpoint, utxoEntry externalapi.UTXOEntry) error { - key := ConvertScriptPublicKeyToString(scriptPublicKey) + key := ScriptPublicKeyString(scriptPublicKey.String()) log.Tracef("Removing outpoint %s:%d from scriptPublicKey %s", outpoint.TransactionID, outpoint.Index, key) @@ -122,7 +122,7 @@ func (uis *utxoIndexStore) commit() error { toRemoveSompiSupply := uint64(0) for scriptPublicKeyString, toRemoveUTXOOutpointEntryPairs := range uis.toRemove { - scriptPublicKey := ConvertStringToScriptPublicKey(scriptPublicKeyString) + scriptPublicKey := externalapi.NewScriptPublicKeyFromString(string(scriptPublicKeyString)) bucket := uis.bucketForScriptPublicKey(scriptPublicKey) for outpointToRemove, utxoEntryToRemove := range toRemoveUTXOOutpointEntryPairs { key, err := uis.convertOutpointToKey(bucket, &outpointToRemove) @@ -140,7 +140,7 @@ func (uis *utxoIndexStore) commit() error { toAddSompiSupply := uint64(0) for scriptPublicKeyString, toAddUTXOOutpointEntryPairs := range uis.toAdd { - scriptPublicKey := ConvertStringToScriptPublicKey(scriptPublicKeyString) + scriptPublicKey := externalapi.NewScriptPublicKeyFromString(string(scriptPublicKeyString)) bucket := uis.bucketForScriptPublicKey(scriptPublicKey) for outpointToAdd, utxoEntryToAdd := range toAddUTXOOutpointEntryPairs { key, err := uis.convertOutpointToKey(bucket, &outpointToAdd)