Skip to content

Commit 1f309d0

Browse files
authored
Merge pull request #61 from blinklabs-io/feat/filter-multiple-value
feat: support for multiple filter values
2 parents f5938d1 + 4d2fcef commit 1f309d0

File tree

7 files changed

+141
-73
lines changed

7 files changed

+141
-73
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@ plugins:
113113
114114
## Filtering
115115
116-
snek supports filtering events before they are output.
116+
snek supports filtering events before they are output using multiple criteria. An event must match all configured filters to be emitted.
117+
Each filter supports specifying multiple possible values separated by commas. When specifying multiple values for a filter, only one of
118+
the values specified must match an event.
117119
118120
You can get a list of all available filter options by using the `-h`/`-help` flag.
119121

@@ -172,6 +174,12 @@ Only output `chainsync.transaction` event types
172174
$ snek -filter-type chainsync.transaction
173175
```
174176

177+
Only output `chainsync.rollback` and `chainsync.block` event types
178+
179+
```bash
180+
$ snek -filter-type chainsync.transaction,chainsync.block
181+
```
182+
175183
#### Filtering on asset policy
176184

177185
Only output transactions involving an asset with a particular policy ID

filter/chainsync/chainsync.go

Lines changed: 67 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ import (
2323
)
2424

2525
type ChainSync struct {
26-
errorChan chan error
27-
inputChan chan event.Event
28-
outputChan chan event.Event
29-
filterAddress string
30-
filterPolicyId string
31-
filterAssetFingerprint string
26+
errorChan chan error
27+
inputChan chan event.Event
28+
outputChan chan event.Event
29+
filterAddresses []string
30+
filterPolicyIds []string
31+
filterAssetFingerprints []string
3232
}
3333

3434
// New returns a new ChainSync object with the specified options applied
@@ -57,74 +57,95 @@ func (c *ChainSync) Start() error {
5757
switch v := evt.Payload.(type) {
5858
case chainsync.TransactionEvent:
5959
// Check address filter
60-
if c.filterAddress != "" {
61-
isStakeAddress := false
62-
if strings.HasPrefix(c.filterAddress, "stake") {
63-
isStakeAddress = true
64-
}
65-
foundMatch := false
66-
for _, output := range v.Outputs {
67-
if output.Address().String() == c.filterAddress {
68-
foundMatch = true
69-
break
70-
}
71-
if isStakeAddress {
72-
stakeAddr := output.Address().StakeAddress()
73-
if stakeAddr == nil {
74-
continue
75-
}
76-
if stakeAddr.String() == c.filterAddress {
60+
if len(c.filterAddresses) > 0 {
61+
filterMatched := false
62+
for _, filterAddress := range c.filterAddresses {
63+
isStakeAddress := strings.HasPrefix(filterAddress, "stake")
64+
foundMatch := false
65+
for _, output := range v.Outputs {
66+
if output.Address().String() == filterAddress {
7767
foundMatch = true
7868
break
7969
}
70+
if isStakeAddress {
71+
stakeAddr := output.Address().StakeAddress()
72+
if stakeAddr == nil {
73+
continue
74+
}
75+
if stakeAddr.String() == filterAddress {
76+
foundMatch = true
77+
break
78+
}
79+
}
80+
}
81+
if foundMatch {
82+
filterMatched = true
83+
break
8084
}
8185
}
82-
if !foundMatch {
86+
// Skip the event if none of the filter values matched
87+
if !filterMatched {
8388
continue
8489
}
8590
}
8691
// Check policy ID filter
87-
if c.filterPolicyId != "" {
88-
foundMatch := false
89-
for _, output := range v.Outputs {
90-
if output.Assets() != nil {
91-
for _, policyId := range output.Assets().Policies() {
92-
if policyId.String() == c.filterPolicyId {
93-
foundMatch = true
94-
break
92+
if len(c.filterPolicyIds) > 0 {
93+
filterMatched := false
94+
for _, filterPolicyId := range c.filterPolicyIds {
95+
foundMatch := false
96+
for _, output := range v.Outputs {
97+
if output.Assets() != nil {
98+
for _, policyId := range output.Assets().Policies() {
99+
if policyId.String() == filterPolicyId {
100+
foundMatch = true
101+
break
102+
}
95103
}
96104
}
105+
if foundMatch {
106+
break
107+
}
97108
}
98109
if foundMatch {
110+
filterMatched = true
99111
break
100112
}
101113
}
102-
if !foundMatch {
114+
// Skip the event if none of the filter values matched
115+
if !filterMatched {
103116
continue
104117
}
105118
}
106119
// Check asset fingerprint filter
107-
if c.filterAssetFingerprint != "" {
108-
foundMatch := false
109-
for _, output := range v.Outputs {
110-
if output.Assets() != nil {
111-
for _, policyId := range output.Assets().Policies() {
112-
for _, assetName := range output.Assets().Assets(policyId) {
113-
assetFp := ledger.NewAssetFingerprint(policyId.Bytes(), assetName)
114-
if assetFp.String() == c.filterAssetFingerprint {
115-
foundMatch = true
120+
if len(c.filterAssetFingerprints) > 0 {
121+
filterMatched := false
122+
for _, filterAssetFingerprint := range c.filterAssetFingerprints {
123+
foundMatch := false
124+
for _, output := range v.Outputs {
125+
if output.Assets() != nil {
126+
for _, policyId := range output.Assets().Policies() {
127+
for _, assetName := range output.Assets().Assets(policyId) {
128+
assetFp := ledger.NewAssetFingerprint(policyId.Bytes(), assetName)
129+
if assetFp.String() == filterAssetFingerprint {
130+
foundMatch = true
131+
}
132+
}
133+
if foundMatch {
134+
break
116135
}
117136
}
118137
if foundMatch {
119138
break
120139
}
121140
}
122-
if foundMatch {
123-
break
124-
}
141+
}
142+
if foundMatch {
143+
filterMatched = true
144+
break
125145
}
126146
}
127-
if !foundMatch {
147+
// Skip the event if none of the filter values matched
148+
if !filterMatched {
128149
continue
129150
}
130151
}

filter/chainsync/option.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,23 @@ package chainsync
1616

1717
type ChainSyncOptionFunc func(*ChainSync)
1818

19-
// WithAddress specfies the address to filter on
20-
func WithAddress(address string) ChainSyncOptionFunc {
19+
// WithAddresses specfies the address to filter on
20+
func WithAddresses(addresses []string) ChainSyncOptionFunc {
2121
return func(c *ChainSync) {
22-
c.filterAddress = address
22+
c.filterAddresses = addresses[:]
2323
}
2424
}
2525

26-
// WithPolicy specfies the address to filter on
27-
func WithPolicy(policyId string) ChainSyncOptionFunc {
26+
// WithPolicies specfies the address to filter on
27+
func WithPolicies(policyIds []string) ChainSyncOptionFunc {
2828
return func(c *ChainSync) {
29-
c.filterPolicyId = policyId
29+
c.filterPolicyIds = policyIds[:]
3030
}
3131
}
3232

33-
//WithAssetFingerprint specifies the asset fingerprint (asset1xxx) to filter on
34-
func WithAssetFingerprint(assetFingerprint string) ChainSyncOptionFunc {
33+
//WithAssetFingerprints specifies the asset fingerprint (asset1xxx) to filter on
34+
func WithAssetFingerprints(assetFingerprints []string) ChainSyncOptionFunc {
3535
return func(c *ChainSync) {
36-
c.filterAssetFingerprint = assetFingerprint
36+
c.filterAssetFingerprints = assetFingerprints[:]
3737
}
3838
}

filter/chainsync/plugin.go

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
package chainsync
1616

1717
import (
18+
"strings"
19+
1820
"github.com/blinklabs-io/snek/plugin"
1921
)
2022

@@ -62,10 +64,31 @@ func init() {
6264
}
6365

6466
func NewFromCmdlineOptions() plugin.Plugin {
65-
p := New(
66-
WithAddress(cmdlineOptions.address),
67-
WithPolicy(cmdlineOptions.policyId),
68-
WithAssetFingerprint(cmdlineOptions.asset),
69-
)
67+
pluginOptions := []ChainSyncOptionFunc{}
68+
if cmdlineOptions.address != "" {
69+
pluginOptions = append(
70+
pluginOptions,
71+
WithAddresses(
72+
strings.Split(cmdlineOptions.address, ","),
73+
),
74+
)
75+
}
76+
if cmdlineOptions.policyId != "" {
77+
pluginOptions = append(
78+
pluginOptions,
79+
WithPolicies(
80+
strings.Split(cmdlineOptions.policyId, ","),
81+
),
82+
)
83+
}
84+
if cmdlineOptions.asset != "" {
85+
pluginOptions = append(
86+
pluginOptions,
87+
WithAssetFingerprints(
88+
strings.Split(cmdlineOptions.asset, ","),
89+
),
90+
)
91+
}
92+
p := New(pluginOptions...)
7093
return p
7194
}

filter/event/event.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ import (
1919
)
2020

2121
type Event struct {
22-
errorChan chan error
23-
inputChan chan event.Event
24-
outputChan chan event.Event
25-
filterType string
22+
errorChan chan error
23+
inputChan chan event.Event
24+
outputChan chan event.Event
25+
filterTypes []string
2626
}
2727

2828
// New returns a new Event object with the specified options applied
@@ -49,8 +49,15 @@ func (e *Event) Start() error {
4949
return
5050
}
5151
// Drop events if we have a type filter configured and the event doesn't match
52-
if e.filterType != "" {
53-
if evt.Type != e.filterType {
52+
if len(e.filterTypes) > 0 {
53+
matched := false
54+
for _, filterType := range e.filterTypes {
55+
if evt.Type == filterType {
56+
matched = true
57+
break
58+
}
59+
}
60+
if !matched {
5461
continue
5562
}
5663
}

filter/event/option.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ package event
1616

1717
type EventOptionFunc func(*Event)
1818

19-
// WithType specfies the event type to filter on
20-
func WithType(eventType string) EventOptionFunc {
19+
// WithTypes specfies the event types to filter on
20+
func WithTypes(eventTypes []string) EventOptionFunc {
2121
return func(e *Event) {
22-
e.filterType = eventType
22+
e.filterTypes = eventTypes[:]
2323
}
2424
}

filter/event/plugin.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
package event
1616

1717
import (
18+
"strings"
19+
1820
"github.com/blinklabs-io/snek/plugin"
1921
)
2022

@@ -44,8 +46,15 @@ func init() {
4446
}
4547

4648
func NewFromCmdlineOptions() plugin.Plugin {
47-
p := New(
48-
WithType(cmdlineOptions.eventType),
49-
)
49+
pluginOptions := []EventOptionFunc{}
50+
if cmdlineOptions.eventType != "" {
51+
pluginOptions = append(
52+
pluginOptions,
53+
WithTypes(
54+
strings.Split(cmdlineOptions.eventType, ","),
55+
),
56+
)
57+
}
58+
p := New(pluginOptions...)
5059
return p
5160
}

0 commit comments

Comments
 (0)