Skip to content

RUES (Rusk Universal Event System)

Matteo Ferretti edited this page Apr 11, 2024 · 9 revisions

The Rusk Universal Event System (RUES) is a key component of the Dusk blockchain network, facilitating real-time communication and interactions across the ecosystem. This document delineates the specifications for event dispatch, subscription, and unsubscription within the RUES framework for external clients.

Clients may engage with a Rusk node through the operations: dispatch, subscribe, and unsubscribe. These interactions employ the HTTP protocol. An active session between the client and the node is a prerequisite for receiving events.

Session Management

Initialization

A session is established through an initial handshake, which involves requesting a WebSocket connection from a Rusk node. A successful handshake results in the client receiving a Rusk-Session-Id as the initial message, which is essential for subsequent event subscription and unsubscription actions. This session identifier is recommended to be a unique value derived by salting the Sec-WebSocket-Key. Future implementations may consider using HTTP Origin-Bound Authentication (HOBA).

Note

A node may refuse the connection at its discretion. Reasons for refusal can include, among others, an excessive number of current connections or the node's configurations restricting the availability of event interactions to external clients.

Persistence

The WebSocket connection serves as the conduit for transmitting subscribed events to the client. In load-balanced environments, it is crucial to ensure consistent routing of requests to the same server instance.

Termination

Either party — client or Rusk node — may terminate a session by closing the WebSocket connection, which automatically unsubscribes all associated events.

Event Subscription

Clients subscribe to events by issuing a GET HTTP request to the node, structured as follows:

GET https://[node address]/events/[component]/[target]/[topic]

Example

A hypothetical events subscription for a contract could be:

GET https://nodes.dusk.network/events/contracts/H9HRci8iW23cL1V8oKRNCGGasDCZYoXepWgaTpD53x2M/item-added

GET https://nodes.dusk.network/events/contracts/H9HRci8iW23cL1V8oKRNCGGasDCZYoXepWgaTpD53x2M/item-removed

GET https://nodes.dusk.network/events/contracts/H9HRci8iW23cL1V8oKRNCGGasDCZYoXepWgaTpD53x2M/item-changed

List of HTTP headers

Name Description
Rusk-Version Specifies the compatible Rusk version
Rusk-Session-Id Identifies the current session

Return value

Status code When
200 OK Successful subscription
400 Bad Request Rusk-Version incompatibility
424 Failed Dependency Rusk-Session-Id issues
404 Not Found [component] or [target] not found

Note

  1. Clients may subscribe to events that the contract may never actually emit.
  2. The encoding of the contract's address follows the base58 format, mirroring the encoding used for wallet addresses.

Event Unsubscription

Unsubscription mimics the subscription process but employs the DELETE method:

DELETE https://[node address]/events/[component]/[target]/[topic]

Example

DELETE https://nodes.dusk.network/events/contracts/H9HRci8iW23cL1V8oKRNCGGasDCZYoXepWgaTpD53x2M/item-added

DELETE  https://nodes.dusk.network/events/contracts/H9HRci8iW23cL1V8oKRNCGGasDCZYoXepWgaTpD53x2M/item-removed

DELETE  https://nodes.dusk.network/events/contracts/H9HRci8iW23cL1V8oKRNCGGasDCZYoXepWgaTpD53x2M/item-changed

List of HTTP headers

Name Description
Rusk-Version Specifies the compatible Rusk version
Rusk-Session-Id Identifies the current session

Return value

Status code When
200 OK Successful unsubscription
400 Bad Request Rusk-Version incompatibility
424 Failed Dependency Rusk-Session-Id issues
404 Not Found [component], [target] or [topic] not found

Note

A prerequisite for unsubscribing from a topic is that it must have been previously subscribed to; failure to meet this condition will result in a 404 Not Found error. This represents a notable distinction from the subscription process.

Event Dispatch

To dispatch events, clients use a POST request, potentially including a payload in the request body:

POST https://[node address]/events/[component]/[target]/[topic]

Dispatching an event is very different from the other two method, since it will most likely have a body, that is the payload of the event.

Example

POST https://nodes.dusk.network/events/contracts/H9HRci8iW23cL1V8oKRNCGGasDCZYoXepWgaTpD53x2M/sync

[content]

List of HTTP headers

Name Description
Rusk-Version Specifies the compatible Rusk version
Rusk-Session-Id Identifies the current session
Content-Type Usually application/json or application/octet-stream
Content-Length The length of the message body in octets (8-bit bytes).
Accept Media type(s) that is/are acceptable for a response message

In this context, the Rusk-Session-Id is optional, accommodating scenarios where a client dispatches an event for an immediate response or for a transaction that does not require subsequent interaction, effectively a "fire-and-forget" operation.

Return value

Status code When
200 OK The event was received successfully and a response is generated in return
202 Accepted The event was received successfully.
400 Bad Request Rusk-Version mismatch
424 Failed Dependency Rusk-Session-Id does not match
404 Not Found [component] and/or [target] and/or [topic] cannot be found
422 Unprocessable Content The event's payload cannot processed with the Content-Type given

Receiving Events

Subscribed events are delivered via the WebSocket connection in binary format, structured to include header information followed by the event payload.

Message structure

Type Description
u32 The length of the headers in LE
[u8] JSON-formatted request headers
[u8] Event data

List of headers

The message's header mimic the HTTP header, and are stored in a JSON key / value dictonary of type { String : String }

Name Description
Content-Location Event dispatch relative URL (e.g. contracts/H9HRci8iW23cL1V8oKRNCGGasDCZYoXepWgaTpD53x2M/item-added)
Content-Type Usually application/json or application/octet-stream
Content-Length The length of the message body in octets (8-bit bytes).

Note

The streaming of messages at the moment is not supported, since we're not expecting a single event to deliver more than 2^63 bytes.

Event Restrictions

Event interactions with a node, including dispatching, subscribing, and unsubscribing, are facilitated through HTTP methods and share a common URL structure tailored to each event. This setup allows for granular access control at the proxy level, enabling precise restriction of event operations even when the node permits external client interactions.

Access Control Examples

The following table illustrates various access restrictions that can be applied to event operations based on HTTP methods and URL patterns:

Restriction Description
DENY GET /events/ Blocks subscription and unsubscription operations (unsubscription requires a pre-existing subscription); however, dispatching events remains permitted.
DENY GET, POST /events/ Prevents subscription, unsubscription, and dispatching operations across all events.
DENY GET, POST /events/contracts Disallows subscription, unsubscription, and dispatching for events related to the contracts component, while permitting these operations for other components (e.g., chain).
DENY GET, POST /events/contracts/H9HRci8iW23cL1V8oKRNCGGasDCZYoXepWgaTpD53x2M Restricts subscription, unsubscription, and dispatching for events associated with the specific contract H9HRci8iW23cL1V8oKRNCGGasDCZYoXepWgaTpD53x2M, but allows for other contracts and components.
DENY GET /events/contracts/H9HRci8iW23cL1V8oKRNCGGasDCZYoXepWgaTpD53x2M/item-changed Blocks subscription to the specific event item-changed for the target contract.
DENY POST /events/contracts/H9HRci8iW23cL1V8oKRNCGGasDCZYoXepWgaTpD53x2M/sync Prohibits dispatching the specific event sync for the targeted contract.
DENY POST /events/contracts/*/sync Forbids dispatching the sync event for any contract within the contracts component.

This structured approach ensures that nodes can maintain a high degree of security and operational integrity by precisely controlling how and by whom event operations are conducted.

Clone this wiki locally