You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: FIPS/fip-actor-upgrades.md
+20-8
Original file line number
Diff line number
Diff line change
@@ -20,14 +20,16 @@ Upgradable actors provide a framework for seamlessly replacing deployed actor co
20
20
21
21
## Change Motivation
22
22
23
-
Currently, all actors on the Filecoin Network are immutable once deployed. To modify the underlying actor code, such as fixing a security bug, the following steps are required:
23
+
Currently, the code associated with all actors on the Filecoin Network are immutable once deployed. To modify the actor code, such as fixing a security bug, the following steps are required:
24
24
1. Deploy a new actor with the corrected code.
25
25
2. Migrate all state from the previous actor to the new one.
26
26
3. Update all other actors interacting with the old actor to use the new actor.
27
27
28
28
By adding support for upgradable actors, deployed actors can easily upgrade their code and no longer need to go through the series of steps mentioned above.
29
29
30
-
This also simplifies the upgrade process for builtin actors. Currently, any changes made to the builtin actors require a network upgrade, a new Lotus version, and collaboration with the network to push the new version to production. This is a time consuming and manual process. However, with upgradable actors, we can instead deploy a new code to the builtin actors allowing the changes to be pushed to production almost instantly and does not require a new network upgrade or new Lotus version.
30
+
This FIP is also motivated by the `f4` extensible address class which was introduced in [FIP-0048] and required special "placeholder" actors to support interactions with addresses that do not yet exist on-chain. With upgradable actors we can simplify this address class and remove these placeholder actors completely and instead deploy real actors and upgrade their code on first send.
31
+
32
+
Furthermore, this FIP paves the way for moving more network upgrade logic on-chain in the future, enabling a more seamless process for implementing critical updates and ensuring the continuous improvement of the Filecoin Network.
31
33
32
34
## Specification
33
35
@@ -66,32 +68,42 @@ When a target actor's `upgrade` WASM entrypoint is called, it can make necessary
66
68
67
69
### New upgrade_actor syscall
68
70
69
-
We introduce a new `upgrade_actor` syscall which calls the `upgrade` wasm entrypoint of the calling actor and then atomically replaces the code CID of the calling actor with the provided code CID. It is defined as follows:
71
+
We introduce a new `upgrade_actor` syscall which calls the `upgrade` wasm entrypoint of the calling actor and then atomically replaces the code CID of the calling actor with the provided code CID, and returns the exit code and block ID of the return. It is defined as follows:
70
72
71
73
```rust
72
74
pubfnupgrade_actor(
73
75
new_code_cid_off:*constu8,
74
76
params:u32,
75
-
) ->Result<Send>;
77
+
) ->Result<CallResult>;
76
78
```
77
79
78
80
Parameters:
79
81
-`new_code_cid_off`: The code CID the calling actor should be replaced with.
80
82
-`params`: The IPLD block handle passed, or `0` for none.
81
83
84
+
The `CallResult` struct is defined as follows:
85
+
86
+
```rust
87
+
pubstructCallResult {
88
+
pubblock_id:BlockId,
89
+
pubblock_stat:BlockStat,
90
+
pubexit_code:ExitCode,
91
+
}
92
+
```
93
+
82
94
On successful upgrade, this syscall will not return. Instead, the current invocation will "complete" and the return value will be the block returned by the new code's `upgrade` endpoint. If the new code rejects the upgrade (calls `sdk::vm::exit()`) or performs an illegal operation, this syscall will return the exit code plus the error returned by the upgrade endpoint.
83
95
84
96
This syscall will:
85
97
1. Validate that the pointers passed to the syscall are in-bounds.
86
98
2. Validate that `new_code_cid_off` is a valid code CID.
87
99
3. Validate that the calling actor is not currently executing in "read-only" mode. If so, the syscall fails with a "ReadOnly" (13) syscall error.
88
-
4. Checks whether the calling actor is already on the call stack where it has previously been called on its `invoke` entrypoint (note that we allow calling `upgrade` recursively). If so, the syscall fails with a "Forbidden" (11) syscall error.
100
+
4. Checks whether the calling actor is already on the call stack where it has previously been called on its `invoke` entrypoint (note that we allow calling `upgrade` recursively). If so, the syscall fails with a "Forbidden" (11) syscall error. For example if an actor A has a call stack `A (upgrade -> upgrade -> upgrade)` then that is allowed, while call stack `A -> B -> A (upgrade)` would be rejected.
89
101
5. Checks that we have space for storing the return block. If not, the syscall fails with a "LimitExceeded" (3) syscall error.
90
102
6. Start a new Call Manager transaction:
91
103
1. Validate that the calling actor has not been deleted. If so, the syscall fails with a "IllegalOperation" (2) syscall error.
92
104
2. Update the actor in the state tree with the new `new_code_cid` keeping the same `state`, `sequence` and `balance`.
93
105
3. Invoke the target actor's `upgrade` entrypoint.
94
-
4. If the target actor does not implement the `upgrade` entrypoint, then return the syscall fails with a `ExitCode::SYS_INVALID_RECEIVER` exit code.
106
+
4. If the target actor does not implement the `upgrade` entrypoint, the syscall fails with a `ExitCode::SYS_INVALID_RECEIVER` exit code.
95
107
5. If the target actor aborts the `upgrade` entrypoint by calling `sdk::vm::exit()`, the syscall fails with the provided exit code.
96
108
7. Apply transaction, committing changes.
97
109
8. Abort the calling actor and return the IPLD block from the `upgrade` entrypoint.
@@ -100,7 +112,7 @@ This syscall will:
100
112
101
113
### Additional metadata syscall
102
114
103
-
We considered adding a new `get_old_code_cid` syscall to get the calling actors code CID. That has the benefit of keeping the `upgrade` entrypoint signature consistent with the `invoke` signature. We however rejected that as we felt the benefit didn't outweight the overhead of adding a new syscall. Furthermore, it did not provide the flexibility of passing in a IPLD handle for a `UpgradeInfo` struct where we can easily add more fields if required.
115
+
We considered adding a new `get_old_code_cid` syscall to get the calling actors code CID. That has the benefit of keeping the `upgrade` entrypoint signature consistent with the `invoke` signature. We however rejected that as we felt the benefit didn't outweigh the overhead of adding a new syscall. Furthermore, it did not provide the flexibility of passing in an IPLD handle for a `UpgradeInfo` struct where we can easily add more fields if required.
104
116
105
117
## Backwards Compatibility
106
118
@@ -126,7 +138,7 @@ This FIP does not materially impact incentives in any way.
126
138
127
139
## Product Considerations
128
140
129
-
This FIP makes it possible to upgrade deployed actors, for example in cases where a bug or security concern was identified in the deployed code, allowing a simple safe way to addres such issues which significantly improves the user experience from how it is today.
141
+
This FIP makes it possible to upgrade deployed actors, for example in cases where a bug or security concern was identified in the deployed code, allowing a simple safe way to address such issues which significantly improves the user experience from how it is today.
0 commit comments