Skip to content

Commit

Permalink
Merge branch 'master' into SilentCicero-bls12-381
Browse files Browse the repository at this point in the history
  • Loading branch information
Dentosal authored Dec 6, 2023
2 parents e0ab1f3 + 0904457 commit b431b88
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/fuel-vm/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ If script bytecode is present, transaction validation requires execution.
The VM is [initialized](#vm-initialization), then:

1. `$pc` and `$is` are set to the start of the transaction's script bytecode.
1. `$ggas` and `$cgas` are set to `tx.gasLimit`.
1. `$ggas` and `$cgas` are set to `tx.scriptGasLimit`.

Following initialization, execution begins.

Expand Down
33 changes: 20 additions & 13 deletions src/fuel-vm/instruction-set.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ This page provides a description of all instructions for the FuelVM. Encoding is
- The syntax `MEM[x, y]` used in this page means the memory range starting at byte `x`, of length `y` bytes.
- The syntax `STATE[x, y]` used in this page means the sequence of storage slots starting at key `x` and spanning `y` bytes.

### Panics

Some instructions may _panic_, i.e. enter an unrecoverable state. Additionally, attempting to execute an instruction not in this list causes a panic and consumes no gas. How a panic is handled depends on [context](./index.md#contexts):

- In a predicate context, cease VM execution and return `false`.
Expand All @@ -148,6 +150,12 @@ then append an additional receipt to the list of receipts, again modifying `tx.r
| `result` | `uint64` | `1` |
| `gas_used` | `uint64` | Gas consumed by the script. |

### Receipts

The number of receipts is limited to 2<sup>16</sup>, with the last two reserved to panic and script result receipts. Trying to add any other receipts after 2<sup>16</sup>-2 will panic.

### Effects

A few instructions are annotated with the _effects_ they produce, the table below explains each effect:

| effect name | description |
Expand Down Expand Up @@ -2065,7 +2073,7 @@ Panic if:
- `$rC + 32 > VM_MAX_RAM`
- `$fp == 0` (in the script context)

Register `$rB` will be set to `false` if any storage slot in the requested range is unset (default) and `true` if all the slots were set.
Register `$rB` will be set to `false` if the requested slot is unset (default) and `true` if it's set.

### SRWQ: State read sequential 32 byte slots

Expand All @@ -2088,7 +2096,7 @@ Panic if:
- The memory range `MEM[$rA, 32 * rD]` does not pass [ownership check](./index.md#ownership)
- `$fp == 0` (in the script context)

Register `$rB` will be set to `false` if any storage slot in the requested range is unset (default) and `true` if all the slots were set.
Register `$rB` will be set to `false` if any storage slot in the requested range is unset (default) and `true` if all the slots are set.

### SWW: State write word

Expand All @@ -2099,7 +2107,7 @@ Register `$rB` will be set to `false` if any storage slot in the requested range
| Syntax | `sww $rA $rB $rC` |
| Encoding | `0x00 rA rB rC -` |
| Effects | Storage write |
| Notes | |
| Notes | Additional gas is charged when a new storage slot is created. |

Panic if:

Expand All @@ -2108,7 +2116,7 @@ Panic if:
- `$rB` is a [reserved register](./index.md#semantics)
- `$fp == 0` (in the script context)

The last 24 bytes of `STATE[MEM[$rA, 32]]` are set to `0`. Register `$rB` will be set to `false` if the storage slot was previously unset (default) and `true` if the slot was set.
The last 24 bytes of `STATE[MEM[$rA, 32]]` are set to `0`. Register `$rB` will be set to the number of new slots written, i.e. `1` if the slot was previously unset, and `0` if it alreaady contained a value.

### SWWQ: State write sequential 32 byte slots

Expand All @@ -2119,7 +2127,7 @@ The last 24 bytes of `STATE[MEM[$rA, 32]]` are set to `0`. Register `$rB` will b
| Syntax | `swwq $rA, $rB, $rC, $rD` |
| Encoding | `0x00 rA rB rC rD` |
| Effects | Storage write |
| Notes | |
| Notes | Additional gas is charged when for each new storage slot created. |

Panic if:

Expand All @@ -2130,7 +2138,7 @@ Panic if:
- `$rC + 32 * $rD > VM_MAX_RAM`
- `$fp == 0` (in the script context)

Register `$rB` will be set to `false` if the first storage slot was previously unset (default) and `true` if the slot was set.
Register `$rB` will be set to the number of storage slots that were previously unset, and were set by this operation.

### TIME: Timestamp at height

Expand Down Expand Up @@ -2469,7 +2477,7 @@ Get [fields from the transaction](../tx-format/transaction.md).
| name | `imm` | set `$rA` to |
|-------------------------------------------|---------|-------------------------------------------------------------------|
| `GTF_TYPE` | `0x001` | `tx.type` |
| `GTF_SCRIPT_GAS_LIMIT` | `0x002` | `tx.gasLimit` |
| `GTF_SCRIPT_GAS_LIMIT` | `0x002` | `tx.scriptGasLimit` |
| `GTF_SCRIPT_SCRIPT_LENGTH` | `0x003` | `tx.scriptLength` |
| `GTF_SCRIPT_SCRIPT_DATA_LENGTH` | `0x004` | `tx.scriptDataLength` |
| `GTF_SCRIPT_INPUTS_COUNT` | `0x005` | `tx.inputsCount` |
Expand Down Expand Up @@ -2535,12 +2543,11 @@ Get [fields from the transaction](../tx-format/transaction.md).
| `GTF_OUTPUT_CONTRACT_CREATED_STATE_ROOT` | `0x308` | Memory address of `tx.outputs[$rB].stateRoot` |
| `GTF_WITNESS_DATA_LENGTH` | `0x400` | `tx.witnesses[$rB].dataLength` |
| `GTF_WITNESS_DATA` | `0x401` | Memory address of `tx.witnesses[$rB].data` |
| `GTF_POLICY_COUNT` | `0x500` | `count_ones(tx.policyTypes)` |
| `GTF_POLICY_TYPE` | `0x501` | `tx.policies[$rB].type` |
| `GTF_POLICY_GAS_PRICE` | `0x502` | `tx.policies[0x00].gasPrice` |
| `GTF_POLICY_WITNESS_LIMIT` | `0x504` | `tx.policies[count_ones(0b11 & tx.policyTypes) - 1].witnessLimit` |
| `GTF_POLICY_MATURITY` | `0x505` | `tx.policies[count_ones(0b111 & tx.policyTypes) - 1].maturity` |
| `GTF_POLICY_MAX_FEE` | `0x506` | `tx.policies[count_ones(0b1111 & tx.policyTypes) - 1].maxFee` |
| `GTF_POLICY_TYPES` | `0x500` | `tx.policies.policyTypes` |
| `GTF_POLICY_GAS_PRICE` | `0x501` | `tx.policies[0x00].gasPrice` |
| `GTF_POLICY_WITNESS_LIMIT` | `0x502` | `tx.policies[count_ones(0b11 & tx.policyTypes) - 1].witnessLimit` |
| `GTF_POLICY_MATURITY` | `0x503` | `tx.policies[count_ones(0b111 & tx.policyTypes) - 1].maturity` |
| `GTF_POLICY_MAX_FEE` | `0x504` | `tx.policies[count_ones(0b1111 & tx.policyTypes) - 1].maxFee` |

Panic if:

Expand Down
2 changes: 1 addition & 1 deletion src/identifiers/utxo-id.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The ID of a message is computed as the [hash](../protocol/cryptographic-primitiv

### Message Nonce

The nonce value for `InputMessage` is determined by the sending system and is published at the time the message is sent. The nonce value for `OutputMessage` is computed as the [hash](../protocol/cryptographic-primitives.md#hashing) of the [Transaction ID](./transaction-id.md) that emitted the message and the index of the message receipt `uint8`: `hash(byte[32] ++ uint8)`.
The nonce value for `InputMessage` is determined by the sending system and is published at the time the message is sent. The nonce value for `OutputMessage` is computed as the [hash](../protocol/cryptographic-primitives.md#hashing) of the [Transaction ID](./transaction-id.md) that emitted the message and the index of the message receipt `uint16` (with canonical encoding): `hash(byte[32] ++ canonical(uint16))`.

## Fee ID

Expand Down
4 changes: 2 additions & 2 deletions src/protocol/tx-validity.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def unavailable_balance(tx, asset_id) -> int:
return sentBalance

def fee_balance(tx, asset_id) -> int:
gas = tx.gasLimit + sum_predicate_gas_used(tx)
gas = tx.scriptGasLimit + sum_predicate_gas_used(tx)
gasBalance = gasPrice * gas / GAS_PRICE_FACTOR
bytesBalance = size(tx) * GAS_PER_BYTE * gasPrice / GAS_PRICE_FACTOR
# Total fee balance
Expand Down Expand Up @@ -205,7 +205,7 @@ Once the free balances are computed, the [script is executed](../fuel-vm/index.m
1. The unspent free balance `unspentBalance` for each asset ID.
1. The unspent gas `unspentGas` from the `$ggas` register.

The fees incurred for a transaction are `ceiling(((size(tx) * GAS_PER_BYTE) + (tx.gasLimit - unspentGas) + sum(tx.inputs[i].predicateGasUsed)) * tx.gasPrice / GAS_PRICE_FACTOR)`.
The fees incurred for a transaction are `ceiling(((size(tx) * GAS_PER_BYTE) + (tx.scriptGasLimit - unspentGas) + sum(tx.inputs[i].predicateGasUsed)) * tx.gasPrice / GAS_PRICE_FACTOR)`.

`size(tx)` includes the entire transaction serialized according to the transaction format, including witness data.
This ensures every byte of block space either on Fuel or corresponding DA layer can be accounted for.
Expand Down
39 changes: 21 additions & 18 deletions src/tx-format/transaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,24 @@ enum ReceiptType : uint8 {
}
```

| name | type | description |
|--------------------|-----------------------------|------------------------------------------------------|
| `gasLimit` | `uint64` | Gas limit for transaction (including predicate gas). |
| `scriptLength` | `uint16` | Script length, in instructions. |
| `scriptDataLength` | `uint16` | Length of script input data, in bytes. |
| `policyTypes` | `uint32` | Bitfield of used policy types. |
| `inputsCount` | `uint8` | Number of inputs. |
| `outputsCount` | `uint8` | Number of outputs. |
| `witnessesCount` | `uint8` | Number of witnesses. |
| `receiptsRoot` | `byte[32]` | Merkle root of receipts. |
| `script` | `byte[]` | Script to execute. |
| `scriptData` | `byte[]` | Script input data (parameters). |
| `policies` | [Policy](./policy.md)`[]` | List of policies, sorted by PolicyType. |
| `inputs` | [Input](./input.md)`[]` | List of inputs. |
| `outputs` | [Output](./output.md)`[]` | List of outputs. |
| `witnesses` | [Witness](./witness.md)`[]` | List of witnesses. |

| name | type | description |
|--------------------|-----------------------------|-----------------------------------------|
| `scriptGasLimit` | `uint64` | Gas limits the script execution. |
| `scriptLength` | `uint16` | Script length, in instructions. |
| `scriptDataLength` | `uint16` | Length of script input data, in bytes. |
| `policyTypes` | `uint32` | Bitfield of used policy types. |
| `inputsCount` | `uint8` | Number of inputs. |
| `outputsCount` | `uint8` | Number of outputs. |
| `witnessesCount` | `uint8` | Number of witnesses. |
| `receiptsRoot` | `byte[32]` | Merkle root of receipts. |
| `script` | `byte[]` | Script to execute. |
| `scriptData` | `byte[]` | Script input data (parameters). |
| `policies` | [Policy](./policy.md)`[]` | List of policies, sorted by PolicyType. |
| `inputs` | [Input](./input.md)`[]` | List of inputs. |
| `outputs` | [Output](./output.md)`[]` | List of outputs. |
| `witnesses` | [Witness](./witness.md)`[]` | List of witnesses. |

Given helper `max_gas()` returns the maximum gas that the transaction can use.
Given helper `len()` that returns the number of bytes of a field.
Given helper `count_ones()` that returns the number of ones in the binary representation of a field.
Given helper `count_variants()` that returns the number of variants in an enum.
Expand All @@ -84,7 +85,7 @@ Transaction is invalid if:
- `scriptDataLength > MAX_SCRIPT_DATA_LENGTH`
- `scriptLength * 4 != len(script)`
- `scriptDataLength != len(scriptData)`
- `gasLimit > MAX_GAS_PER_TX`
- `max_gas(tx) > MAX_GAS_PER_TX`
- No policy of type `PolicyType.GasPrice`
- `count_ones(policyTypes) > count_variants(PolicyType)`
- `policyTypes > sum_variants(PolicyType)`
Expand Down Expand Up @@ -116,6 +117,7 @@ The receipts root `receiptsRoot` is the root of the [binary Merkle tree](../prot
| `outputs` | [Output](./output.md)`[]` | List of outputs. |
| `witnesses` | [Witness](./witness.md)`[]` | List of witnesses. |

Given helper `max_gas()` returns the maximum gas that the transaction can use.
Given helper `count_ones()` that returns the number of ones in the binary representation of a field.
Given helper `count_variants()` that returns the number of variants in an enum.
Given helper `sum_variants()` that sums all variants of an enum.
Expand All @@ -133,6 +135,7 @@ Transaction is invalid if:
- The keys of `storageSlots` are not in ascending lexicographic order
- The computed contract ID (see below) is not equal to the `contractID` of the one `OutputType.ContractCreated` output
- `storageSlotsCount > MAX_STORAGE_SLOTS`
- `max_gas(tx) > MAX_GAS_PER_TX`
- The [Sparse Merkle tree](../protocol/cryptographic-primitives.md#sparse-merkle-tree) root of `storageSlots` is not equal to the `stateRoot` of the one `OutputType.ContractCreated` output
- No policy of type `PolicyType.GasPrice`
- `count_ones(policyTypes) > count_variants(PolicyType)`
Expand Down

0 comments on commit b431b88

Please sign in to comment.