spacemeshos / SMIPS

Spacemesh Improvement Proposals
https://spacemesh.io
Creative Commons Zero v1.0 Universal
7 stars 1 forks source link

SVM Receipts Encoding #58

Closed YaronWittenstein closed 1 year ago

YaronWittenstein commented 3 years ago

Overview

This SMIP documents the exact binary encoding of Receipts. It'll also include ASCII charts to make it (hopefully) nicer to read.

Goals and motivation

The primary motivation for the SMIP is to give a full spec to be implemented by go-svm. After a transaction has completed, SVM will pass back a blob back (using the svm_byte_array) to go-svm.

In order to enable go-svm to reason about this blob it must know how to decode it properly.

High-level design

SVM has 3 types of Receipts - one for each kind of Transaction:

In order to simplify things, each encoded Receipt of a successful transaction starts the same:

Additionally, there is only one encoding Receipt for failed transactions. There was not good reason to keep a different Error encoding for each kind of transaction. So this design also reduces the amount of work for implementing this spec.

Proposed implementation

Here is the current Receipts encoding implementation for SVM v0.3

Successful Deploy Receipt

+-----------------------------------------------------------------------+
|          |             |             |                    |           |
| tx type  |   version   |  is_success | Template `Address` | gas_used  |
| (1 byte) |  (2 bytes)  |  (1 byte)   |     (20 bytes)     | (8 bytes) |
|          |             |             |                    |           |
+-----------------------------------------------------------------------+

Successful Spawn Receipt`

+---------------------------------------------------------+
|           |            |             |                  |
|  tx type  |  version   | is_success  |  Account Address |
| (1 byte)  | (2 bytes)  |  (1 byte)   |    (20 bytes)    |
|           |            |             |                  |
+---------------------------------------------------------+
|              |              |              |            |
|  init State  | returndata   |  returndata  |  gas_used  |
|  (32 bytes)  |  byte-size   |   (Blob)     | (8 bytes)  |
|              |  (2 bytes)   |              |            |
|              |              |              |            |
+---------------------------------------------------------+
|           |          |         |                        |
|  #logs    |  log #1  |  . . .  |       log #N           |
| (1 byte)  |  (Blob)  |         |       (Blob)           |
|           |          |         |                        |
+---------------------------------------------------------+

Successful Call Receipt

 +--------------------------------------------------+
|           |            |            |             |
|  tx type  |  version   | is_success |  new State  |
| (1 byte)  |  (2 bytes) |  (1 byte)  | (32 bytes)  |
|           |            |            |             |
+---------------------------------------------------+
|              |             |                      |
|  returndata  | returndata  |      gas_used        |
|   byte-size  |   (Blob)    |      (8 bytes)       |
|   (2 bytes)  |             |                      |
|              |             |                      |
+---------------------------------------------------+
|           |          |         |                  |
|  #logs    |  log #1  |  . . .  |     log #N       |
| (1 byte)  |  (Blob)  |         |     (Blob)       |
|           |          |         |                  |
+---------------------------------------------------+

Failed Transaction Receipts

+-------------------------------------------------------+
|          |              |             |               |
|  tx type |   version    |  is_success |  error code   |
| (1 byte) |  (2 bytes)   |   (1 byte)  |   (1 byte)    |
|          |              |             |               |  
+-------------------------------------------------------+
|          |          |         |            |          |
|  #logs   |  log #1  |  . . .  |  log #N-1  |  log #N  |
| (1 byte) |          |         |            |          |
|          |          |         |            |          |
+-------------------------------------------------------+
|                                                       |
|                     Error Blob                        |
|                                                       |
+-------------------------------------------------------+

Error Blob

The Error Blob is determined by the error code field.

Important:

Each Error Message Field is truncated to fit into at most 255 bytes. In such a case the Message might not make a valid UTF-String.

OOG (Out-of-Gas)

Error Blob is empty

Template Not Found

+---------------------+
|  Template Address   |
|     (20 bytes)      |
+---------------------+

Account Not Found

+---------------------+
|   Account Address   |
|     (20 bytes)      |
+---------------------+

Compilation Failed

+-------------------+-----------------+-----------------+
|  Template Address | Account Address |     Message     |
|   (20 bytes)      |  (20 bytes)     |  (UTF-8 String) |
+-------------------+-----------------+-----------------+

Instantiation Failed

+-------------------+-----------------+-----------------+
|  Template Address | Account Address |     Message     |
|   (20 bytes)      |  (20 bytes)     |  (UTF-8 String) |
+-------------------+-----------------+-----------------+

Function Not Found

+-------------------+-----------------+--------------+
|  Template Address | Account Address |   Function   |
|   (20 bytes)      |  (20 bytes)     |   (String)   |
+-------------------+-----------------+--------------+

Function Failed

+-------------------+------------------+------------+----------------+
|  Template Address |  Account Address |  Function  |    Message     |
|   (20 bytes)      |   (20 bytes)     |  (String)  | (UTF-8 String) |
+-------------------+------------------+------------+----------------+

Function Not Allowed

+-------------------+-------------------+------------+----------------+
|  Template Address |  Account Address  |  Function  |    Message     |
|   (20 bytes       |   (20 bytes)      |  (String)  | (UTF-8 String) |
+-------------------+-------------------+------------+----------------+

Function Invalid Signature

+-------------------+-------------------+------------+
|  Template Address |  Account Address  |  Function  |     
|   (20 bytes)      |   (20 bytes)      |  (String)  |
+-------------------+-------------------+------------+

Questions/concerns

Dependencies and interactions

As described above, since the communication between go-svm and SVM is by passing blobs - this spec should be implemented by go-svm.

Any non-Rust client that we'd like to integrate with SVM will have go through the FFI layer and implement this SMIP spec.

Stakeholders and reviewers

@YaronWittenstein @neysofu @sudachen @noamnelke @lrettig @avive

neysofu commented 2 years ago

This SMIP is partially outdated due to replacing our custom encoding with SSZ. Also, the new transaction syntax redefines deploy transactions as call's, effectively removing the need to have a custom encoding for them. Similarly, spawn receipts will most likely be replaced with self-spawn receipts due to transaction types unification. See also https://github.com/spacemeshos/pm/issues/108.