Module p2panda_rs::operation

source ·
Expand description

Create, encode and decode p2panda operations.

Operations describe data mutations in the p2panda network. Authors send operations to create, update or delete documents.

Every operations contains application data which is formed after a schema. To be able to decode an operation, a schema aids with getting the data out of the operation.

Build or decode operation

There are two approaches (similar to Entry) to create an Operation.

To programmatically create an Operation, use the OperationBuilder. When working with operations coming in as bytes, you can use the decode_operation method to first deserialize it into a PlainOperation instance, which is a schemaless object giving you already access to the “header” data, like the schema id.

Knowing the schema id you can look up your internal database for known schemas and derive a Schema instance from there. Now together with the PlainOperation and Schema you can finally validate the operation (via validate_operation) to arrive at the final, verified Operation.

             ┌────────────────┐
             │OperationBuilder├──────────build()──────────────┐
             └────────────────┘                               │
                                                              │
                                                              │
                                                              ▼
                                        ┌──────┐          ┌─────────┐
                                        │Schema│          │Operation│
                                        └──┬───┘          └─────────┘
                                           │                  ▲
                          Lookup Schema    │                  │
                                           │                  │
             ┌──────────────┐              ▼                  │
             │PlainOperation├───────validate_operation()──────┘
             └──────────────┘
                    ▲
                    │
            decode_operation()
                    │
            ┌───────┴────────┐
bytes ────► │EncodedOperation│
            └────────────────┘

Please note that Operation in itself is immutable and can not directly be deserialized, there are only these above mentioned approaches to arrive at it. Both approaches apply all means to validate the integrity and correct encoding of the operation as per specification.

Encoding

Operation structs can be encoded again into their raw bytes form like that, for this no Schema is required:

┌─────────┐                           ┌────────────────┐
│Operation│ ───encode_operation()───► │EncodedOperation│ ────► bytes
└─────────┘                           └────────────────┘

Validation

The above mentioned high-level methods will automatically apply different sorts of validation checks. All low-level methods can also be used independently, depending on your implementation:

  1. Correct hexadecimal encoding (when using human-readable encoding format) (#OP1)
  2. Correct operation format as per specification, including canonic format checks against duplicate and unsorted operation fields (#OP2)
  3. Correctly formatted and canonic operation field values, like document view ids (no duplicates, sorted, when no semantic value is given by that) as per specification (#OP3)
  4. Operation fields match the claimed schema (#OP4)

Both #OP2 and #OP3 check against the canonic format but in separate steps, this is required as we can only check for the correct format of the operation field values, like document view ids after we obtained the schema, while we can already check the correct operation format before.

This module also provides a high-level method validate_operation_with_entry which will apply all checks required to verify the integrity of an operation and entry. This includes all validation steps listed above plus the ones mentioned in the entry module. Since this validation requires you to provide a Schema instance and the regarding back- & skiplink Entry instances yourself, it needs some preparation from your end which can roughly be described like this:

                                                                 Look-Up

            ┌────────────┐                       ┌─────┐    ┌─────┐    ┌─────┐
 bytes ───► │EncodedEntry├────decode_entry()────►│Entry│    │Entry│    │Entry│
            └──────┬─────┘                       └──┬──┘    └─────┘    └─────┘
                   │                                │
                   └───────────────────────────┐    │       Skiplink   Backlink
                                               │    │          │          │
            ┌────────────────┐                 │    │          │          │
 bytes ───► │EncodedOperation├─────────────┐   │    │          │          │
            └───────┬────────┘             │   │    │          │          │
                    │                      │   │    │          │          │
            decode_operation()             │   │    │          │          │
                    │            Look-Up   │   │    │          │          │
                    ▼                      │   │    │          │          │
             ┌──────────────┐    ┌──────┐  │   │    │          │          │
             │PlainOperation│    │Schema│  │   │    │          │          │
             └──────┬───────┘    └──┬───┘  │   │    │          │          │
                    │               │      │   │    │          │          │
                    │               │      │   │    │          │          │
                    │               │      │   │    │          │          │
                    │               │      │   │    │          │          │
                    │               ▼      ▼   ▼    ▼          ▼          │
                    └───────────►  validate_operation_with_entry() ◄──────┘
                                                │
                                                │
                                                │
                                                │
                                                ▼
                                    ┌────────────────────────┐
                                    │(Operation, OperationId)│
                                    └────────────────────────┘

Modules

  • Methods to decode an operation and validate it against its claimed schema.
  • Methods to encode operations.
  • Error types for encoding, decoding and validating operations with schemas and regarding data types like operation fields, relations or plain operations.
  • Intermediary operation type which was not checked against a schema yet.
  • Interfaces for interactions for operation-like structs.
  • Collection of low-level validation methods for operations.

Structs

  • Wrapper type for operation bytes.
  • Operations describe data mutations of “documents” in the p2panda network. Authors send operations to CREATE, UPDATE or DELETE documents.
  • Create new operations.
  • Operation fields are used to store application data. They are implemented as a simple key/value store with support for a limited number of data types (see OperationValue for further documentation on this). A OperationFields instance can contain any number and types of fields. However, when a OperationFields instance is attached to a Operation, the operation’s schema determines which fields may be used.
  • Uniquely identifies an Operation.
  • Reference to the exact version of the document.
  • A PinnedRelationList can be used to reference multiple documents views.
  • Field type representing references to other documents.
  • A RelationList can be used to reference multiple foreign documents from a document field.

Enums

  • Operations are categorised by their action type.
  • Enum of possible data types which can be added to the operations fields as values.
  • Operation format versions to introduce API changes in the future.