Skip to content

Commit

Permalink
Support forwarding coins with CALL (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
adlerjohn authored Feb 12, 2021
1 parent 2f00c62 commit 8b91ed5
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 17 deletions.
3 changes: 1 addition & 2 deletions specs/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Of the 64 registers (6-bit register address space), the first `16` are reserved:
| `0x07` | `$hp` | heap pointer | Memory address below the current bottom of the heap (points to free memory). |
| `0x08` | `$err` | error | Error codes for particular operations. |
| `0x09` | `$gas` | gas | Remaining gas. |
| `0x0A` | `$bal` | balance | Currently available coins. |
| `0x0A` | `$bal` | balance | Received balance for this context. |
| `0x0B` | `$is` | instrs start | Pointer to the start of the currently-executing code. |
| `0x0C` | | | |
| `0x0D` | | | |
Expand Down Expand Up @@ -123,7 +123,6 @@ A call frame consists of the following, word-aligned:
| bytes | type | value | description |
| ----- | -------------------- | ----------------- | ----------------------------------------------------------------------------- |
| | | | **Unwritable area begins.** |
| 8 | `uint32` | out offset | Offset from start of this call frame to out count, in bytes. |
| 32 | `byte[32]` | to | Contract ID for this call. |
| 8*64 | `byte[8][64]` | regs | Saved registers from previous context. |
| 8 | `uint8` | in count | Number of input values. |
Expand Down
34 changes: 20 additions & 14 deletions specs/opcodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@
This page provides a description of all opcodes for the FuelVM. Encoding should be read as a sequence of one 8-bit value (the opcode identifier) followed by four 6-bit values (the register identifiers or immediate value). A single `i` indicates a 6-bit immediate value, `i i` indicates a 12-bit immediate value, `i i i` indicates an 18-bit immediate value, and `i i i i` indicates a 24-bit immediate value. All immediate values are interpreted as big-endian unsigned integers.

Some opcodes may _panic_, i.e. enter an unrecoverable state. How a panic is handled depends on [context](./main.md#contexts):
- In a predicate context, [return](#return-return-from-context) `false`.
- In other contexts, [revert](#revert-revert).
* In a predicate context, [return](#return-return-from-context) `false`.
* In other contexts, [revert](#revert-revert).

## Arithmetic/Logic (ALU) Opcodes

Expand Down Expand Up @@ -529,8 +529,9 @@ Panic if:

If current context is external, cease VM execution and return `$rs`.

If current context is internal, return from contract call, popping the call frame. Before popping, return the unused forwarded gas to the caller:
1. `$gas = $gas + $fp->$gas` (add remaining gas from previous context to current remaining gas)
Returns from contract call, popping the call frame. Before popping:
1. Return the unused forwarded gas to the caller:
* `$gas = $gas + $fp->$gas` (add remaining gas from previous context to current remaining gas)

Then pop the call frame and restoring registers _except_ the `$gas`. Afterwards, set the following registers:
1. `$pc = $pc + 4` (advance program counter from where we called)
Expand Down Expand Up @@ -707,18 +708,20 @@ Block header hashes for blocks with height greater than or equal to current bloc

### CALL: Call contract

| | |
| ----------- | ---------------- |
| Description | Call contract. |
| Operation | |
| Syntax | `call $rs $rt` |
| Encoding | `0x00 rs rt - -` |
| Notes | |
| | |
| ----------- | ------------------ |
| Description | Call contract. |
| Operation | |
| Syntax | `call $rs $rt $ru` |
| Encoding | `0x00 rs rt ru -` |
| Notes | |

Panic if:
* Contract with ID `MEM[$rs, 32]` is not in `tx.inputs`
* Reading past `MEM[VM_MAX_RAM - 1]`
* Any output range does not pass [ownership check](./main.md#ownership)
* In an external context, if `$rt > $bal`
* In an internal context, if `$rt` is greater than `amount` of output with contract ID `MEM[$rs, 32]`

Register `$rs` is a memory address from which the following fields are set (word-aligned):

Expand All @@ -730,13 +733,16 @@ Register `$rs` is a memory address from which the following fields are set (word
| 16* | `(uint32, uint32)[]` | out (addr, size)s | Array of memory addresses and lengths in bytes of return values. |
| 16* | `(uint32, uint32)[]` | in (addr, size)s | Array of memory addresses and lengths in bytes of input values. |

`$rt` is the amount of gas to forward. If it is set to an amount greater than the available gas, all available gas is forwarded.
`$ru` is the amount of gas to forward. If it is set to an amount greater than the available gas, all available gas is forwarded.

For output with contract ID `MEM[$rs, 32]`, increase `amount` by `$rt`. In an external context, decrease `$bal` by `$rt`.

A [call frame](./main.md#call-frames) is pushed at `$sp`. In addition to filling in the values of the call frame, the following registers are set:
1. `$fp = $sp` (on top of the previous call frame is the beginning of this call frame)
1. Set `$ssp` and `$sp` to the start of the writable stack area of the call frame.
1. Set `$pc` and `$is` to the starting address of the code.
1. `$gas` = forwarded gas.
1. `$bal = $rt` (forward coins)
1. `$gas = $ru` (forward gas)

### CODECOPY: Code copy

Expand Down Expand Up @@ -843,7 +849,7 @@ Panic if:
| Notes | |

After a revert:
1. All [OutputContract](./tx_format.md#outputcontract) outputs will have the same `amount` and `stateRoot` as their respective inputs.
1. All [OutputContract](./tx_format.md#outputcontract) outputs will have the same `amount` and `stateRoot` as on initialization.
1. All [OutputVariable](./tx_format.md outputs#outputvariable) outputs will have `to` and `amount` of zero.
1. All [OutputContractConditional](./tx_format.md#outputcontractconditional) outputs will have `contractID`, `amount`, and `stateRoot` of zero.

Expand Down
2 changes: 1 addition & 1 deletion specs/tx_format.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ enum OutputType : uint8 {

Note: when signing a transaction, `amount` and `stateRoot` are set to zero.

Note: when executing a transaction, `amount` and `stateRoot` are initialized to zero.
Note: when executing a transaction, `amount` and `stateRoot` are initialized to the balance and state root of the contract with ID `tx.inputs[inputIndex].contractID`.

### OutputChange

Expand Down

0 comments on commit 8b91ed5

Please sign in to comment.