github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/docs/source/rest_api/state_delta_websockets.rst (about)

     1  *****************************************
     2  State Delta Subscriptions via Web Sockets
     3  *****************************************
     4  
     5  As transactions are committed to the blockchain, an app developer may be
     6  interested in receiving events related to the changes in state that result.
     7  These events, `StateDeltaEvents`, include information about the advance of the
     8  blockchain, as well as state changes that can be limited to specific address
     9  spaces in the global state.
    10  
    11  An application can subscribe to receive these events via a web socket, provided
    12  by the REST API component.  For example, a single-page JavaScript application may
    13  open a web socket connection and subscribe to a particular transaction family's
    14  state values, using the incoming events to re-render portions of the display.
    15  
    16  .. note::
    17  
    18     All examples here are written in JavaScript, and assumes the Sawtooth REST
    19     API is reachable at `localhost`.
    20  
    21  Opening a Web Socket
    22  ====================
    23  
    24  The application developer must first open a web socket. This is accomplished
    25  by using standard means.  In the case of in-browser JavaScript:
    26  
    27  .. code-block:: javascript
    28  
    29     let ws = new WebSocket('ws:localhost:8008/subscriptions')
    30  
    31  If the REST API is running, it should trigger an event on the web socket's
    32  `onopen` handler.
    33  
    34  Subscribing to State Changes
    35  ============================
    36  
    37  In order to subscribe to an address space in the global state, first a message
    38  needs to be sent on the socket with the list of prefixes. It is a best-practice
    39  to send this message as part of the web socket's `onopen` handler.
    40  
    41  In the following example, we'll subscribe to changes in the XO family:
    42  
    43  .. code-block:: javascript
    44  
    45    ws.onopen = () => {
    46      ws.send(JSON.stringify({
    47        'action': 'subscribe',
    48        'address_prefixes': ['5b7349']
    49      }))
    50    }
    51  
    52  This message will begin the subscription of events as of the current block.  If
    53  you are interested in the state prior to the point of subscription, you should
    54  fetch the values of state via the REST API's `/state` endpoint.
    55  
    56  Subscriptions may be changed by sending a subscribe message at later time while
    57  the websocket is open.  It is up to the client to maintain the list of address
    58  prefixes of interest.  Any subsequent subscriptions will overwrite this list.
    59  
    60  
    61  Events
    62  ======
    63  
    64  Once subscribed, events will be received via the web socket's `onmessage`
    65  handler. The event data is a JSON string, which looks like the following:
    66  
    67  .. code-block:: javascript
    68  
    69    {
    70      "block_num": 8,
    71      "block_id": "ab7cbc7a...",
    72      "previous_block_id": "d4b46c1c...",
    73      "state_changes": [
    74        {
    75          "type": "SET",
    76          "value": "oWZQdmxqcmsZU4w"=,
    77          "address": "1cf126613a..."
    78        },
    79        ...
    80      ]
    81    }
    82  
    83  There is an entry in the `state_changes` array for each address that matches the
    84  `address_prefixes` provided during the subscribe action.  The type is either
    85  "SET" or "DELETE".  In the case of "SET" the value is base-64 encoded (like the
    86  `/state` endpoint's response).  In the case of "DELETE", only the address is
    87  provided. If you are using a transaction family that supports deletes, you'll
    88  need to keep track of values via address, as well.
    89  
    90  Missed Events
    91  -------------
    92  
    93  In the case where you have missed an event, a request can be sent via the web
    94  socket for a particular block's changes.  You can use the `previous_block_id`
    95  from the current event to request the previous block's events, for example.
    96  Send the following message:
    97  
    98  .. code-block:: javascript
    99  
   100    ws.send(JSON.stringify({
   101      'action': 'get_block_deltas',
   102      'block_id': 'd4b46c1c...',
   103      'address_prefixes': ['5b7349']
   104    }))
   105  
   106  The event will be returned in the same manner as any other event, so it is
   107  recommended that you push the events on to a stack before processing them.
   108  
   109  If the block id does not exist, the following error will be returned:
   110  
   111  .. code-block:: javascript
   112  
   113    {
   114      "error": "Must specify a block id"
   115    }
   116  
   117  Unsubscribing
   118  =============
   119  
   120  To unsubscribe, you can either close the web socket, or if you want to
   121  unsubscribe temporarily, you can send an unsubscribe action:
   122  
   123  .. code-block:: javascript
   124  
   125    ws.send(JSON.stringify({
   126      'action': 'unsubscribe'
   127    }))
   128  
   129  
   130  Errors and Warnings
   131  ===================
   132  
   133  An open, subscribed web socket may receive the following errors and warnings:
   134  
   135  * the validator is unavailable
   136  * an unknown action was requested
   137  
   138  If the validator is unavailable to the REST API process, a warning will be sent
   139  in lieu of a state delta event:
   140  
   141  .. code-block:: javascript
   142  
   143    {
   144      "warning": "Validator unavailable"
   145    }
   146  
   147  If an unrecognized action is sent on to the server via the websocket, an error
   148  message will be sent back:
   149  
   150  .. code-block:: javascript
   151  
   152    {
   153      "error": "Unknown action \"bad_action\""
   154    }
   155  
   156  
   157  .. Licensed under Creative Commons Attribution 4.0 International License
   158  .. https://creativecommons.org/licenses/by/4.0/