filecoin-project / lotus

Reference implementation of the Filecoin protocol, written in Go
https://lotus.filecoin.io/
Other
2.85k stars 1.27k forks source link

Support actor state accessors using canonical actor #8063

Open arajasek opened 2 years ago

arajasek commented 2 years ago

I'm not quite sure what the right thing to do here is. Although the actual state objects aren't having their shapes changed, we currently use go-actors code for a bunch of getters (and the occasional setter for test things). We could:

Stebalien commented 2 years ago

We do need to keep old specs actors for old network versions, but for future state changes, we could:

  1. Copy go struct definitions into lotus.
  2. Define schemas for actors and codegen.
  3. Define accessors as read-only methods actors.

I prefer option 3, but there could be some performance implications as that implies calling through the FVM. But that shouldn't matter too much here.

frrist commented 2 years ago

In Lily, we are exploring the possibility of creating an IPLD schema and generating the required methods from that: https://github.com/filecoin-project/lily/issues/859. Could this be considered as a 4th option -- unless that is what's meant by option 2?

Stebalien commented 2 years ago

That's what I meant by option 2. We'd actually like to attach said schemas to actor code itself. This would allow one to resolve:

actor -> actor code cid -> actor schema cid

arajasek commented 2 years ago

@jennijuju ordered me to let @frrist know that we'll be sticking with the go-actors accessors for now, which means no change for Lily.

While we're at it, can someone explain to me what an IPLD schema means (and what it would look like in this context)? I don't really know what's being proposed. Maybe an example I can look at?

Stebalien commented 2 years ago

See https://ipld.io/docs/schemas/

It allows one to specify the logical structure of some IPLD datastructure, regardless of it's underlying representation.

For example, we could specify the Multisig state as follows:

type Address bytes
type TokenAmount bytes
type ChainEpoch int
type MethodNum int

type Transaction struct {
    To     Address
    Value  TokenAmount
    Method MethodNum
    Params bytes

    // This address at index 0 is the transaction proposer, order of this slice must be preserved.
    Approved [Address]
} representation tuple

type MultisigState struct {
    Signers               [Address]
    NumApprovalsThreshold int
    NextTxnID             int

    // Linear unlock
    InitialBalance TokenAmount
    StartEpoch     ChainEpoch
    UnlockDuration ChainEpoch

    PendingTxns &{ bytes : Transaction } representation advanced FilecoinHAMT
} representation tuple

We can use this to:

  1. Generate go and/or rust code, in theory at least. In practice, we lack some tooling.
  2. Generate an IPLD-based representation of this schema (so we can store it on-chain).

In this case, my plan would be to:

  1. Generate an IPLDified version of the schema.
  2. Store it in the chain state along with the actor code.
  3. When trying to decode some actor's state, use the schema to "understand" the state.
frrist commented 2 years ago

With respect to lack of tooling: @mvdan pointed me at this https://github.com/ipld/go-ipld-adl-hamt/issues/17 (perhaps there is more here I'm not aware of) over in #ipld-chatter.

@Stebalien is this a pattern FVM is considering?

jennijuju commented 2 years ago

The discussion about the schema is good. however, we have decided to use spec actor for now and then - maybe consider this in the future (meaning, not happening in network v16 FVM M1)

frrist commented 2 years ago

Will there be a new version of specs-actors (i.e. v8) for network v16?

rvagg commented 2 years ago

I did schemas back for an older version of the chain, things have probably changed a bit since then: https://github.com/ipld/ipld/tree/master/_legacy/specs/data-structures/filecoin - it's stuck in the _legacy folder and not published to the new ipld.io site because it's out of date and not as useful as I'd hoped it to be (I refer to it regularly still though!). Actors are all in https://github.com/ipld/ipld/blob/master/_legacy/specs/data-structures/filecoin/chain.md#actors

Accuracy would need to be checked. And the issue of what to do with the HAMTs and AMTs is an interesting one too if you want to get down and dirty in there. They're pretty ugly and impenetrable from a purely data model perspective, but that's why we're doing "ADLs"—to pretend they're the thing they're designed to be used as (HAMT = map, AMT = list). So one step I always hoped for those docs was to be able to build in the ADL forms too, but we don't have a good way of expressing that yet. We're making good progress on go-ipld-adl-hamt and it has a "filecoin mode". Doing an AMT version would be pretty easy once we have the full ADL pattern nailed down for the HAMT.

wrt tooling—we have Go codegen that works for most of this stuff, if we needed to close up some gaps I don't think there's major challenges here (Any support is a bigger challenge, but that doesn't come into play here). But we're currently prioritising bindnode (reflection) as our recommended interface via go-ipld-prime for now. You can see an example of it being used against some native Filecoin types here: https://github.com/filecoin-project/go-fil-markets/pull/713 - we get to reuse the existing Go types, without modification, and with parallel cbor-gen support intact, and we're just attaching a schema and some wiring (which gets a touch complicated for things like Address and TokenAmount, Signature, but they're now doable with changes in go-ipld-prime master, as you can see in that PR - search for signatureFromBytes and signatureToBytes as an example).

Stebalien commented 2 years ago

Note: There's also edelweiss (https://github.com/ipld/edelweiss/) and a discussion on whether or not we can use it as an IDL for actor APIs. If we did that, it would be nice to use it to describe actor state as well.

See https://github.com/filecoin-project/ref-fvm/issues/719.