From 3a8e2c7f73668350521837d51568d77db3beb5a1 Mon Sep 17 00:00:00 2001 From: Hannes Karppila Date: Mon, 24 Jun 2024 15:05:13 +0300 Subject: [PATCH] Add Blob tx and related instructions --- src/fuel-vm/instruction-set.md | 57 ++++++++++++++++++++++++++++++++++ src/identifiers/blob-id.md | 10 ++++++ src/identifiers/index.md | 1 + src/tx-format/index.md | 3 ++ src/tx-format/transaction.md | 28 +++++++++++++++++ 5 files changed, 99 insertions(+) create mode 100644 src/identifiers/blob-id.md diff --git a/src/fuel-vm/instruction-set.md b/src/fuel-vm/instruction-set.md index b301bb4f..43988d04 100644 --- a/src/fuel-vm/instruction-set.md +++ b/src/fuel-vm/instruction-set.md @@ -106,6 +106,10 @@ - [`TIME`: Timestamp at height](#time-timestamp-at-height) - [`TR`: Transfer coins to contract](#tr-transfer-coins-to-contract) - [`TRO`: Transfer coins to output](#tro-transfer-coins-to-output) +- [Blob Instructions](#blob-instructions) + - [`BSIZ`: Blob size](#bsiz-blob-size) + - [`BLDC`: Load code from a blob](#blcd-load-code-from-a-blob) + - [`BLDD`: Load data from a blob](#blcd-load-data-from-a-blob) - [Cryptographic Instructions](#cryptographic-instructions) - [`ECK1`: Secp251k1 signature recovery](#eck1-secp256k1-signature-recovery) - [`ECR1`: Secp256r1 signature recovery](#ecr1-secp256r1-signature-recovery) @@ -2255,6 +2259,59 @@ In an external context, decrease `MEM[balanceOfStart(MEM[$rD, 32]), 8]` by `$rC` This modifies the `balanceRoot` field of the appropriate output(s). +## Blob Instructions + +All these instructions advance the program counter `$pc` by `4` after performing their operation. + +### `BSIZ`: Blob size + +| | | +|-------------|-----------------------------------------------------------------------------------------------------------| +| Description | Set `$rA` to the size of the blob with ID equal to the 32 bytes in memory starting at `$rB`. | +| Operation | ```$rA = blobsize(MEM[$rB, 32]);``` | +| Syntax | `bsiz $rA, $rB` | +| Encoding | `0x00 rA rB - -` | +| Notes | | + +Panic if: + +- `$rA` is a [reserved register](./index.md#semantics) +- `$rB + 32` overflows or `> VM_MAX_RAM` +- Blob ID `MEM[$rB, 32]` is not found + +### `BLDC`: Load code from a blob + +|-------------|-------------------------------------------------------------------------------------------------------------| +| Description | Load 32-byte blob id at `$rB`, and copy `$rD` bytes starting from `$rC` into `$sp`. Set `$ssp=$sp=$sp+$rC`. | +| Operation | `assert($rA == 0); MEM[$sp, $rD] = blob($rB)[$rC, $rD];` | +| Syntax | `bldc $rA, $rB, rC, $rD` | +| Encoding | `0x00 rA rB rC rD` | +| Notes | If `$rC >` blob size, zero bytes are filled in. `$rA` is reserved for future use, and must be zero. | + +Panic if: + +- `$ra != 0` +- `$sp + $rD` overflows or `> VM_MAX_RAM` or `> $hp` +- `$rB + 32` overflows or `> VM_MAX_RAM` + +Increment `$fp->codesize` and `$sp` by `$rD` padded to word alignment. Then set `$sp` to `$ssp`. + +This instruction can be used to extend current script or contract from a blob. + +### `BLDD`: Load data from a blob + +|-------------|-------------------------------------------------------------------------------------------------------------| +| Description | Load 32-byte blob id at `$rB`, and copy `$rD` bytes starting from `$rC` into `$sA`. | +| Operation | `0; MEM[$rA, $rD] = blob($rB)[$rC, $rD];` | +| Syntax | `bldd $rA, $rB, rC, $rD` | +| Encoding | `0x00 rA rB rC rD` | +| Notes | If `$rC >` blob size, zero bytes are filled in. | + +Panic if: + +- `$rA + $rD` overflows or `> VM_MAX_RAM` or `> $hp` +- `$rB + 32` overflows or `> VM_MAX_RAM` + ## Cryptographic Instructions All these instructions advance the program counter `$pc` by `4` after performing their operation. diff --git a/src/identifiers/blob-id.md b/src/identifiers/blob-id.md new file mode 100644 index 00000000..8c7e062e --- /dev/null +++ b/src/identifiers/blob-id.md @@ -0,0 +1,10 @@ +# Blob ID + +The _blob ID_ (also called _blob hash_) of a transaction is computed as +the [hash](../protocol/cryptographic-primitives.md#hashing) of the blob data. + +Blob ID calculation doesn't vary between chains. + +```python +sha256(blob_data) +``` diff --git a/src/identifiers/index.md b/src/identifiers/index.md index 0cff02bb..52bf2c84 100644 --- a/src/identifiers/index.md +++ b/src/identifiers/index.md @@ -3,6 +3,7 @@ This chapter defines how to compute unique identifiers. - [Asset ID](./asset.md) +- [Blob ID](./blob-id.md) - [Contract ID](./contract-id.md) - [Predicate ID](./predicate-id.md) - [Transaction ID](./transaction-id.md) diff --git a/src/tx-format/index.md b/src/tx-format/index.md index bfc91a1f..ade5b18e 100644 --- a/src/tx-format/index.md +++ b/src/tx-format/index.md @@ -7,6 +7,9 @@ The Fuel Transaction Format. - [`TransactionScript`](./transaction.md#transactionscript) - [`TransactionCreate`](./transaction.md#transactioncreate) - [`TransactionMint`](./transaction.md#transactionmint) + - [`TransactionUpgrade`](./transaction.md#transactionupgrade) + - [`TransactionUpload`](./transaction.md#transactionupload) + - [`TransactionBlob`](./transaction.md#transactionblob) - [Input](./input.md) - [`InputCoin`](./input.md#inputcoin) - [`InputContract`](./input.md#inputcontract) diff --git a/src/tx-format/transaction.md b/src/tx-format/transaction.md index 06bfc67a..28dc8fcf 100644 --- a/src/tx-format/transaction.md +++ b/src/tx-format/transaction.md @@ -7,6 +7,7 @@ enum TransactionType : uint8 { Mint = 2, Upgrade = 3, Upload = 4, + Blob = 5, } ``` @@ -232,3 +233,30 @@ Transaction is invalid if: - `subsectionIndex` >= `subsectionsNumber` - `subsectionsNumber > MAX_BYTECODE_SUBSECTIONS` - The [Binary Merkle tree](../protocol/cryptographic-primitives.md#binary-merkle-tree) root calculated from `(witnesses[witnessIndex], subsectionIndex, subsectionsNumber, proofSet)` is not equal to the `root`. Root calculation is affected by all fields, so modification of one of them invalidates the proof. + + +## `TransactionBlob` + +The `Blob` inserts a simple binary blob in the chain. It's raw immutable data that can be cheaply loaded by the VM and used as instructions or just data. Unlike `Create`, it doesn't hold any state or balances. + +`Blob`s are content-addressed, i.e. the they are uniquely identified by hash of the data field. Programs running on the VM can load an already-posted blob just by the hash, without having to specify it in contract inputs. + +| name | type | description | +|---------------------|-----------------------------|----------------------------------| +| `dataLength` | `uint64` | Size of the blob, in bytes. | +| `policyTypes` | `uint32` | Bitfield of used policy types. | +| `inputsCount` | `uint16` | Number of inputs. | +| `outputsCount` | `uint16` | Number of outputs. | +| `witnessesCount` | `uint16` | Number of witnesses. | +| `data` | `byte[]` | The data to post. | +| `policies` | [Policy](./policy.md)`[]` | List of policies. | +| `inputs` | [Input](./input.md)`[]` | List of inputs. | +| `outputs` | [Output](./output.md)`[]` | List of outputs. | +| `witnesses` | [Witness](./witness.md)`[]` | List of witnesses. | + +Transaction is invalid if: + +- Any input is of type `InputType.Contract` or `InputType.Message` where `input.dataLength > 0` +- Any input uses non-base asset. +- Any output is of type `OutputType.Contract` or `OutputType.Variable` or `OutputType.Message` or `OutputType.ContractCreated` +- Any output is of type `OutputType.Change` with non-base `asset_id`