Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Notification filters 2.x #951

Merged
merged 7 commits into from
May 14, 2020
Merged

Notification filters 2.x #951

merged 7 commits into from
May 14, 2020

Conversation

roman-khimov
Copy link
Member

Problem

#895.

Solution

This one closes #895.

It's not practical adding server-side tests for 2.0 (as it requires generating
more blocks), so we'll leave it for 3.0.
Differing a bit from #895 draft specification, we won't add `verifier` (or
signer) for Neo 2, it's not worth doing so at the moment.
@roman-khimov roman-khimov added the rpc RPC server and client label May 14, 2020
@roman-khimov roman-khimov requested a review from fyrchik May 14, 2020 07:31
@codecov
Copy link

codecov bot commented May 14, 2020

Codecov Report

Merging #951 into master-2.x will decrease coverage by 0.49%.
The diff coverage is 47.22%.

Impacted file tree graph

@@              Coverage Diff               @@
##           master-2.x     #951      +/-   ##
==============================================
- Coverage       68.71%   68.22%   -0.50%     
==============================================
  Files             143      144       +1     
  Lines           13912    14172     +260     
==============================================
+ Hits             9560     9669     +109     
- Misses           3913     4050     +137     
- Partials          439      453      +14     
Impacted Files Coverage Δ
pkg/core/transaction/attribute.go 9.77% <0.00%> (-21.18%) ⬇️
pkg/rpc/response/result/block.go 0.00% <0.00%> (ø)
pkg/core/block/block.go 78.49% <58.33%> (-7.02%) ⬇️
pkg/rpc/server/server.go 82.53% <69.11%> (-1.02%) ⬇️
pkg/core/block/block_base.go 78.16% <74.35%> (-3.09%) ⬇️
pkg/rpc/client/wsclient.go 84.13% <82.35%> (-0.31%) ⬇️
pkg/rpc/request/param.go 93.97% <93.93%> (-1.80%) ⬇️
pkg/rpc/server/subscription.go 94.73% <94.73%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1d5734c...8cd7bc7. Read the comment docs.

drainloop:
for {
select {
case _, ok := <-subChan:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why exactly do u need this ok? (instead of blocking recv)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be fair, it's not strictly needed as no one closes subChan, but it's a safety guard in case it changes in the future for some reason.

default:
sub.overflown.Store(true)
// MissedEvent is to be delivered eventually.
go func(sub *subscriber) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is at most one such goroutine for each (sub, eventID) pair in each moment of time, am I right?
I care about executing .Store(false) 2 lines below while there are 2 goroutines executing concurrently.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually at most one per sub as we skip overflown subscribers completely.

if (*val).State == "HALT" || (*val).State == "FAULT" {
p.Value = *val
} else {
continue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why no error here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe there is a better fit for this JSON, not ExecutionFilter. At the moment, of course that could only be []Param which is unlikely to be a match if we're this deep with ExecutionFilter, but it also might change in the future.

case response.TransactionEventID:
filt := f.filter.(request.TxFilter)
tx := r.Payload[0].(*transaction.Transaction)
if tx.Type == filt.Type {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can replace it with return tx.Type == filt.Type here and below, which will look more compact.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

"tx matching": {
params: `["transaction_added", {"type":"InvocationTransaction"}]`,
check: func(t *testing.T, resp *response.Notification) {
rmap := resp.Payload[0].(map[string]interface{})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does response.Notification.Payload[0] casts here to a map and in non-test code to a specific type?
Am I missing something?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a server test and it doesn't try to interpret these JSONs as real structures (it would complicate this test probably), instead it uses the same type server uses for marshaling and that has plain interface{} that is unmarshalled in standard encoding/json fashion.

// As Base and txes are at the same level in json,
// do unmarshalling separately for both structs.
txes := new(auxTxes)
base := new(Base)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe allocate it after this if?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

And check state string correctness on unmarshaling.
It actually was missing and it might affect Transaction conversion to/from
JSON.
Our block.Block was JSONized in a bit different fashion than result.Block in
its Nonce and NextConsensus fields. It's not good for notifications because
third-party clients would probably expect to see the same format. Also, using
completely different Block representation in result is probably making our
client a bit weaker as this representation is harder to use with other neo-go
components.

So use the same approach we took for Transactions and wrap block.Base which is
to be serialized in proper way.
The same data is copied at least three times here.
@roman-khimov roman-khimov merged commit f0abbfd into master-2.x May 14, 2020
@roman-khimov roman-khimov deleted the notification-filters-2.x branch May 14, 2020 17:57
@roman-khimov roman-khimov mentioned this pull request May 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rpc RPC server and client
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants