mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-07 14:46:44 +00:00
Allow blank address in NotifyUTXOsChanged to get all updates (#2027)
* Allow blank address in NotifyUTXOsChanged to get all updates * To see if address is possible to extract: Check for NonStandardTy rather than error * Don't swallow errors Co-authored-by: Ori Newman <orinewman1@gmail.com>
This commit is contained in:
parent
8735da045f
commit
5d24e2afbc
@ -44,7 +44,7 @@ func NewContext(cfg *config.Config,
|
|||||||
UTXOIndex: utxoIndex,
|
UTXOIndex: utxoIndex,
|
||||||
ShutDownChan: shutDownChan,
|
ShutDownChan: shutDownChan,
|
||||||
}
|
}
|
||||||
context.NotificationManager = NewNotificationManager()
|
context.NotificationManager = NewNotificationManager(cfg.ActiveNetParams)
|
||||||
|
|
||||||
return context
|
return context
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,10 @@ package rpccontext
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/kaspanet/kaspad/domain/dagconfig"
|
||||||
|
|
||||||
|
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/app/appmessage"
|
"github.com/kaspanet/kaspad/app/appmessage"
|
||||||
"github.com/kaspanet/kaspad/domain/utxoindex"
|
"github.com/kaspanet/kaspad/domain/utxoindex"
|
||||||
routerpkg "github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
routerpkg "github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||||
@ -13,6 +17,7 @@ import (
|
|||||||
type NotificationManager struct {
|
type NotificationManager struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
listeners map[*routerpkg.Router]*NotificationListener
|
listeners map[*routerpkg.Router]*NotificationListener
|
||||||
|
params *dagconfig.Params
|
||||||
}
|
}
|
||||||
|
|
||||||
// UTXOsChangedNotificationAddress represents a kaspad address.
|
// UTXOsChangedNotificationAddress represents a kaspad address.
|
||||||
@ -24,6 +29,8 @@ type UTXOsChangedNotificationAddress struct {
|
|||||||
|
|
||||||
// NotificationListener represents a registered RPC notification listener
|
// NotificationListener represents a registered RPC notification listener
|
||||||
type NotificationListener struct {
|
type NotificationListener struct {
|
||||||
|
params *dagconfig.Params
|
||||||
|
|
||||||
propagateBlockAddedNotifications bool
|
propagateBlockAddedNotifications bool
|
||||||
propagateVirtualSelectedParentChainChangedNotifications bool
|
propagateVirtualSelectedParentChainChangedNotifications bool
|
||||||
propagateFinalityConflictNotifications bool
|
propagateFinalityConflictNotifications bool
|
||||||
@ -39,8 +46,9 @@ type NotificationListener struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewNotificationManager creates a new NotificationManager
|
// NewNotificationManager creates a new NotificationManager
|
||||||
func NewNotificationManager() *NotificationManager {
|
func NewNotificationManager(params *dagconfig.Params) *NotificationManager {
|
||||||
return &NotificationManager{
|
return &NotificationManager{
|
||||||
|
params: params,
|
||||||
listeners: make(map[*routerpkg.Router]*NotificationListener),
|
listeners: make(map[*routerpkg.Router]*NotificationListener),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,7 +58,7 @@ func (nm *NotificationManager) AddListener(router *routerpkg.Router) {
|
|||||||
nm.Lock()
|
nm.Lock()
|
||||||
defer nm.Unlock()
|
defer nm.Unlock()
|
||||||
|
|
||||||
listener := newNotificationListener()
|
listener := newNotificationListener(nm.params)
|
||||||
nm.listeners[router] = listener
|
nm.listeners[router] = listener
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +182,10 @@ func (nm *NotificationManager) NotifyUTXOsChanged(utxoChanges *utxoindex.UTXOCha
|
|||||||
for router, listener := range nm.listeners {
|
for router, listener := range nm.listeners {
|
||||||
if listener.propagateUTXOsChangedNotifications {
|
if listener.propagateUTXOsChangedNotifications {
|
||||||
// Filter utxoChanges and create a notification
|
// Filter utxoChanges and create a notification
|
||||||
notification := listener.convertUTXOChangesToUTXOsChangedNotification(utxoChanges)
|
notification, err := listener.convertUTXOChangesToUTXOsChangedNotification(utxoChanges)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Don't send the notification if it's empty
|
// Don't send the notification if it's empty
|
||||||
if len(notification.Added) == 0 && len(notification.Removed) == 0 {
|
if len(notification.Added) == 0 && len(notification.Removed) == 0 {
|
||||||
@ -182,7 +193,7 @@ func (nm *NotificationManager) NotifyUTXOsChanged(utxoChanges *utxoindex.UTXOCha
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Enqueue the notification
|
// Enqueue the notification
|
||||||
err := router.OutgoingRoute().Enqueue(notification)
|
err = router.OutgoingRoute().Enqueue(notification)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -265,8 +276,10 @@ func (nm *NotificationManager) NotifyPruningPointUTXOSetOverride() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newNotificationListener() *NotificationListener {
|
func newNotificationListener(params *dagconfig.Params) *NotificationListener {
|
||||||
return &NotificationListener{
|
return &NotificationListener{
|
||||||
|
params: params,
|
||||||
|
|
||||||
propagateBlockAddedNotifications: false,
|
propagateBlockAddedNotifications: false,
|
||||||
propagateVirtualSelectedParentChainChangedNotifications: false,
|
propagateVirtualSelectedParentChainChangedNotifications: false,
|
||||||
propagateFinalityConflictNotifications: false,
|
propagateFinalityConflictNotifications: false,
|
||||||
@ -339,7 +352,7 @@ func (nl *NotificationListener) StopPropagatingUTXOsChangedNotifications(address
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (nl *NotificationListener) convertUTXOChangesToUTXOsChangedNotification(
|
func (nl *NotificationListener) convertUTXOChangesToUTXOsChangedNotification(
|
||||||
utxoChanges *utxoindex.UTXOChanges) *appmessage.UTXOsChangedNotificationMessage {
|
utxoChanges *utxoindex.UTXOChanges) (*appmessage.UTXOsChangedNotificationMessage, error) {
|
||||||
|
|
||||||
// As an optimization, we iterate over the smaller set (O(n)) among the two below
|
// As an optimization, we iterate over the smaller set (O(n)) among the two below
|
||||||
// and check existence over the larger set (O(1))
|
// and check existence over the larger set (O(1))
|
||||||
@ -360,7 +373,7 @@ func (nl *NotificationListener) convertUTXOChangesToUTXOsChangedNotification(
|
|||||||
notification.Removed = append(notification.Removed, utxosByAddressesEntries...)
|
notification.Removed = append(notification.Removed, utxosByAddressesEntries...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if addressesSize > 0 {
|
||||||
for _, listenerAddress := range nl.propagateUTXOsChangedNotificationAddresses {
|
for _, listenerAddress := range nl.propagateUTXOsChangedNotificationAddresses {
|
||||||
listenerScriptPublicKeyString := listenerAddress.ScriptPublicKeyString
|
listenerScriptPublicKeyString := listenerAddress.ScriptPublicKeyString
|
||||||
if addedPairs, ok := utxoChanges.Added[listenerScriptPublicKeyString]; ok {
|
if addedPairs, ok := utxoChanges.Added[listenerScriptPublicKeyString]; ok {
|
||||||
@ -372,9 +385,46 @@ func (nl *NotificationListener) convertUTXOChangesToUTXOsChangedNotification(
|
|||||||
notification.Removed = append(notification.Removed, utxosByAddressesEntries...)
|
notification.Removed = append(notification.Removed, utxosByAddressesEntries...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for scriptPublicKeyString, addedPairs := range utxoChanges.Added {
|
||||||
|
addressString, err := nl.scriptPubKeyStringToAddressString(scriptPublicKeyString)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return notification
|
utxosByAddressesEntries := ConvertUTXOOutpointEntryPairsToUTXOsByAddressesEntries(addressString, addedPairs)
|
||||||
|
notification.Added = append(notification.Added, utxosByAddressesEntries...)
|
||||||
|
}
|
||||||
|
for scriptPublicKeyString, removedOutpoints := range utxoChanges.Removed {
|
||||||
|
addressString, err := nl.scriptPubKeyStringToAddressString(scriptPublicKeyString)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
utxosByAddressesEntries := convertUTXOOutpointsToUTXOsByAddressesEntries(addressString, removedOutpoints)
|
||||||
|
notification.Removed = append(notification.Removed, utxosByAddressesEntries...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return notification, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nl *NotificationListener) scriptPubKeyStringToAddressString(scriptPublicKeyString utxoindex.ScriptPublicKeyString) (string, error) {
|
||||||
|
scriptPubKey := utxoindex.ConvertStringToScriptPublicKey(scriptPublicKeyString)
|
||||||
|
|
||||||
|
// ignore error because it is often returned when the script is of unknown type
|
||||||
|
scriptType, address, err := txscript.ExtractScriptPubKeyAddress(scriptPubKey, nl.params)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var addressString string
|
||||||
|
if scriptType == txscript.NonStandardTy {
|
||||||
|
addressString = ""
|
||||||
|
} else {
|
||||||
|
addressString = address.String()
|
||||||
|
}
|
||||||
|
return addressString, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PropagateVirtualSelectedParentBlueScoreChangedNotifications instructs the listener to send
|
// PropagateVirtualSelectedParentBlueScoreChangedNotifications instructs the listener to send
|
||||||
|
@ -306,7 +306,7 @@ func PushedData(script []byte) ([][]byte, error) {
|
|||||||
// as public keys which are invalid will return a nil address.
|
// as public keys which are invalid will return a nil address.
|
||||||
func ExtractScriptPubKeyAddress(scriptPubKey *externalapi.ScriptPublicKey, dagParams *dagconfig.Params) (ScriptClass, util.Address, error) {
|
func ExtractScriptPubKeyAddress(scriptPubKey *externalapi.ScriptPublicKey, dagParams *dagconfig.Params) (ScriptClass, util.Address, error) {
|
||||||
if scriptPubKey.Version > constants.MaxScriptPublicKeyVersion {
|
if scriptPubKey.Version > constants.MaxScriptPublicKeyVersion {
|
||||||
return NonStandardTy, nil, errors.Errorf("Script version is unknown.")
|
return NonStandardTy, nil, nil
|
||||||
}
|
}
|
||||||
// No valid address if the script doesn't parse.
|
// No valid address if the script doesn't parse.
|
||||||
pops, err := parseScript(scriptPubKey.Script)
|
pops, err := parseScript(scriptPubKey.Script)
|
||||||
|
@ -469,7 +469,7 @@ message GetHeadersResponseMessage{
|
|||||||
//
|
//
|
||||||
// See: UtxosChangedNotificationMessage
|
// See: UtxosChangedNotificationMessage
|
||||||
message NotifyUtxosChangedRequestMessage {
|
message NotifyUtxosChangedRequestMessage {
|
||||||
repeated string addresses = 1;
|
repeated string addresses = 1; // Leave empty to get all updates
|
||||||
}
|
}
|
||||||
|
|
||||||
message NotifyUtxosChangedResponseMessage {
|
message NotifyUtxosChangedResponseMessage {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user