diff --git a/docs/images/message-store-service.png b/docs/images/message-store-service.png new file mode 100644 index 00000000..f9ef6897 Binary files /dev/null and b/docs/images/message-store-service.png differ diff --git a/docs/message-store-service.md b/docs/message-store-service.md new file mode 100644 index 00000000..da838ef0 --- /dev/null +++ b/docs/message-store-service.md @@ -0,0 +1,34 @@ +## Message Store Service +The *Message Store Service* is a simple REST service that stores messages forwarded from one or more Relayers, and serves them to clients upon request. +This service is an essential component for protocols such as GPACT that rely on the ability of off-chain components to query for the state of specific messages. + +### Features +- Store messages forwarded by Relayers +- Retrieve messages based on client request +- Aggregates proof information from multiple Relayers, if required +- Manage the lifecycle of messages if required (i.e. expiry and removal of messages) + +### Design and Specification +The *Message Store Service* consumes events that have been processed by Relayers. +The service can be configured to store all messages that pass through a Relayer or only a subset that require persistence (e.g. GPACT events). +A [specialised message dispatcher]("TODO") is responsible for forwarding messages to the store by interacting with its API. +Relayers can either create a message if it is not already in the Message Store, or update it with their own attestation (or other proof), if the message already exists. + +The service is responsible for ensuring that all create and update operations on messages can only be performed by authorised Relayers. +The specific authentication and authorisation mechanism to use is TBD, however the scheme should minimise the level of configuration required on the Relayer services. +This is because a Relayer might in future work with multiple Message Stores, some of which could be dynamically specified on a per-event basis. +This requires that the amount of context information that a Relayer requires when interacting with a *Message Store* be minimal. + +
+
+
Figure 1: Relayer interaction with Message Store Service
+ +The API for the *Message Store Service* is detailed in [this specification document](spec/message-store-service-api.yml). +It is defined using the [Open API Specification format](https://swagger.io/specification/) and can be displayed using the [Swagger UI tool](https://swagger.io/tools/swagger-ui/). + +#### TODOs +- [ ] Security +- [ ] Deployment considerations +- [ ] Proof aggregation +- [ ] Data Store description \ No newline at end of file diff --git a/docs/spec/message-store-service-api.yml b/docs/spec/message-store-service-api.yml new file mode 100644 index 00000000..05df8c87 --- /dev/null +++ b/docs/spec/message-store-service-api.yml @@ -0,0 +1,262 @@ +swagger: '2.0' +info: + description: >- + A service that stores and manages blockchain events forwarded by one or more + Relayer services. The blockchain events are stored in the canonical data + format employed by Relayer components. + version: 0.1.0 + title: Relayer Message Store Service +tags: + - name: messages + description: >- + Represents blockchain events in the canonical data format used by + Relayers. + - name: events + description: Represents raw blockchain events emitted by a network. +schemes: + - https +paths: + '/messages/{id}': + put: + tags: + - messages + summary: Adds or updates a Relayer message representing a blockchain event. + description: >- + The endpoint is used to submit (and create) a message if it does not + already exist in the store. If it does, the existing message is updated + to include the additional proof data of the submitting Relayer. Only + Relayers can add or update messages. + operationId: addOrUpdateMessage + consumes: + - application/json + produces: + - application/json + parameters: + - in: body + name: body + description: Message object to add to the store + required: true + schema: + $ref: '#/definitions/Message' + - name: id + in: path + description: ID of message to return + required: true + type: string + responses: + '200': + description: Exising message updated successfully + '201': + description: New message created successfully + '400': + description: Invalid input + '401': + description: Caller is not authorised to perform this operation + security: + - api_key: [] + get: + tags: + - messages + summary: 'Retrieve the message associated with the given ID, if it exists.' + description: >- + Returns the message object associated with the given ID, if it exists in + the store. + operationId: getMessageById + produces: + - application/json + parameters: + - name: id + in: path + description: ID of message to return + required: true + type: string + responses: + '200': + description: Successful retrieval of message + schema: + $ref: '#/definitions/Message' + '400': + description: Invalid ID supplied + '404': + description: Message not found + security: + - api_key: [] + '/messages/{id}/proofs': + get: + tags: + - messages + summary: >- + Retrieve all proofs that have been recorded for the message with the + given ID. + description: >- + Returns all proofs (e.g. attestations) that have been recorded for the + message with the given ID. + operationId: getProofs + produces: + - application/json + parameters: + - name: id + in: path + description: ID of message to return + required: true + type: string + responses: + '200': + description: Successful retrieval of message proofs + schema: + type: array + items: + $ref: '#/definitions/Proof' + '400': + description: Invalid ID supplied + '404': + description: Message not found + security: + - api_key: [] + post: + tags: + - messages + summary: Record a new proof for message. + description: Records a new proof for the message with a given ID. + operationId: addProof + consumes: + - application/json + produces: + - application/json + parameters: + - in: body + name: body + description: Message proof object to add to the store + required: true + schema: + type: array + items: + $ref: '#/definitions/Proof' + - name: id + in: path + description: ID of message to return + required: true + type: string + responses: + '200': + description: Proof successfuly added to message + '400': + description: Invalid ID or proof object supplied + '401': + description: Caller is not authorised to perform this operation + '404': + description: Message not found + '409': + description: Given message proof was already recorded + '422': + description: Validation of attestation failed + security: + - api_key: [] + '/events/{networkId}/{blockNumber}/{txIndex}/{logIndex}': + get: + tags: + - events + summary: >- + Retrieve's a message that represents the blockchain event identified + with the given path parameters. + description: >- + Returns a message that represents the identified blockchain event, if + one exists. This endpoint offers a convinient way for clients that only + know identifying details of an event (and not the associated Relayer + message), to interact with messages in the store. + operationId: getEvent + produces: + - application/json + parameters: + - name: networkId + in: path + description: ID of network in which the event was generated + required: true + type: string + - name: blockNumber + in: path + description: Block number that contains this event + required: true + type: string + - name: txIndex + in: path + description: Index number within the block for the transaction that generates the event + required: true + type: string + - name: logIndex + in: path + description: Index number of the event within the block + required: true + type: string + responses: + '200': + description: Successful retrieval of associated message + schema: + $ref: '#/definitions/Message' + '400': + description: One or more invalid path parameters provided + '404': + description: Message not found + security: + - api_key: [] +securityDefinitions: + api_key: + type: apiKey + name: api_key + in: header +definitions: + Proof: + type: object + required: + - type + - created + - proof + properties: + type: + type: string + created: + type: string + proof: + type: string + NetworkAddress: + type: object + required: + - networkId + - bridgeAddress + - contractAddress + properties: + networkId: + type: string + contractAddress: + type: string + bridgeAddress: + type: string + Meta: + type: object + required: + - timestamp + - version + properties: + timestamp: + type: string + version: + type: string + Message: + type: object + required: + - id + properties: + id: + type: string + meta: + $ref: '#/definitions/Meta' + destination: + $ref: '#/definitions/NetworkAddress' + source: + $ref: '#/definitions/NetworkAddress' + proofs: + type: array + items: + $ref: '#/definitions/Proof' + payload: + type: string