Skip to content

Commit

Permalink
Zero all malleable fields before execution (#545)
Browse files Browse the repository at this point in the history
Closes #542.

Also changes `tx.receiptsRoot` to only be updated after the tx has
terminated, as the intermediate values are no longer useful. The speeds
up and simplifies implementation of receipt-pushing opcodes.
  • Loading branch information
Dentosal authored Feb 22, 2024
1 parent c7b6f7f commit 2742f30
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 36 deletions.
2 changes: 2 additions & 0 deletions src/fuel-vm/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ Following initialization, execution begins.

For each instruction, its gas cost `gc` is first computed. If `gc > $cgas`, deduct `$cgas` from `$ggas` and `$cgas` (i.e. spend all of `$cgas` and no more), then [revert](./instruction-set.md#rvrt-revert) immediately without actually executing the instruction. Otherwise, deduct `gc` from `$ggas` and `$cgas`.

After the script has been executed, `tx.receiptsRoot` is updated to contain the Merkle root of the receipts, [as described in the `TransactionScript` spec](../tx-format/transaction.md#`TransactionScript`).

## Call Frames

Cross-contract calls push a _call frame_ onto the stack, similar to a stack frame used in regular languages for function calls (which may be used by a high-level language that targets the FuelVM). The distinction is as follows:
Expand Down
39 changes: 16 additions & 23 deletions src/fuel-vm/instruction-set.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ Some instructions may _panic_, i.e. enter an unrecoverable state. Additionally,
- In a predicate context, cease VM execution and return `false`.
- In other contexts, revert (described below).

On a non-predicate panic, append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
On a non-predicate panic, append a receipt to the list of receipts:

| name | type | description |
|--------|---------------|---------------------------------------------------------------------------|
Expand All @@ -141,7 +141,7 @@ On a non-predicate panic, append a receipt to the list of receipts, modifying `t
| `pc` | `uint64` | Value of register `$pc`. |
| `is` | `uint64` | Value of register `$is`. |

then append an additional receipt to the list of receipts, again modifying `tx.receiptsRoot`:
then append an additional receipt to the list of receipts:

| name | type | description |
|------------|---------------|-----------------------------|
Expand Down Expand Up @@ -1249,7 +1249,7 @@ Panic if:
| Encoding | `0x00 rA - - -` |
| Notes | |

Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
Append a receipt to the list of receipts:

| name | type | description |
|--------|---------------|---------------------------------------------------------------------------|
Expand All @@ -1259,7 +1259,7 @@ Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
| `pc` | `uint64` | Value of register `$pc`. |
| `is` | `uint64` | Value of register `$is`. |

If current context is external, append an additional receipt to the list of receipts, modifying `tx.receiptsRoot`:
If current context is external, append an additional receipt to the list of receipts:

| name | type | description |
|------------|---------------|-----------------------------|
Expand Down Expand Up @@ -1667,7 +1667,7 @@ For output with contract ID `MEM[$fp, 32]`, decrease balance of asset ID `constr

This modifies the `balanceRoot` field of the appropriate output.

Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
Append a receipt to the list of receipts:

| name | type | description |
|---------------|---------------|--------------------------------------------|
Expand Down Expand Up @@ -1710,7 +1710,7 @@ Register `$rA` is a memory address from which the following fields are set (word

`$rB` is the amount of coins to forward. `$rC` points to the 32-byte asset ID of the coins to forward. `$rD` is the amount of gas to forward. If it is set to an amount greater than the available gas, all available gas is forwarded.

Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
Append a receipt to the list of receipts:

| name | type | description |
|------------|---------------|---------------------------------------------------------------------------|
Expand Down Expand Up @@ -1847,7 +1847,7 @@ This instruction can be used to concatenate the code of multiple contracts toget
| Encoding | `0x00 rA rB rC rD` |
| Notes | |

Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
Append a receipt to the list of receipts:

| name | type | description |
|--------|---------------|---------------------------------------------------------------------------|
Expand All @@ -1870,7 +1870,7 @@ Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
| Encoding | `0x00 rA rB rC rD` |
| Notes | |

Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
Append a receipt to the list of receipts:

| name | type | description |
|----------|---------------|---------------------------------------------------------------------------|
Expand Down Expand Up @@ -1913,7 +1913,7 @@ For output with contract ID `MEM[$fp, 32]`, increase balance of asset ID `constr

This modifies the `balanceRoot` field of the appropriate output.

Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
Append a receipt to the list of receipts:

| name | type | description |
|---------------|---------------|--------------------------------------------|
Expand All @@ -1939,7 +1939,7 @@ Panic if:
- `$rA + $rB` overflows
- `$rA + $rB > VM_MAX_RAM`

Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
Append a receipt to the list of receipts:

| name | type | description |
|----------|---------------|---------------------------------------------------------------------------|
Expand All @@ -1951,7 +1951,7 @@ Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
| `pc` | `uint64` | Value of register `$pc`. |
| `is` | `uint64` | Value of register `$is`. |

If current context is a script, append an additional receipt to the list of receipts, modifying `tx.receiptsRoot`:
If current context is a script, append an additional receipt to the list of receipts:

| name | type | description |
|------------|---------------|-----------------------------|
Expand Down Expand Up @@ -1986,7 +1986,7 @@ Then pop the call frame and restore all registers _except_ `$ggas`, `$cgas`, `$r
| Encoding | `0x00 rA - - -` |
| Notes | |

Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
Append a receipt to the list of receipts:

| name | type | description |
|--------|---------------|---------------------------------------------------------------------------|
Expand All @@ -1996,7 +1996,7 @@ Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
| `pc` | `uint64` | Value of register `$pc`. |
| `is` | `uint64` | Value of register `$is`. |

Then append an additional receipt to the list of receipts, modifying `tx.receiptsRoot`:
Then append an additional receipt to the list of receipts:

| name | type | description |
|------------|---------------|-----------------------------|
Expand Down Expand Up @@ -2032,7 +2032,7 @@ Panic if:
- In an external context, if `$rD > MEM[balanceOfStart(0), 8]`
- In an internal context, if `$rD` is greater than the balance of asset ID 0 of output with contract ID `MEM[$fp, 32]`

Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
Append a receipt to the list of receipts:

| name | type | description |
|-------------|---------------|---------------------------------------------------------------------------------|
Expand Down Expand Up @@ -2192,7 +2192,7 @@ Panic if:
- In an internal context, if `$rB` is greater than the balance of asset ID `MEM[$rC, 32]` of output with contract ID `MEM[$fp, 32]`
- `$rB == 0`

Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
Append a receipt to the list of receipts:

| name | type | description |
|------------|---------------|---------------------------------------------------------------------------|
Expand Down Expand Up @@ -2234,7 +2234,7 @@ Panic if:
- `tx.outputs[$rB].type != OutputType.Variable`
- `tx.outputs[$rB].amount != 0`

Append a receipt to the list of receipts, modifying `tx.receiptsRoot`:
Append a receipt to the list of receipts:

| name | type | description |
|------------|---------------|---------------------------------------------------------------------------|
Expand Down Expand Up @@ -2468,7 +2468,6 @@ Get [fields from the transaction](../tx-format/transaction.md).
| `GTF_SCRIPT_INPUTS_COUNT` | `0x005` | `tx.inputsCount` |
| `GTF_SCRIPT_OUTPUTS_COUNT` | `0x006` | `tx.outputsCount` |
| `GTF_SCRIPT_WITNESSES_COUNT` | `0x007` | `tx.witnessesCount` |
| `GTF_SCRIPT_RECEIPTS_ROOT` | `0x008` | Memory address of `tx.receiptsRoot` |
| `GTF_SCRIPT_SCRIPT` | `0x009` | Memory address of `tx.script` |
| `GTF_SCRIPT_SCRIPT_DATA` | `0x00A` | Memory address of `tx.scriptData` |
| `GTF_SCRIPT_INPUT_AT_INDEX` | `0x00B` | Memory address of `tx.inputs[$rB]` |
Expand All @@ -2491,18 +2490,12 @@ Get [fields from the transaction](../tx-format/transaction.md).
| `GTF_INPUT_COIN_OWNER` | `0x203` | Memory address of `tx.inputs[$rB].owner` |
| `GTF_INPUT_COIN_AMOUNT` | `0x204` | `tx.inputs[$rB].amount` |
| `GTF_INPUT_COIN_ASSET_ID` | `0x205` | Memory address of `tx.inputs[$rB].asset_id` |
| `GTF_INPUT_COIN_TX_POINTER` | `0x206` | Memory address of `tx.inputs[$rB].txPointer` |
| `GTF_INPUT_COIN_WITNESS_INDEX` | `0x207` | `tx.inputs[$rB].witnessIndex` |
| `GTF_INPUT_COIN_PREDICATE_LENGTH` | `0x209` | `tx.inputs[$rB].predicateLength` |
| `GTF_INPUT_COIN_PREDICATE_DATA_LENGTH` | `0x20A` | `tx.inputs[$rB].predicateDataLength` |
| `GTF_INPUT_COIN_PREDICATE` | `0x20B` | Memory address of `tx.inputs[$rB].predicate` |
| `GTF_INPUT_COIN_PREDICATE_DATA` | `0x20C` | Memory address of `tx.inputs[$rB].predicateData` |
| `GTF_INPUT_COIN_PREDICATE_GAS_USED` | `0x20D` | `tx.inputs[$rB].predicateGasUsed` |
| `GTF_INPUT_CONTRACT_TX_ID` | `0x220` | Memory address of `tx.inputs[$rB].txID` |
| `GTF_INPUT_CONTRACT_OUTPUT_INDEX` | `0x221` | `tx.inputs[$rB].outputIndex` |
| `GTF_INPUT_CONTRACT_BALANCE_ROOT` | `0x222` | Memory address of `tx.inputs[$rB].balanceRoot` |
| `GTF_INPUT_CONTRACT_STATE_ROOT` | `0x223` | Memory address of `tx.inputs[$rB].stateRoot` |
| `GTF_INPUT_CONTRACT_TX_POINTER` | `0x224` | Memory address of `tx.inputs[$rB].txPointer` |
| `GTF_INPUT_CONTRACT_CONTRACT_ID` | `0x225` | Memory address of `tx.inputs[$rB].contractID` |
| `GTF_INPUT_MESSAGE_SENDER` | `0x240` | Memory address of `tx.inputs[$rB].sender` |
| `GTF_INPUT_MESSAGE_RECIPIENT` | `0x241` | Memory address of `tx.inputs[$rB].recipient` |
Expand Down
10 changes: 3 additions & 7 deletions src/tx-format/input.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,9 @@ Transaction is invalid if:
- `predicateDataLength != len(predicateData)`
- `predicateGasUsed > MAX_GAS_PER_PREDICATE`

> **Note:** when signing a transaction, `txPointer` and `predicateGasUsed` is set to zero.
> **Note:** when signing a transaction, `txPointer` and `predicateGasUsed` are set to zero.
>
> **Note:** when verifying and estimating a predicate, `txPointer` and `predicateGasUsed` is initialized to zero.
>
> **Note:** when executing a script, `txPointer` is initialized to the TX whose output is being spent.
> **Note:** when verifying and estimating a predicate or executing a script, `txPointer` and `predicateGasUsed` are initialized to zero.
The predicate root is computed [here](../identifiers/predicate-id.md).

Expand All @@ -71,9 +69,7 @@ Transaction is invalid if:

> **Note:** when signing a transaction, `txID`, `outputIndex`, `balanceRoot`, `stateRoot`, and `txPointer` are set to zero.
>
> **Note:** when verifying a predicate, `txID`, `outputIndex`, `balanceRoot`, `stateRoot`, and `txPointer` are initialized to zero.
>
> **Note:** when executing a script, `txID`, `outputIndex`, `balanceRoot`, and `stateRoot` are initialized to the transaction ID, output index, amount, and state root of the contract with ID `contractID`, and `txPointer` is initialized to the TX whose output is being spent.
> **Note:** when verifying a predicate or executing a script, `txID`, `outputIndex`, `balanceRoot`, `stateRoot`, and `txPointer` are initialized to zero.
## `InputMessage`

Expand Down
4 changes: 1 addition & 3 deletions src/tx-format/output.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ Transaction is invalid if:

> **Note:** when signing a transaction, `balanceRoot` and `stateRoot` are set to zero.
>
> **Note:** when verifying a predicate, `balanceRoot` and `stateRoot` are initialized to zero.
>
> **Note:** when executing a script, `balanceRoot` and `stateRoot` are initialized to the balance root and state root of the contract with ID `tx.inputs[inputIndex].contractID`.
> **Note:** when verifying a predicate or executing a script, `balanceRoot` and `stateRoot` are initialized to zero.
The balance root `balanceRoot` is the root of the [SMT](../protocol/cryptographic-primitives.md#sparse-merkle-tree) of balance leaves. Each balance is a `uint64`, keyed by asset ID (a `byte[32]`).

Expand Down
4 changes: 1 addition & 3 deletions src/tx-format/transaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ Transaction is invalid if:

> **Note:** when signing a transaction, `receiptsRoot` is set to zero.
>
> **Note:** when verifying a predicate, `receiptsRoot` is initialized to zero.
>
> **Note:** when executing a script, `receiptsRoot` is initialized to zero.
> **Note:** when verifying a predicate or executing a script, `receiptsRoot` is initialized to zero.
The receipts root `receiptsRoot` is the root of the [binary Merkle tree](../protocol/cryptographic-primitives.md#binary-merkle-tree) of receipts. If there are no receipts, its value is set to the root of the empty tree, i.e. `0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`.

Expand Down

0 comments on commit 2742f30

Please sign in to comment.