forked from TrueCloudLab/neoneo-go
rpcclient: drop deprecated Notifications an Subscribe*
Signed-off-by: Roman Khimov <roman@nspcc.ru>
This commit is contained in:
parent
413caac941
commit
eb995c8600
5 changed files with 9 additions and 311 deletions
10
ROADMAP.md
10
ROADMAP.md
|
@ -26,16 +26,6 @@ APIs/commands/configurations will be removed and here is a list of scheduled
|
||||||
breaking changes. Consider changing your code/scripts/configurations if you're
|
breaking changes. Consider changing your code/scripts/configurations if you're
|
||||||
using anything mentioned here.
|
using anything mentioned here.
|
||||||
|
|
||||||
## WSClient Notifications channel and SubscribeFor* APIs
|
|
||||||
|
|
||||||
Version 0.99.5 of NeoGo introduces a new set of subscription APIs that gives
|
|
||||||
more control to the WSClient user that can pass specific channels to be used
|
|
||||||
for specific subscriptions now. Old APIs and generic Notifications channel are
|
|
||||||
still available, but will be removed, so please convert your code to using new
|
|
||||||
Receive* APIs.
|
|
||||||
|
|
||||||
Removal of these APIs is scheduled for May 2023 (~0.103.0 release).
|
|
||||||
|
|
||||||
## SecondsPerBlock protocol configuration
|
## SecondsPerBlock protocol configuration
|
||||||
|
|
||||||
With 0.100.0 version SecondsPerBlock protocol configuration setting was
|
With 0.100.0 version SecondsPerBlock protocol configuration setting was
|
||||||
|
|
|
@ -27,8 +27,7 @@ type Internal struct {
|
||||||
func NewInternal(ctx context.Context, register InternalHook) (*Internal, error) {
|
func NewInternal(ctx context.Context, register InternalHook) (*Internal, error) {
|
||||||
c := &Internal{
|
c := &Internal{
|
||||||
WSClient: WSClient{
|
WSClient: WSClient{
|
||||||
Client: Client{},
|
Client: Client{},
|
||||||
Notifications: make(chan Notification),
|
|
||||||
|
|
||||||
shutdown: make(chan struct{}),
|
shutdown: make(chan struct{}),
|
||||||
done: make(chan struct{}),
|
done: make(chan struct{}),
|
||||||
|
@ -67,7 +66,6 @@ eventloop:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(c.done)
|
close(c.done)
|
||||||
close(c.Notifications)
|
|
||||||
c.ctxCancel()
|
c.ctxCancel()
|
||||||
// ctx is cancelled, server is notified and will finish soon.
|
// ctx is cancelled, server is notified and will finish soon.
|
||||||
drainloop:
|
drainloop:
|
||||||
|
|
|
@ -16,7 +16,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neorpc"
|
"github.com/nspcc-dev/neo-go/pkg/neorpc"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neorpc/rpcevent"
|
"github.com/nspcc-dev/neo-go/pkg/neorpc/rpcevent"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
||||||
"go.uber.org/atomic"
|
"go.uber.org/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -56,20 +55,6 @@ import (
|
||||||
// CloseNotificationChannelIfFull option is on.
|
// CloseNotificationChannelIfFull option is on.
|
||||||
type WSClient struct {
|
type WSClient struct {
|
||||||
Client
|
Client
|
||||||
// Notifications is a channel that is used to send events received from
|
|
||||||
// the server. Client's code is supposed to be reading from this channel if
|
|
||||||
// it wants to use subscription mechanism. Failing to do so will cause
|
|
||||||
// WSClient to block even regular requests. This channel is not buffered.
|
|
||||||
// In case of protocol error or upon connection closure, this channel will
|
|
||||||
// be closed, so make sure to handle this. Make sure you're not changing the
|
|
||||||
// received notifications, as it may affect the functionality of other
|
|
||||||
// notification receivers.
|
|
||||||
//
|
|
||||||
// Deprecated: please, use custom channels with ReceiveBlocks, ReceiveTransactions,
|
|
||||||
// ReceiveExecutionNotifications, ReceiveExecutions, ReceiveNotaryRequests
|
|
||||||
// methods to subscribe for notifications. This field will be removed in future
|
|
||||||
// versions.
|
|
||||||
Notifications chan Notification
|
|
||||||
|
|
||||||
ws *websocket.Conn
|
ws *websocket.Conn
|
||||||
wsOpts WSOptions
|
wsOpts WSOptions
|
||||||
|
@ -360,56 +345,6 @@ func (r *notaryRequestReceiver) Close() {
|
||||||
close(r.ch)
|
close(r.ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
// naiveReceiver is a structure leaved for deprecated single channel based notifications
|
|
||||||
// delivering.
|
|
||||||
//
|
|
||||||
// Deprecated: this receiver must be removed after outdated subscriptions API removal.
|
|
||||||
type naiveReceiver struct {
|
|
||||||
eventID neorpc.EventID
|
|
||||||
filter any
|
|
||||||
ch chan<- Notification
|
|
||||||
}
|
|
||||||
|
|
||||||
// EventID implements neorpc.Comparator interface.
|
|
||||||
func (r *naiveReceiver) EventID() neorpc.EventID {
|
|
||||||
return r.eventID
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter implements neorpc.Comparator interface.
|
|
||||||
func (r *naiveReceiver) Filter() any {
|
|
||||||
return r.filter
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receiver implements notificationReceiver interface.
|
|
||||||
func (r *naiveReceiver) Receiver() any {
|
|
||||||
return r.ch
|
|
||||||
}
|
|
||||||
|
|
||||||
// TrySend implements notificationReceiver interface.
|
|
||||||
func (r *naiveReceiver) TrySend(ntf Notification, nonBlocking bool) (bool, bool) {
|
|
||||||
if rpcevent.Matches(r, ntf) {
|
|
||||||
if nonBlocking {
|
|
||||||
select {
|
|
||||||
case r.ch <- ntf:
|
|
||||||
default:
|
|
||||||
return true, true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r.ch <- ntf
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, false
|
|
||||||
}
|
|
||||||
return false, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close implements notificationReceiver interface.
|
|
||||||
func (r *naiveReceiver) Close() {
|
|
||||||
r.ch <- Notification{
|
|
||||||
Type: neorpc.MissedEventID, // backwards-compatible behaviour
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notification represents a server-generated notification for client subscriptions.
|
// Notification represents a server-generated notification for client subscriptions.
|
||||||
// Value can be one of *block.Block, *state.AppExecResult, *state.ContainedNotificationEvent
|
// Value can be one of *block.Block, *state.AppExecResult, *state.ContainedNotificationEvent
|
||||||
// *transaction.Transaction or *subscriptions.NotaryRequestEvent based on Type.
|
// *transaction.Transaction or *subscriptions.NotaryRequestEvent based on Type.
|
||||||
|
@ -485,8 +420,7 @@ func NewWS(ctx context.Context, endpoint string, opts WSOptions) (*WSClient, err
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
wsc := &WSClient{
|
wsc := &WSClient{
|
||||||
Client: Client{},
|
Client: Client{},
|
||||||
Notifications: make(chan Notification),
|
|
||||||
|
|
||||||
ws: ws,
|
ws: ws,
|
||||||
wsOpts: opts,
|
wsOpts: opts,
|
||||||
|
@ -634,21 +568,14 @@ readloop:
|
||||||
}
|
}
|
||||||
|
|
||||||
// dropSubCh closes corresponding subscriber's channel and removes it from the
|
// dropSubCh closes corresponding subscriber's channel and removes it from the
|
||||||
// receivers map. If the channel belongs to a naive subscriber then it will be
|
// receivers map. The channel is still being kept in
|
||||||
// closed manually without call to Close(). The channel is still being kept in
|
|
||||||
// the subscribers map as technically the server-side subscription still exists
|
// the subscribers map as technically the server-side subscription still exists
|
||||||
// and the user is responsible for unsubscription. This method must be called
|
// and the user is responsible for unsubscription. This method must be called
|
||||||
// under subscriptionsLock taken. It's the caller's duty to ensure dropSubCh
|
// under subscriptionsLock taken. It's the caller's duty to ensure dropSubCh
|
||||||
// will be called once per channel, otherwise panic will occur.
|
// will be called once per channel, otherwise panic will occur.
|
||||||
func (c *WSClient) dropSubCh(rcvrCh any, id string, ignoreCloseNotificationChannelIfFull bool) {
|
func (c *WSClient) dropSubCh(rcvrCh any, id string, ignoreCloseNotificationChannelIfFull bool) {
|
||||||
if ignoreCloseNotificationChannelIfFull || c.wsOpts.CloseNotificationChannelIfFull {
|
if ignoreCloseNotificationChannelIfFull || c.wsOpts.CloseNotificationChannelIfFull {
|
||||||
rcvr := c.subscriptions[id]
|
c.subscriptions[id].Close()
|
||||||
_, ok := rcvr.(*naiveReceiver)
|
|
||||||
if ok { // naiveReceiver uses c.Notifications that should be handled separately.
|
|
||||||
close(c.Notifications)
|
|
||||||
} else {
|
|
||||||
c.subscriptions[id].Close()
|
|
||||||
}
|
|
||||||
delete(c.receivers, rcvrCh)
|
delete(c.receivers, rcvrCh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -778,29 +705,6 @@ func (c *WSClient) performSubscription(params []any, rcvr notificationReceiver)
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubscribeForNewBlocks adds subscription for new block events to this instance
|
|
||||||
// of the client. It can be filtered by primary consensus node index, nil value doesn't
|
|
||||||
// add any filters.
|
|
||||||
//
|
|
||||||
// Deprecated: please, use ReceiveBlocks. This method will be removed in future versions.
|
|
||||||
func (c *WSClient) SubscribeForNewBlocks(primary *int) (string, error) {
|
|
||||||
var flt any
|
|
||||||
if primary != nil {
|
|
||||||
var f = neorpc.BlockFilter{Primary: primary}
|
|
||||||
flt = *f.Copy()
|
|
||||||
}
|
|
||||||
params := []any{"block_added"}
|
|
||||||
if flt != nil {
|
|
||||||
params = append(params, flt)
|
|
||||||
}
|
|
||||||
r := &naiveReceiver{
|
|
||||||
eventID: neorpc.BlockEventID,
|
|
||||||
filter: flt,
|
|
||||||
ch: c.Notifications,
|
|
||||||
}
|
|
||||||
return c.performSubscription(params, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReceiveBlocks registers provided channel as a receiver for the new block events.
|
// ReceiveBlocks registers provided channel as a receiver for the new block events.
|
||||||
// Events can be filtered by the given BlockFilter, nil value doesn't add any filter.
|
// Events can be filtered by the given BlockFilter, nil value doesn't add any filter.
|
||||||
// See WSClient comments for generic Receive* behaviour details.
|
// See WSClient comments for generic Receive* behaviour details.
|
||||||
|
@ -820,29 +724,6 @@ func (c *WSClient) ReceiveBlocks(flt *neorpc.BlockFilter, rcvr chan<- *block.Blo
|
||||||
return c.performSubscription(params, r)
|
return c.performSubscription(params, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubscribeForNewTransactions adds subscription for new transaction events to
|
|
||||||
// this instance of the client. It can be filtered by the sender and/or the signer, nil
|
|
||||||
// value is treated as missing filter.
|
|
||||||
//
|
|
||||||
// Deprecated: please, use ReceiveTransactions. This method will be removed in future versions.
|
|
||||||
func (c *WSClient) SubscribeForNewTransactions(sender *util.Uint160, signer *util.Uint160) (string, error) {
|
|
||||||
var flt any
|
|
||||||
if sender != nil || signer != nil {
|
|
||||||
var f = neorpc.TxFilter{Sender: sender, Signer: signer}
|
|
||||||
flt = *f.Copy()
|
|
||||||
}
|
|
||||||
params := []any{"transaction_added"}
|
|
||||||
if flt != nil {
|
|
||||||
params = append(params, flt)
|
|
||||||
}
|
|
||||||
r := &naiveReceiver{
|
|
||||||
eventID: neorpc.TransactionEventID,
|
|
||||||
filter: flt,
|
|
||||||
ch: c.Notifications,
|
|
||||||
}
|
|
||||||
return c.performSubscription(params, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReceiveTransactions registers provided channel as a receiver for new transaction
|
// ReceiveTransactions registers provided channel as a receiver for new transaction
|
||||||
// events. Events can be filtered by the given TxFilter, nil value doesn't add any
|
// events. Events can be filtered by the given TxFilter, nil value doesn't add any
|
||||||
// filter. See WSClient comments for generic Receive* behaviour details.
|
// filter. See WSClient comments for generic Receive* behaviour details.
|
||||||
|
@ -862,30 +743,6 @@ func (c *WSClient) ReceiveTransactions(flt *neorpc.TxFilter, rcvr chan<- *transa
|
||||||
return c.performSubscription(params, r)
|
return c.performSubscription(params, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubscribeForExecutionNotifications adds subscription for notifications
|
|
||||||
// generated during transaction execution to this instance of the client. It can be
|
|
||||||
// filtered by the contract's hash (that emits notifications), nil value puts no such
|
|
||||||
// restrictions.
|
|
||||||
//
|
|
||||||
// Deprecated: please, use ReceiveExecutionNotifications. This method will be removed in future versions.
|
|
||||||
func (c *WSClient) SubscribeForExecutionNotifications(contract *util.Uint160, name *string) (string, error) {
|
|
||||||
var flt any
|
|
||||||
if contract != nil || name != nil {
|
|
||||||
var f = neorpc.NotificationFilter{Contract: contract, Name: name}
|
|
||||||
flt = *f.Copy()
|
|
||||||
}
|
|
||||||
params := []any{"notification_from_execution"}
|
|
||||||
if flt != nil {
|
|
||||||
params = append(params, flt)
|
|
||||||
}
|
|
||||||
r := &naiveReceiver{
|
|
||||||
eventID: neorpc.NotificationEventID,
|
|
||||||
filter: flt,
|
|
||||||
ch: c.Notifications,
|
|
||||||
}
|
|
||||||
return c.performSubscription(params, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReceiveExecutionNotifications registers provided channel as a receiver for execution
|
// ReceiveExecutionNotifications registers provided channel as a receiver for execution
|
||||||
// events. Events can be filtered by the given NotificationFilter, nil value doesn't add
|
// events. Events can be filtered by the given NotificationFilter, nil value doesn't add
|
||||||
// any filter. See WSClient comments for generic Receive* behaviour details.
|
// any filter. See WSClient comments for generic Receive* behaviour details.
|
||||||
|
@ -905,33 +762,6 @@ func (c *WSClient) ReceiveExecutionNotifications(flt *neorpc.NotificationFilter,
|
||||||
return c.performSubscription(params, r)
|
return c.performSubscription(params, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubscribeForTransactionExecutions adds subscription for application execution
|
|
||||||
// results generated during transaction execution to this instance of the client. It can
|
|
||||||
// be filtered by state (HALT/FAULT) to check for successful or failing
|
|
||||||
// transactions, nil value means no filtering.
|
|
||||||
//
|
|
||||||
// Deprecated: please, use ReceiveExecutions. This method will be removed in future versions.
|
|
||||||
func (c *WSClient) SubscribeForTransactionExecutions(state *string) (string, error) {
|
|
||||||
var flt any
|
|
||||||
if state != nil {
|
|
||||||
if *state != "HALT" && *state != "FAULT" {
|
|
||||||
return "", errors.New("bad state parameter")
|
|
||||||
}
|
|
||||||
var f = neorpc.ExecutionFilter{State: state}
|
|
||||||
flt = *f.Copy()
|
|
||||||
}
|
|
||||||
params := []any{"transaction_executed"}
|
|
||||||
if flt != nil {
|
|
||||||
params = append(params, flt)
|
|
||||||
}
|
|
||||||
r := &naiveReceiver{
|
|
||||||
eventID: neorpc.ExecutionEventID,
|
|
||||||
filter: flt,
|
|
||||||
ch: c.Notifications,
|
|
||||||
}
|
|
||||||
return c.performSubscription(params, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReceiveExecutions registers provided channel as a receiver for
|
// ReceiveExecutions registers provided channel as a receiver for
|
||||||
// application execution result events generated during transaction execution.
|
// application execution result events generated during transaction execution.
|
||||||
// Events can be filtered by the given ExecutionFilter, nil value doesn't add any filter.
|
// Events can be filtered by the given ExecutionFilter, nil value doesn't add any filter.
|
||||||
|
@ -957,30 +787,6 @@ func (c *WSClient) ReceiveExecutions(flt *neorpc.ExecutionFilter, rcvr chan<- *s
|
||||||
return c.performSubscription(params, r)
|
return c.performSubscription(params, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubscribeForNotaryRequests adds subscription for notary request payloads
|
|
||||||
// addition or removal events to this instance of client. It can be filtered by
|
|
||||||
// request sender's hash, or main tx signer's hash, nil value puts no such
|
|
||||||
// restrictions.
|
|
||||||
//
|
|
||||||
// Deprecated: please, use ReceiveNotaryRequests. This method will be removed in future versions.
|
|
||||||
func (c *WSClient) SubscribeForNotaryRequests(sender *util.Uint160, mainSigner *util.Uint160) (string, error) {
|
|
||||||
var flt any
|
|
||||||
if sender != nil || mainSigner != nil {
|
|
||||||
var f = neorpc.TxFilter{Sender: sender, Signer: mainSigner}
|
|
||||||
flt = *f.Copy()
|
|
||||||
}
|
|
||||||
params := []any{"notary_request_event"}
|
|
||||||
if flt != nil {
|
|
||||||
params = append(params, flt)
|
|
||||||
}
|
|
||||||
r := &naiveReceiver{
|
|
||||||
eventID: neorpc.NotaryRequestEventID,
|
|
||||||
filter: flt,
|
|
||||||
ch: c.Notifications,
|
|
||||||
}
|
|
||||||
return c.performSubscription(params, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReceiveNotaryRequests registers provided channel as a receiver for notary request
|
// ReceiveNotaryRequests registers provided channel as a receiver for notary request
|
||||||
// payload addition or removal events. Events can be filtered by the given TxFilter
|
// payload addition or removal events. Events can be filtered by the given TxFilter
|
||||||
// where sender corresponds to notary request sender (the second fallback transaction
|
// where sender corresponds to notary request sender (the second fallback transaction
|
||||||
|
|
|
@ -205,31 +205,23 @@ func TestWSClientEvents(t *testing.T) {
|
||||||
wsc.receivers[chan<- *state.AppExecResult(aerCh3)] = []string{"6"}
|
wsc.receivers[chan<- *state.AppExecResult(aerCh3)] = []string{"6"}
|
||||||
// MissedEvent must close the channels above.
|
// MissedEvent must close the channels above.
|
||||||
|
|
||||||
wsc.subscriptions["7"] = &naiveReceiver{eventID: neorpc.BlockEventID, ch: wsc.Notifications}
|
|
||||||
wsc.subscriptions["8"] = &naiveReceiver{eventID: neorpc.BlockEventID, ch: wsc.Notifications} // check duplicating subscriptions
|
|
||||||
wsc.subscriptions["9"] = &naiveReceiver{eventID: neorpc.ExecutionEventID, ch: wsc.Notifications} // check different events
|
|
||||||
wsc.receivers[wsc.Notifications] = []string{"7", "8", "9"}
|
|
||||||
wsc.subscriptionsLock.Unlock()
|
wsc.subscriptionsLock.Unlock()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
b1Cnt, b2Cnt int
|
b1Cnt, b2Cnt int
|
||||||
aer1Cnt, aer2Cnt, aer3Cnt int
|
aer1Cnt, aer2Cnt, aer3Cnt int
|
||||||
ntfCnt int
|
ntfCnt int
|
||||||
defaultCount int
|
expectedb1Cnt, expectedb2Cnt = 1, 1 // single Block event
|
||||||
expectedb1Cnt, expectedb2Cnt = 1, 1 // single Block event
|
expectedaer1Cnt, expectedaer2Cnt, expectedaer3Cnt = 2, 2, 0 // two HALTED AERs
|
||||||
expectedaer1Cnt, expectedaer2Cnt, expectedaer3Cnt = 2, 2, 0 // two HALTED AERs
|
expectedntfCnt = 1 // single notification event
|
||||||
expectedntfCnt = 1 // single notification event
|
|
||||||
expectedDefaultCnt = 1 + 2 + 1 // single Block event + two AERs + missed event
|
|
||||||
aer *state.AppExecResult
|
aer *state.AppExecResult
|
||||||
)
|
)
|
||||||
for b1Cnt+b2Cnt+
|
for b1Cnt+b2Cnt+
|
||||||
aer1Cnt+aer2Cnt+aer3Cnt+
|
aer1Cnt+aer2Cnt+aer3Cnt+
|
||||||
ntfCnt+
|
ntfCnt !=
|
||||||
defaultCount !=
|
|
||||||
expectedb1Cnt+expectedb2Cnt+
|
expectedb1Cnt+expectedb2Cnt+
|
||||||
expectedaer1Cnt+expectedaer2Cnt+expectedaer3Cnt+
|
expectedaer1Cnt+expectedaer2Cnt+expectedaer3Cnt+
|
||||||
expectedntfCnt+
|
expectedntfCnt {
|
||||||
expectedDefaultCnt {
|
|
||||||
select {
|
select {
|
||||||
case _, ok = <-bCh1:
|
case _, ok = <-bCh1:
|
||||||
if ok {
|
if ok {
|
||||||
|
@ -256,10 +248,6 @@ func TestWSClientEvents(t *testing.T) {
|
||||||
if ok {
|
if ok {
|
||||||
ntfCnt++
|
ntfCnt++
|
||||||
}
|
}
|
||||||
case _, ok = <-wsc.Notifications:
|
|
||||||
if ok {
|
|
||||||
defaultCount++
|
|
||||||
}
|
|
||||||
case <-time.After(time.Second):
|
case <-time.After(time.Second):
|
||||||
t.Fatal("timeout waiting for event")
|
t.Fatal("timeout waiting for event")
|
||||||
}
|
}
|
||||||
|
@ -270,7 +258,6 @@ func TestWSClientEvents(t *testing.T) {
|
||||||
assert.Equal(t, expectedaer2Cnt, aer2Cnt)
|
assert.Equal(t, expectedaer2Cnt, aer2Cnt)
|
||||||
assert.Equal(t, expectedaer3Cnt, aer3Cnt)
|
assert.Equal(t, expectedaer3Cnt, aer3Cnt)
|
||||||
assert.Equal(t, expectedntfCnt, ntfCnt)
|
assert.Equal(t, expectedntfCnt, ntfCnt)
|
||||||
assert.Equal(t, expectedDefaultCnt, defaultCount)
|
|
||||||
|
|
||||||
// Channels must be closed by server
|
// Channels must be closed by server
|
||||||
_, ok = <-bCh1
|
_, ok = <-bCh1
|
||||||
|
|
|
@ -2066,89 +2066,6 @@ func TestWSClient_SubscriptionsCompat(t *testing.T) {
|
||||||
bCount++
|
bCount++
|
||||||
return b1, primary, sender, ntfName, st
|
return b1, primary, sender, ntfName, st
|
||||||
}
|
}
|
||||||
checkDeprecated := func(t *testing.T, filtered bool) {
|
|
||||||
var (
|
|
||||||
bID, txID, ntfID, aerID string
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
b, primary, sender, ntfName, st := getData(t)
|
|
||||||
if filtered {
|
|
||||||
bID, err = c.SubscribeForNewBlocks(&primary) //nolint:staticcheck // SA1019: c.SubscribeForNewBlocks is deprecated
|
|
||||||
require.NoError(t, err)
|
|
||||||
txID, err = c.SubscribeForNewTransactions(&sender, nil) //nolint:staticcheck // SA1019: c.SubscribeForNewTransactions is deprecated
|
|
||||||
require.NoError(t, err)
|
|
||||||
ntfID, err = c.SubscribeForExecutionNotifications(nil, &ntfName) //nolint:staticcheck // SA1019: c.SubscribeForExecutionNotifications is deprecated
|
|
||||||
require.NoError(t, err)
|
|
||||||
aerID, err = c.SubscribeForTransactionExecutions(&st) //nolint:staticcheck // SA1019: c.SubscribeForTransactionExecutions is deprecated
|
|
||||||
require.NoError(t, err)
|
|
||||||
} else {
|
|
||||||
bID, err = c.SubscribeForNewBlocks(nil) //nolint:staticcheck // SA1019: c.SubscribeForNewBlocks is deprecated
|
|
||||||
require.NoError(t, err)
|
|
||||||
txID, err = c.SubscribeForNewTransactions(nil, nil) //nolint:staticcheck // SA1019: c.SubscribeForNewTransactions is deprecated
|
|
||||||
require.NoError(t, err)
|
|
||||||
ntfID, err = c.SubscribeForExecutionNotifications(nil, nil) //nolint:staticcheck // SA1019: c.SubscribeForExecutionNotifications is deprecated
|
|
||||||
require.NoError(t, err)
|
|
||||||
aerID, err = c.SubscribeForTransactionExecutions(nil) //nolint:staticcheck // SA1019: c.SubscribeForTransactionExecutions is deprecated
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
lock sync.RWMutex
|
|
||||||
received byte
|
|
||||||
exitCh = make(chan struct{})
|
|
||||||
)
|
|
||||||
go func() {
|
|
||||||
dispatcher:
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case ntf := <-c.Notifications: //nolint:staticcheck // SA1019: c.Notifications is deprecated
|
|
||||||
lock.Lock()
|
|
||||||
switch ntf.Type {
|
|
||||||
case neorpc.BlockEventID:
|
|
||||||
received |= 1
|
|
||||||
case neorpc.TransactionEventID:
|
|
||||||
received |= 1 << 1
|
|
||||||
case neorpc.NotificationEventID:
|
|
||||||
received |= 1 << 2
|
|
||||||
case neorpc.ExecutionEventID:
|
|
||||||
received |= 1 << 3
|
|
||||||
}
|
|
||||||
lock.Unlock()
|
|
||||||
case <-exitCh:
|
|
||||||
break dispatcher
|
|
||||||
}
|
|
||||||
}
|
|
||||||
drainLoop:
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-c.Notifications: //nolint:staticcheck // SA1019: c.Notifications is deprecated
|
|
||||||
default:
|
|
||||||
break drainLoop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Accept the next block and wait for events.
|
|
||||||
require.NoError(t, chain.AddBlock(b))
|
|
||||||
assert.Eventually(t, func() bool {
|
|
||||||
lock.RLock()
|
|
||||||
defer lock.RUnlock()
|
|
||||||
|
|
||||||
return received == 1<<4-1
|
|
||||||
}, time.Second, 100*time.Millisecond)
|
|
||||||
|
|
||||||
require.NoError(t, c.Unsubscribe(bID))
|
|
||||||
require.NoError(t, c.Unsubscribe(txID))
|
|
||||||
require.NoError(t, c.Unsubscribe(ntfID))
|
|
||||||
require.NoError(t, c.Unsubscribe(aerID))
|
|
||||||
exitCh <- struct{}{}
|
|
||||||
}
|
|
||||||
t.Run("deprecated, filtered", func(t *testing.T) {
|
|
||||||
checkDeprecated(t, true)
|
|
||||||
})
|
|
||||||
t.Run("deprecated, non-filtered", func(t *testing.T) {
|
|
||||||
checkDeprecated(t, false)
|
|
||||||
})
|
|
||||||
|
|
||||||
checkRelevant := func(t *testing.T, filtered bool) {
|
checkRelevant := func(t *testing.T, filtered bool) {
|
||||||
b, primary, sender, ntfName, st := getData(t)
|
b, primary, sender, ntfName, st := getData(t)
|
||||||
|
|
Loading…
Reference in a new issue