-
Notifications
You must be signed in to change notification settings - Fork 77
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 subsystem #895
Milestone
Comments
roman-khimov
added a commit
that referenced
this issue
May 12, 2020
A deep internal part of #895. Blockchainer interface is also extended for various uses of these methods.
roman-khimov
added a commit
that referenced
this issue
May 12, 2020
Note that the protocol differs a bit from #895 in its notifications format, to avoid additional server-side processing we're omitting some metadata like: * block size and confirmations * transaction fees, confirmations, block hash and timestamp * application execution doesn't have ScriptHash populated Some block fields may also differ in encoding compared to `getblock` results (like nonce field). I think these differences are unnoticieable for most use cases, so we can leave them as is, but it can be changed in the future.
roman-khimov
added a commit
that referenced
this issue
May 12, 2020
It differs from #895 design in that we have Notifications channel always exposed as WSClient field, probably it simplifies things a little.
Merged
roman-khimov
added a commit
that referenced
this issue
May 12, 2020
A deep internal part of #895. Blockchainer interface is also extended for various uses of these methods.
roman-khimov
added a commit
that referenced
this issue
May 12, 2020
Note that the protocol differs a bit from #895 in its notifications format, to avoid additional server-side processing we're omitting some metadata like: * block size and confirmations * transaction fees, confirmations, block hash and timestamp * application execution doesn't have ScriptHash populated Some block fields may also differ in encoding compared to `getblock` results (like nonce field). I think these differences are unnoticieable for most use cases, so we can leave them as is, but it can be changed in the future.
roman-khimov
added a commit
that referenced
this issue
May 12, 2020
It differs from #895 design in that we have Notifications channel always exposed as WSClient field, probably it simplifies things a little.
roman-khimov
added a commit
that referenced
this issue
May 12, 2020
Note that the protocol differs a bit from #895 in its notifications format, to avoid additional server-side processing we're omitting some metadata like: * block size and confirmations * transaction fees, confirmations, block hash and timestamp * application execution doesn't have ScriptHash populated Some block fields may also differ in encoding compared to `getblock` results (like nonce field). I think these differences are unnoticieable for most use cases, so we can leave them as is, but it can be changed in the future.
roman-khimov
added a commit
that referenced
this issue
May 12, 2020
It differs from #895 design in that we have Notifications channel always exposed as WSClient field, probably it simplifies things a little.
roman-khimov
added a commit
that referenced
this issue
May 13, 2020
Note that the protocol differs a bit from #895 in its notifications format, to avoid additional server-side processing we're omitting some metadata like: * block size and confirmations * transaction fees, confirmations, block hash and timestamp * application execution doesn't have ScriptHash populated Some block fields may also differ in encoding compared to `getblock` results (like nonce field). I think these differences are unnoticieable for most use cases, so we can leave them as is, but it can be changed in the future.
roman-khimov
added a commit
that referenced
this issue
May 13, 2020
It differs from #895 design in that we have Notifications channel always exposed as WSClient field, probably it simplifies things a little.
roman-khimov
added a commit
that referenced
this issue
May 14, 2020
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.
Done. |
roman-khimov
added a commit
that referenced
this issue
May 25, 2020
A deep internal part of #895. Blockchainer interface is also extended for various uses of these methods.
roman-khimov
added a commit
that referenced
this issue
May 25, 2020
Note that the protocol differs a bit from #895 in its notifications format, to avoid additional server-side processing we're omitting some metadata like: * block size and confirmations * transaction fees, confirmations, block hash and timestamp * application execution doesn't have ScriptHash populated Some block fields may also differ in encoding compared to `getblock` results (like nonce field). I think these differences are unnoticieable for most use cases, so we can leave them as is, but it can be changed in the future.
roman-khimov
added a commit
that referenced
this issue
May 25, 2020
It differs from #895 design in that we have Notifications channel always exposed as WSClient field, probably it simplifies things a little.
roman-khimov
added a commit
that referenced
this issue
May 25, 2020
Differing a bit from #895 draft specification, we won't add `sender` or `cosigner` to `transaction_executed`.
roman-khimov
added a commit
that referenced
this issue
May 26, 2020
Note that the protocol differs a bit from #895 in its notifications format, to avoid additional server-side processing we're omitting some metadata like: * block size and confirmations * transaction fees, confirmations, block hash and timestamp * application execution doesn't have ScriptHash populated Some block fields may also differ in encoding compared to `getblock` results (like nonce field). I think these differences are unnoticieable for most use cases, so we can leave them as is, but it can be changed in the future.
roman-khimov
added a commit
that referenced
this issue
May 26, 2020
It differs from #895 design in that we have Notifications channel always exposed as WSClient field, probably it simplifies things a little.
roman-khimov
added a commit
that referenced
this issue
May 26, 2020
Differing a bit from #895 draft specification, we won't add `sender` or `cosigner` to `transaction_executed`.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Overview
We need a notification system for smart contract developers. At the same time it might be interesting to have something similar to plugin system of the C# node (especially in the form described in neo-project/neo#1225), although its
IP2PPlugin
andIStoragePlugin
can directly affect node behaviour and plugins have synchronous model while we're mostly concerned with asynchronous notifications about chain state.Requirements
Primary requirements:
Primary usage model:
General solution
As we already have JSON-RPC support in our node it seems to be a good idea to extend it for notification service because it allows for some code reuse and makes our RPC client be the sole interface for interacting with node in various ways (it's expected that event listener might make additional requests to node based on events received). Still there are some caveats:
At the same time smart contract developers are not expected to be using public RPC nodes and a private node can be restricted in any way by regular network firewalling. Still we should make this subsystem optional and future synchronous call extensions should also add an additional option. We could make it a separate service on a different port, but it doesn't seem to be a good option for now because of expected usage model.
Which probably is OK given that we're starting to extend our existing JSON-RPC interface, but note that it differs from websockets usage in Neo 3 where P2P protocol is layered above them.
Initial events list (all about chain processing):
Contents: block.
Filters: none for Neo 2, primary index for Neo 3.
Contents: transaction.
Filters: type and verification script hash for Neo 2, transaction Sender and Cosigner for Neo 3.
Contents: container hash, contract script hash, stack item.
Filters: contract script hash. Note that for Neo 2 only transaction can be container, but for Neo 3 block itself can also produce some notifications.
Contents: application execution result.
Filters: VM state; transaction Sender and Cosigner for Neo 3.
Filters use conjunctional logic.
Ordering and persistence guarantees:
No disk-level persistence guarantees are given.
At first transaction execution is announced, then followed by notifications generated during this execution, then followed by transaction announcement (for Neo 2). Transaction announcements are ordered the same way they're in the block.
Other notes:
Extensions considered
Possible future extensions:
IMemoryPoolTxObserverPlugin
)ILogPlugin
)Can be dangerous as logs might contain some sensitive data about node configuration. At the same time it might be useful if restricted properly.
IP2PPlugin
)Might be useful for making neo-go compatible with things like Red4Sec/neo-resilience, but not a priority for now and also note that
IP2PPlugin
can affect message processing, so it's not just an event subsystem.Doesn't seem to be a priority because the primary target audience for this system is smart contract developers and most of the time they're dealing with one or two contracts/addresses.
Things we probably won't do (but they're used in neo-resilience):
OnCommit()
andShouldThrowExceptionFromCommit()
fromIPersistencePlugin
ShouldThrowExceptionFromCommit()
isn't really applicable to our model and the only value inOnCommit()
is that it synchronously exposes the new state before the chain moves on, I think block notification is a good enough alternative.OnPersist()
callback implementation fromIPersistencePlugin
Doesn't seem to be very useful as it can be substituted by subscribing to our transaction execution and block notifications.
Protocol specification draft
Websocket connection
Connection switch is done with a GET request to
/ws
path. Standard protocolupgrade happens after that and all subsequent messaging is being done via this
channel (including regular RPC calls).
Subscription management
subscribe
methodParameters: event stream name, stream-specific filter rules hash (can be
omitted if empty).
Recognized stream names:
block_added
No filter parameters for Neo 2,
primary
with integer value for Neo 3.transaction_added
Neo 2:
type
as a string containing standard transaction types(
MinerTransaction
,InvocationTransaction
, etc);verifier
as a stringcontaining hex-encoded Uint160. Neo 3:
sender
andcosigner
fieldscontaining string with hex-encoded Uint160.
notification_from_execution
contract
field containing string with hex-encoded Uint160.transaction_executed
Both versions:
state
containingHALT
orFAULT
string for successfuland failed executions respectively. Neo 3:
sender
andcosigner
fieldswith the same semantics as for
transaction_added
.Response: returns subscription ID (string) as a result.
Example request (subscribe to notifications from contract
0x6293a440ed80a427038e175a507d3def1e04fb67 generated when executing
transactions):
Example response:
unsubscribe
methodParameters: subscription ID as a string.
Response: boolean
true
.Example request (unsubscribe from "55aaff00"):
Example response:
Events
Events are sent as JSON-RPC notifications from the server with
method
fieldbeing used for notification names. Notification names are identical to stream
names described for
subscribe
method.Verbose responses for various structures like blocks and transactions are used
to simplify working with notifications on client side. Other models
considered:
Using them would require deserializing, which is not a problem for neo-go
client, but can be problematic in other circumstances
Which would simplify server's life, but we're suggesting that if there is a
subscription, then the client really is interested in the contents and so
requiring an additional request to get the real data reduces overall
efficiency in the end.
block_added
notificationAs a first parameter (
params
section) contains block converted to JSONstructure (similar to verbose
getblock
response). No other parameters aresent.
Example:
transaction_added
notificationIn the first parameter (
params
section) contains transaction converted to JSON(similar to verbose
getrawtransaction
response). No other parameters aresent.
notification_from_execution
notificationContains three parameters: container hash (Uint256 encoded in a string),
contract script hash (Uint160 encoded in a string) and stack item (encoded the
same way as
state
field contents for notifications fromgetapplicationlog
response).
Example:
transaction_executed
notificationContains the same result as from
getapplicationlog
method in the firstparameter and no other parameters.
Example:
Draft client-side API
The text was updated successfully, but these errors were encountered: