New API for built-in actors accessible to user-programmed actors #401
Replies: 15 comments 32 replies
-
I strongly agree that the API for built-in actors should follow whichever calling convention we eventually decide for user programmed actors. Nonetheless, I do not advocate for an EVM based calling convention. FVM is WASM-based virtual machine, it simply makes more sense to adopt other WASM-based virtual machine calling conventions such as Ink from Polkadot, Cosmwasm from Cosmos, etc. And if we do choose these WASM-based conventions, we will also realized the overhead costs in terms of development and maintenance can be significantly lowered compared to what we have right now. Let me use Cosmwasm internal internal message dispatch (yes, two internals as we are doing an internal dispatch within an internal dispatch) to illustrate this:
First of all, this is a snippet of the Cosmwasm calling convention that has been implemented on FVM. The ugly method numbers will only be used to define on what kind of methods we are calling (1 for constructor methods, 2 for state modifying methods, 3 for state querying methods, etc). This means that it will be pre-defined since the start, and developers writing actors should never need or be required to modify it. We can also replace this numbers with readable macros. And to resolve the method internally, here's how: whereby We then used the Rust's Enum Matching pattern to perform the resolution of the json object to whatever method it was suppose to call, and it is a widely used pattern in Rust to make code readable and beginner friendly. And the advantage of this is pretty obvious, its super easy to extend. If we have a new API, we just need to declare an additional enum with the expected input params. If we need to rename or change existing parameters of an existing API, we just modify the corresponding enum. And for user created actors that depend on them, the json used to interact with the current actor just needs to be upgraded. And guess what, we can also generate an ABI-equivalent template by piggybacking cosmwasm tools from the enums. And that effect spillovers to other tools including frontend wallet SDKs and more. Therefore I believe by adopting a widely used WASM-based calling convention from existing WASM-based virtual machines, it will help the Filecoin ecosystem to save a lot of unnecessary work. We should work smart, not work hard. |
Beta Was this translation helpful? Give feedback.
-
First impressions: @anorth Thanks a lot for getting this started! I think the need for this is well-motivated.
Strong support for this idea. |
Beta Was this translation helpful? Give feedback.
-
Thanks for getting this started, @anorth. FeedbackI concur with the suggested approach of restricting currently exposed APIs so they can only be consumed by other built-in actors (we might need to add a syscall to efficiently evaluate this condition, as it'll gate every call; likely something we can evaluate in the invoke entrypoint). As you say, these APIs were not implemented with the view that they'll be etched in stone forever (as a consequence of user-deployed actors relying on them). We also will not violate the basic blockchain guarantee of not breaking already-deployed actors with a future protocol upgrade that may change these APIs. I'm also onboard with deliberately re-exporting functionality under a new future-proof API. One technicality that I want to point out to confirm that our thinking is aligned:
I would rephrase this as: "I think it's better to conciously re-export the functionality under a new set of methods that use a more flexible and future-proof schema". [I don't expect the call convention to change besides what will come out #382 and #409 re: dispatch; that is, builtin actors will use CBOR for params and return values, errors are communicated through aborts, etc.] ActionI'm keen to get started with this initiative ASAP -- I think FEVM cannot ship without a public builtin-actors API that enables devs to build the use cases they are intending to. Since we expect to open up the API progressively over time, we should ensure that the first iteration follows Pareto (let's expose the 20% that will enable 80% of use cases) to avoid user disappointment. Aadi (Product Manager from our team) is conducting research to catalogue the use cases being pursued by the community. This research should heavily influence the decisions of which APIs we open up, with understanding of the consequences. However, here comes the bad news: the FVM team is not equipped to tackle this for nv18. We are not planning to make functional changes to built-in actors, this would significantly expand our scope and dillute our focus -- which is on the runtime itself. Would Protocol Dev be keen to drive this for nv18? |
Beta Was this translation helpful? Give feedback.
-
Some work on this has begun
@arajasek and I will roll through this list to produce some APIs that can be exercised in upcoming dev/testnets, and then write up a quick FIP as it settles. |
Beta Was this translation helpful? Give feedback.
-
Is it possible to define non-stable APIs and warn users of restricted usage rules, and when APIs will be changed, users upgrade actors to achieve new compatibility? |
Beta Was this translation helpful? Give feedback.
-
One open question is whether to export the methods on the current payment channel actor. The big picture line is that, once user-programmed native actors are possible, we expect people to write new and better payment channel actors, and there's no reason for the built-in one to have any special status. So by refusing to export its API, we encourage that development. However, given that the actor does exist and work, a reasonable argument could be made that it's more helpful just to open it up. We don't expect to do any further development on it, so API lock-in is a low-level concern. FYI @arajasek @ZenGround0 Note that we have exported methods on the multisig actor, for which similar arguments could be made both ways. |
Beta Was this translation helpful? Give feedback.
-
My initial pass did not export any methods from the power or reward actor. However, I can see it would be useful for the sector initial pledge calculation to be possible in user-programmed actors. To enable this, we'd need to export either:
|
Beta Was this translation helpful? Give feedback.
-
Progress update@arajasek and I have done a first quick pass at restricting the current internal API, exporting a set of existing methods, and adding some basic new methods to the market and miner actors. The main goal in this initial pass was to establish a pattern and get a conservative safe set of methods out quickly for testing and downstream SDK development. We don't think this is the complete API for FVM 2.1 milestone, and we'll work on that next. One particular focus will be miner actor orchestration methods, so that another actor could meaningfully function as a miner owner or controller. Please let us know other major needs either here or in the #fil-actors slack channel. This API is being developed on the integration/builtin-api branch of the built-in actors repo. We'll draft a FIP for the API as it gets closer to finished.
|
Beta Was this translation helpful? Give feedback.
-
I've written up a longer motivation for why to avoid exposing many parts of miner and sector state: #539 |
Beta Was this translation helpful? Give feedback.
-
What about exposing QA power (e.g this request)? The reasons to expose it are that it is (today) a core feature of the network and a miner, and corresponds to consensus power, share of reward, and (more roughly) stake. I think it's clear there is at least some utility, though raw byte power would suffice for many other things. The reason not to expose it is that it would lock in the concept and approximate mechanism of QA power (callers would not expect the meaning to change a lot over time). While I don't see QA power changing in the short term, there have been multiple proposals for various ways of decoupling stake and reward distribution from raw storage commitments. These proposals would generally do away with QA power as it's the coupling mechanism.
There have also been multiple changes to how QA power is calculated, rather than how it is used. It's unclear whether change like this might be impeded by wide adoption of QA power for other uses by actors. |
Beta Was this translation helpful? Give feedback.
-
User-defined actors read SP's initial pledge total, which I think needs to be opened early. |
Beta Was this translation helpful? Give feedback.
-
Why not provide a simpler GetLockedFunds? |
Beta Was this translation helpful? Give feedback.
-
I am recommending removal of Since FIP 0050 was merged to There is definitely room for innovation on top of PSD from the storage provider pool side but I don't think its worth the cost of constantly fighting the misconception that a developer can use PSD to make a storage deal for the next few months. If we don't remove this method we should at least rename it to something that indicates it is a storage provider infrastructure method. |
Beta Was this translation helpful? Give feedback.
-
I'm having concerns about the utility of exporting the Init actor's Exec method. While this does have some use-cases today (eg. having a contract create a multisig actor), it's likely not very useful in its current form. The fact that it takes a code_cid as an input means it's gonna be pretty hard to ever write an unchanging contract that uses this method reliably. Further, this method receives a serialization of the relevant constructor's params as input. Exporting this method risks locking the current shape of the constructor params for our built-in actors. Lastly, the only actors that can actually be created by contracts using this method are multisigs and payment channels, both of which we're interested in dropping long-term support for. @Stebalien also has concerns about potential unforeseen consequences of exporting this method, and would rather delay its exporting until a pressing use-case is identified. |
Beta Was this translation helpful? Give feedback.
-
Since we support fevm actor to call native actor with opcode From a longer-term perspective, Is it possible extend built-in actors to provide New APIs that receives and returns data in ABI-encoded format? In this way, fevm actors can directly call built-in actors conveniently. |
Beta Was this translation helpful? Give feedback.
-
This is a proposal for the built-in actors to present a thoughtful API to user actors on the FVM, while retaining abstraction and flexibility for future protocol upgrades.
Motivation
User-programmed actors on the FVM will want to interact with the built-in actors, especially those related to storage. The built-in actors were not designed with calls from user actors in mind, so do not present a good interface to them.
In the past, we have been able to alter the APIs presented by the built-in actors because callers were either other built in actors (which we could atomically upgrade) or off-chain parties (who can change their code). User-programmed actors will be a new class of caller which will generally be unable or unwilling to upgrade to new APIs. This means that if we ever change a built-in actor method that a user actor depends on, we would break that actor. Network stakeholders will likely be extremely reluctant to break existing actors, with the implication that built-in actor methods reachable by user-programmed actors are effectively permanent.
Indefinite compatibility requirements on a legacy or poorly-conceived interface could present a very significant restriction on future improvements to Filecoin’s protocol and capabilities.
Goals
Proposal
New public API
I propose that we thoughtfully design a new API for built-in actors to expose to user actors, independent of the existing API that is used for internal messaging. This API would conform to a recommended calling convention (discussion in #382) to present the same calling pattern as user-programmed actors are expected to expose and use between themselves.
I would expect this new API to present much more of the built-in actors internal state than is currently accessible. The current built-in API is limited only to methods actually necessary for use by other built-in actors. Off-chain tools use direct state inspection. A new API should have relatively wide coverage over the data that another actor might reasonably need access to, and potentially replace much state inspection with invocation of getter-type methods.
At the same time, this new API should abstract over the concrete representation of internal state as much as possible. There are opportunities to improve the internal state representation for many built-in actors. Hiding the concrete details while exposing useful information can bring us utility and flexibility.
Restricted internal API
I propose we restrict the currently implemented API of all built-in actors by rejecting calls from any caller which is not a built-in actor, except for a selection of those methods intended to be invoked by external entities.
This API is primarily designed for messaging between mutually-trusting built-in actors. It may expose information or capabilities that are not intended for general consumption. If we allow user-actors to call these methods, we will be locked into their signatures and behaviour indefinitely. This lock-in would severely restrict our ability to improve Filecoin’s core protocol capabilities in the future.
It’s possible that a subset of existing API methods are suitable for export. In this case, I think it is better to consciously re-export those methods under a more flexible calling convention than to support direct calls to them. This opt-in approach to exporting will also reduce the burden of analysis of which methods are both safe and supportable indefinitely.
Limits on public API scope
It is likely that the first version of a public API for built-in actors will not expose everything that a user programmer may want. This is because some core functionalities are targets for immediate change (e.g. #313, #298). We should scope initial API access to those data and capabilities of the built-in actors that we think are most stable and least likely to interact with future protocol improvements. These will be tough decisions in many instances. Future protocol upgrade can add new API functionality (but probably never remove or significantly alter existing methods).
Discussion
Calling convention
As discussed in #382, the existing sequential-method-number dispatch mechanism used by built-in actors is inappropriate for the development of APIs and standards for interoperability. User-programmed actors are expected to adopt some alternative and more flexible convention.
But the built-in actors must support some calling style for invocations from others. So we have to pick one, and composition of multiple actors will be most straightforward if they all use the same convention. This will also permit the built-in actors to implement standard APIs intended to be widely implemented, such as token APIs (e.g. storage deals as standardised NFTs).
While the FVM team are keen that the VM itself shouldn’t preclude the development of alternative conventions, this need not apply to the built-in actors. It’s acknowledged that support from the built-in actors would represent a significant endorsement of some convention, and promote its adoption more broadly. But, again, they have to support something. So it may as well be consciously designed, flexible, and suitable for wide use.
API scope
I don’t have a concrete API scope to propose yet, but we should probably develop an initial one for the FIP describing this proposal. Even if small, we can always extend it later.
Beta Was this translation helpful? Give feedback.
All reactions