mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-23 13:41:37 +00:00
Merge pull request #2937 from nspcc-dev/copy-wsclient-filters
Copy wsclient filters
This commit is contained in:
commit
da7eafd4c7
4 changed files with 244 additions and 38 deletions
113
pkg/neorpc/filters.go
Normal file
113
pkg/neorpc/filters.go
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
package neorpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// BlockFilter is a wrapper structure for the block event filter. It allows
|
||||||
|
// to filter blocks by primary index and/or by block index (allowing blocks
|
||||||
|
// since/till the specified index inclusively). nil value treated as missing
|
||||||
|
// filter.
|
||||||
|
BlockFilter struct {
|
||||||
|
Primary *int `json:"primary,omitempty"`
|
||||||
|
Since *uint32 `json:"since,omitempty"`
|
||||||
|
Till *uint32 `json:"till,omitempty"`
|
||||||
|
}
|
||||||
|
// TxFilter is a wrapper structure for the transaction event filter. It
|
||||||
|
// allows to filter transactions by senders and/or signers. nil value treated
|
||||||
|
// as missing filter.
|
||||||
|
TxFilter struct {
|
||||||
|
Sender *util.Uint160 `json:"sender,omitempty"`
|
||||||
|
Signer *util.Uint160 `json:"signer,omitempty"`
|
||||||
|
}
|
||||||
|
// NotificationFilter is a wrapper structure representing a filter used for
|
||||||
|
// notifications generated during transaction execution. Notifications can
|
||||||
|
// be filtered by contract hash and/or by name. nil value treated as missing
|
||||||
|
// filter.
|
||||||
|
NotificationFilter struct {
|
||||||
|
Contract *util.Uint160 `json:"contract,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
}
|
||||||
|
// ExecutionFilter is a wrapper structure used for transaction and persisting
|
||||||
|
// scripts execution events. It allows to choose failing or successful
|
||||||
|
// transactions and persisting scripts based on their VM state and/or to
|
||||||
|
// choose execution event with the specified container. nil value treated as
|
||||||
|
// missing filter.
|
||||||
|
ExecutionFilter struct {
|
||||||
|
State *string `json:"state,omitempty"`
|
||||||
|
Container *util.Uint256 `json:"container,omitempty"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Copy creates a deep copy of the BlockFilter. It handles nil BlockFilter correctly.
|
||||||
|
func (f *BlockFilter) Copy() *BlockFilter {
|
||||||
|
if f == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var res = new(BlockFilter)
|
||||||
|
if f.Primary != nil {
|
||||||
|
res.Primary = new(int)
|
||||||
|
*res.Primary = *f.Primary
|
||||||
|
}
|
||||||
|
if f.Since != nil {
|
||||||
|
res.Since = new(uint32)
|
||||||
|
*res.Since = *f.Since
|
||||||
|
}
|
||||||
|
if f.Till != nil {
|
||||||
|
res.Till = new(uint32)
|
||||||
|
*res.Till = *f.Till
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy creates a deep copy of the TxFilter. It handles nil TxFilter correctly.
|
||||||
|
func (f *TxFilter) Copy() *TxFilter {
|
||||||
|
if f == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var res = new(TxFilter)
|
||||||
|
if f.Sender != nil {
|
||||||
|
res.Sender = new(util.Uint160)
|
||||||
|
*res.Sender = *f.Sender
|
||||||
|
}
|
||||||
|
if f.Signer != nil {
|
||||||
|
res.Signer = new(util.Uint160)
|
||||||
|
*res.Signer = *f.Signer
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy creates a deep copy of the NotificationFilter. It handles nil NotificationFilter correctly.
|
||||||
|
func (f *NotificationFilter) Copy() *NotificationFilter {
|
||||||
|
if f == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var res = new(NotificationFilter)
|
||||||
|
if f.Contract != nil {
|
||||||
|
res.Contract = new(util.Uint160)
|
||||||
|
*res.Contract = *f.Contract
|
||||||
|
}
|
||||||
|
if f.Name != nil {
|
||||||
|
res.Name = new(string)
|
||||||
|
*res.Name = *f.Name
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy creates a deep copy of the ExecutionFilter. It handles nil ExecutionFilter correctly.
|
||||||
|
func (f *ExecutionFilter) Copy() *ExecutionFilter {
|
||||||
|
if f == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var res = new(ExecutionFilter)
|
||||||
|
if f.State != nil {
|
||||||
|
res.State = new(string)
|
||||||
|
*res.State = *f.State
|
||||||
|
}
|
||||||
|
if f.Container != nil {
|
||||||
|
res.Container = new(util.Uint256)
|
||||||
|
*res.Container = *f.Container
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
116
pkg/neorpc/filters_test.go
Normal file
116
pkg/neorpc/filters_test.go
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
package neorpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBlockFilterCopy(t *testing.T) {
|
||||||
|
var bf, tf *BlockFilter
|
||||||
|
|
||||||
|
require.Nil(t, bf.Copy())
|
||||||
|
|
||||||
|
bf = new(BlockFilter)
|
||||||
|
tf = bf.Copy()
|
||||||
|
require.Equal(t, bf, tf)
|
||||||
|
|
||||||
|
bf.Primary = new(int)
|
||||||
|
*bf.Primary = 42
|
||||||
|
|
||||||
|
tf = bf.Copy()
|
||||||
|
require.Equal(t, bf, tf)
|
||||||
|
*bf.Primary = 100500
|
||||||
|
require.NotEqual(t, bf, tf)
|
||||||
|
|
||||||
|
bf.Since = new(uint32)
|
||||||
|
*bf.Since = 42
|
||||||
|
|
||||||
|
tf = bf.Copy()
|
||||||
|
require.Equal(t, bf, tf)
|
||||||
|
*bf.Since = 100500
|
||||||
|
require.NotEqual(t, bf, tf)
|
||||||
|
|
||||||
|
bf.Till = new(uint32)
|
||||||
|
*bf.Till = 42
|
||||||
|
|
||||||
|
tf = bf.Copy()
|
||||||
|
require.Equal(t, bf, tf)
|
||||||
|
*bf.Till = 100500
|
||||||
|
require.NotEqual(t, bf, tf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTxFilterCopy(t *testing.T) {
|
||||||
|
var bf, tf *TxFilter
|
||||||
|
|
||||||
|
require.Nil(t, bf.Copy())
|
||||||
|
|
||||||
|
bf = new(TxFilter)
|
||||||
|
tf = bf.Copy()
|
||||||
|
require.Equal(t, bf, tf)
|
||||||
|
|
||||||
|
bf.Sender = &util.Uint160{1, 2, 3}
|
||||||
|
|
||||||
|
tf = bf.Copy()
|
||||||
|
require.Equal(t, bf, tf)
|
||||||
|
*bf.Sender = util.Uint160{3, 2, 1}
|
||||||
|
require.NotEqual(t, bf, tf)
|
||||||
|
|
||||||
|
bf.Signer = &util.Uint160{1, 2, 3}
|
||||||
|
|
||||||
|
tf = bf.Copy()
|
||||||
|
require.Equal(t, bf, tf)
|
||||||
|
*bf.Signer = util.Uint160{3, 2, 1}
|
||||||
|
require.NotEqual(t, bf, tf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNotificationFilterCopy(t *testing.T) {
|
||||||
|
var bf, tf *NotificationFilter
|
||||||
|
|
||||||
|
require.Nil(t, bf.Copy())
|
||||||
|
|
||||||
|
bf = new(NotificationFilter)
|
||||||
|
tf = bf.Copy()
|
||||||
|
require.Equal(t, bf, tf)
|
||||||
|
|
||||||
|
bf.Contract = &util.Uint160{1, 2, 3}
|
||||||
|
|
||||||
|
tf = bf.Copy()
|
||||||
|
require.Equal(t, bf, tf)
|
||||||
|
*bf.Contract = util.Uint160{3, 2, 1}
|
||||||
|
require.NotEqual(t, bf, tf)
|
||||||
|
|
||||||
|
bf.Name = new(string)
|
||||||
|
*bf.Name = "ololo"
|
||||||
|
|
||||||
|
tf = bf.Copy()
|
||||||
|
require.Equal(t, bf, tf)
|
||||||
|
*bf.Name = "azaza"
|
||||||
|
require.NotEqual(t, bf, tf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExecutionFilterCopy(t *testing.T) {
|
||||||
|
var bf, tf *ExecutionFilter
|
||||||
|
|
||||||
|
require.Nil(t, bf.Copy())
|
||||||
|
|
||||||
|
bf = new(ExecutionFilter)
|
||||||
|
tf = bf.Copy()
|
||||||
|
require.Equal(t, bf, tf)
|
||||||
|
|
||||||
|
bf.State = new(string)
|
||||||
|
*bf.State = "ololo"
|
||||||
|
|
||||||
|
tf = bf.Copy()
|
||||||
|
require.Equal(t, bf, tf)
|
||||||
|
*bf.State = "azaza"
|
||||||
|
require.NotEqual(t, bf, tf)
|
||||||
|
|
||||||
|
bf.Container = &util.Uint256{1, 2, 3}
|
||||||
|
|
||||||
|
tf = bf.Copy()
|
||||||
|
require.Equal(t, bf, tf)
|
||||||
|
*bf.Container = util.Uint256{3, 2, 1}
|
||||||
|
require.NotEqual(t, bf, tf)
|
||||||
|
}
|
|
@ -71,39 +71,6 @@ type (
|
||||||
Payload []interface{} `json:"params"`
|
Payload []interface{} `json:"params"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockFilter is a wrapper structure for the block event filter. It allows
|
|
||||||
// to filter blocks by primary index and/or by block index (allowing blocks
|
|
||||||
// since/till the specified index inclusively). nil value treated as missing
|
|
||||||
// filter.
|
|
||||||
BlockFilter struct {
|
|
||||||
Primary *int `json:"primary,omitempty"`
|
|
||||||
Since *uint32 `json:"since,omitempty"`
|
|
||||||
Till *uint32 `json:"till,omitempty"`
|
|
||||||
}
|
|
||||||
// TxFilter is a wrapper structure for the transaction event filter. It
|
|
||||||
// allows to filter transactions by senders and/or signers. nil value treated
|
|
||||||
// as missing filter.
|
|
||||||
TxFilter struct {
|
|
||||||
Sender *util.Uint160 `json:"sender,omitempty"`
|
|
||||||
Signer *util.Uint160 `json:"signer,omitempty"`
|
|
||||||
}
|
|
||||||
// NotificationFilter is a wrapper structure representing a filter used for
|
|
||||||
// notifications generated during transaction execution. Notifications can
|
|
||||||
// be filtered by contract hash and/or by name. nil value treated as missing
|
|
||||||
// filter.
|
|
||||||
NotificationFilter struct {
|
|
||||||
Contract *util.Uint160 `json:"contract,omitempty"`
|
|
||||||
Name *string `json:"name,omitempty"`
|
|
||||||
}
|
|
||||||
// ExecutionFilter is a wrapper structure used for transaction and persisting
|
|
||||||
// scripts execution events. It allows to choose failing or successful
|
|
||||||
// transactions and persisting scripts based on their VM state and/or to
|
|
||||||
// choose execution event with the specified container. nil value treated as
|
|
||||||
// missing filter.
|
|
||||||
ExecutionFilter struct {
|
|
||||||
State *string `json:"state,omitempty"`
|
|
||||||
Container *util.Uint256 `json:"container,omitempty"`
|
|
||||||
}
|
|
||||||
// SignerWithWitness represents transaction's signer with the corresponding witness.
|
// SignerWithWitness represents transaction's signer with the corresponding witness.
|
||||||
SignerWithWitness struct {
|
SignerWithWitness struct {
|
||||||
transaction.Signer
|
transaction.Signer
|
||||||
|
|
|
@ -668,7 +668,8 @@ func (c *WSClient) performSubscription(params []interface{}, rcvr notificationRe
|
||||||
func (c *WSClient) SubscribeForNewBlocks(primary *int) (string, error) {
|
func (c *WSClient) SubscribeForNewBlocks(primary *int) (string, error) {
|
||||||
var flt interface{}
|
var flt interface{}
|
||||||
if primary != nil {
|
if primary != nil {
|
||||||
flt = neorpc.BlockFilter{Primary: primary}
|
var f = neorpc.BlockFilter{Primary: primary}
|
||||||
|
flt = *f.Copy()
|
||||||
}
|
}
|
||||||
params := []interface{}{"block_added"}
|
params := []interface{}{"block_added"}
|
||||||
if flt != nil {
|
if flt != nil {
|
||||||
|
@ -691,6 +692,7 @@ func (c *WSClient) ReceiveBlocks(flt *neorpc.BlockFilter, rcvr chan<- *block.Blo
|
||||||
}
|
}
|
||||||
params := []interface{}{"block_added"}
|
params := []interface{}{"block_added"}
|
||||||
if flt != nil {
|
if flt != nil {
|
||||||
|
flt = flt.Copy()
|
||||||
params = append(params, *flt)
|
params = append(params, *flt)
|
||||||
}
|
}
|
||||||
r := &blockReceiver{
|
r := &blockReceiver{
|
||||||
|
@ -708,7 +710,8 @@ func (c *WSClient) ReceiveBlocks(flt *neorpc.BlockFilter, rcvr chan<- *block.Blo
|
||||||
func (c *WSClient) SubscribeForNewTransactions(sender *util.Uint160, signer *util.Uint160) (string, error) {
|
func (c *WSClient) SubscribeForNewTransactions(sender *util.Uint160, signer *util.Uint160) (string, error) {
|
||||||
var flt interface{}
|
var flt interface{}
|
||||||
if sender != nil || signer != nil {
|
if sender != nil || signer != nil {
|
||||||
flt = neorpc.TxFilter{Sender: sender, Signer: signer}
|
var f = neorpc.TxFilter{Sender: sender, Signer: signer}
|
||||||
|
flt = *f.Copy()
|
||||||
}
|
}
|
||||||
params := []interface{}{"transaction_added"}
|
params := []interface{}{"transaction_added"}
|
||||||
if flt != nil {
|
if flt != nil {
|
||||||
|
@ -731,6 +734,7 @@ func (c *WSClient) ReceiveTransactions(flt *neorpc.TxFilter, rcvr chan<- *transa
|
||||||
}
|
}
|
||||||
params := []interface{}{"transaction_added"}
|
params := []interface{}{"transaction_added"}
|
||||||
if flt != nil {
|
if flt != nil {
|
||||||
|
flt = flt.Copy()
|
||||||
params = append(params, *flt)
|
params = append(params, *flt)
|
||||||
}
|
}
|
||||||
r := &txReceiver{
|
r := &txReceiver{
|
||||||
|
@ -749,7 +753,8 @@ func (c *WSClient) ReceiveTransactions(flt *neorpc.TxFilter, rcvr chan<- *transa
|
||||||
func (c *WSClient) SubscribeForExecutionNotifications(contract *util.Uint160, name *string) (string, error) {
|
func (c *WSClient) SubscribeForExecutionNotifications(contract *util.Uint160, name *string) (string, error) {
|
||||||
var flt interface{}
|
var flt interface{}
|
||||||
if contract != nil || name != nil {
|
if contract != nil || name != nil {
|
||||||
flt = neorpc.NotificationFilter{Contract: contract, Name: name}
|
var f = neorpc.NotificationFilter{Contract: contract, Name: name}
|
||||||
|
flt = *f.Copy()
|
||||||
}
|
}
|
||||||
params := []interface{}{"notification_from_execution"}
|
params := []interface{}{"notification_from_execution"}
|
||||||
if flt != nil {
|
if flt != nil {
|
||||||
|
@ -772,6 +777,7 @@ func (c *WSClient) ReceiveExecutionNotifications(flt *neorpc.NotificationFilter,
|
||||||
}
|
}
|
||||||
params := []interface{}{"notification_from_execution"}
|
params := []interface{}{"notification_from_execution"}
|
||||||
if flt != nil {
|
if flt != nil {
|
||||||
|
flt = flt.Copy()
|
||||||
params = append(params, *flt)
|
params = append(params, *flt)
|
||||||
}
|
}
|
||||||
r := &executionNotificationReceiver{
|
r := &executionNotificationReceiver{
|
||||||
|
@ -793,7 +799,8 @@ func (c *WSClient) SubscribeForTransactionExecutions(state *string) (string, err
|
||||||
if *state != "HALT" && *state != "FAULT" {
|
if *state != "HALT" && *state != "FAULT" {
|
||||||
return "", errors.New("bad state parameter")
|
return "", errors.New("bad state parameter")
|
||||||
}
|
}
|
||||||
flt = neorpc.ExecutionFilter{State: state}
|
var f = neorpc.ExecutionFilter{State: state}
|
||||||
|
flt = *f.Copy()
|
||||||
}
|
}
|
||||||
params := []interface{}{"transaction_executed"}
|
params := []interface{}{"transaction_executed"}
|
||||||
if flt != nil {
|
if flt != nil {
|
||||||
|
@ -822,6 +829,7 @@ func (c *WSClient) ReceiveExecutions(flt *neorpc.ExecutionFilter, rcvr chan<- *s
|
||||||
return "", errors.New("bad state parameter")
|
return "", errors.New("bad state parameter")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
flt = flt.Copy()
|
||||||
params = append(params, *flt)
|
params = append(params, *flt)
|
||||||
}
|
}
|
||||||
r := &executionReceiver{
|
r := &executionReceiver{
|
||||||
|
@ -840,7 +848,8 @@ func (c *WSClient) ReceiveExecutions(flt *neorpc.ExecutionFilter, rcvr chan<- *s
|
||||||
func (c *WSClient) SubscribeForNotaryRequests(sender *util.Uint160, mainSigner *util.Uint160) (string, error) {
|
func (c *WSClient) SubscribeForNotaryRequests(sender *util.Uint160, mainSigner *util.Uint160) (string, error) {
|
||||||
var flt interface{}
|
var flt interface{}
|
||||||
if sender != nil || mainSigner != nil {
|
if sender != nil || mainSigner != nil {
|
||||||
flt = neorpc.TxFilter{Sender: sender, Signer: mainSigner}
|
var f = neorpc.TxFilter{Sender: sender, Signer: mainSigner}
|
||||||
|
flt = *f.Copy()
|
||||||
}
|
}
|
||||||
params := []interface{}{"notary_request_event"}
|
params := []interface{}{"notary_request_event"}
|
||||||
if flt != nil {
|
if flt != nil {
|
||||||
|
@ -865,6 +874,7 @@ func (c *WSClient) ReceiveNotaryRequests(flt *neorpc.TxFilter, rcvr chan<- *resu
|
||||||
}
|
}
|
||||||
params := []interface{}{"notary_request_event"}
|
params := []interface{}{"notary_request_event"}
|
||||||
if flt != nil {
|
if flt != nil {
|
||||||
|
flt = flt.Copy()
|
||||||
params = append(params, *flt)
|
params = append(params, *flt)
|
||||||
}
|
}
|
||||||
r := ¬aryRequestReceiver{
|
r := ¬aryRequestReceiver{
|
||||||
|
|
Loading…
Reference in a new issue