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
Having a minimal, experimental protoype of an actor deployment flow will unlock several downstream community projects. What's described here is most certainly not the definitive flow, but it's doubly useful:
It's a sufficiently functional PoC to allow FVM devs to spin up devnets, and node operators to provide testnets, where actors can be deployed.
Can be regarded like a spike to explore the problem and dissipate unknowns.
This implementation should sit in a branch, ideally behind a Cargo feature flag, and should carry prominent EXPERIMENTAL warnings.
Add an actor_registry: Hamt<Cid, ActorSpec> field to the state object, where:
structActorSpec{// The actor that installed this actor.creator:ActorID,// The originator of the message that triggered creator to install this actor.// Probably needs https://github.com/filecoin-project/ref-fvm/issues/300originator:ActorID,// The version of the invocation container.container_version:u32,}
Operations
Add an InstallActor(bytecode: RawBytes) -> Result<InstallActorReturn, ActorError> method, where:
structInstallActorReturn{// The CodeCID with which this actor can be constructed.code_cid:Cid,// Whether the bytecode was effectively installed in this call or not.// False when the CodeCID already existed.// Alternatively we could fail, but that would break API idempotency.installed:bool,}
This method:
Computes the Cid of the parameter block (Wasm bytecode).
Checks if an entry already exists inactor_registry. If yes, it shortcircuits and returns the CodeCID and installed=false.
Adds the bytecode to the blockstore.
Calls the actor::install_actor(block_id) -> Result<Cid> syscall to apply the installation. Aborts on failure.
Adds an entry in actor_registry, filling in the active container version, creator, and originator.
Returns the CodeCID and installed=true
ref-fvm enhancements
actor::install_actor syscall
Persists the Wasm bytecode to the blockstore, and remembers the resulting Cid as the code_cid.
Calls kernel.call_manager().machine().engine().preload(blockstore, code_cid) => this compiles the bytecode and caches the instantiated module in memory (cache will be entirely revisited for M2).
In the future, this will perform bytecode validation, structural analysis to derive complexity factors, patching to replace floating point operations, and more.
Note: this approach leaks cached modules in case of reorgs.
Caveats
There are message payload limits in various components and protocols that hinder the inlining of Wasm bytecode in chain messages. Gossipsub: 1MiB, Bitswap: 2MiB (suspected), Mempool: 64KiB. The effective limit is the lowest one (64KiB), which most certainly will always be insufficient. We need to figure out a path forward (e.g. offloading and chunking), but for this PoC it would be acceptable to increase these limits.
Did I say this is EXPERIMENTAL and will change in many ways? If you depend on this flow, your code will be broken in the future.
Context
Having a minimal, experimental protoype of an actor deployment flow will unlock several downstream community projects. What's described here is most certainly not the definitive flow, but it's doubly useful:
This implementation should sit in a branch, ideally behind a Cargo feature flag, and should carry prominent EXPERIMENTAL warnings.
InitActor enhancements
See https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0030.md#actor-deployment for reference.
State object
Add an
actor_registry: Hamt<Cid, ActorSpec>field to the state object, where:Operations
Add an
InstallActor(bytecode: RawBytes) -> Result<InstallActorReturn, ActorError>method, where:This method:
actor_registry. If yes, it shortcircuits and returns the CodeCID andinstalled=false.actor::install_actor(block_id) -> Result<Cid>syscall to apply the installation. Aborts on failure.actor_registry, filling in the active container version, creator, and originator.installed=trueref-fvm enhancements
actor::install_actorsyscallcode_cid.kernel.call_manager().machine().engine().preload(blockstore, code_cid)=> this compiles the bytecode and caches the instantiated module in memory (cache will be entirely revisited for M2).In the future, this will perform bytecode validation, structural analysis to derive complexity factors, patching to replace floating point operations, and more.
Note: this approach leaks cached modules in case of reorgs.
Caveats