filecoin-project / builtin-actors

The Filecoin built-in actors
Other
82 stars 79 forks source link

IDEA: Stronger transaction guarantees #137

Open Stebalien opened 2 years ago

Stebalien commented 2 years ago

We can get better guarantees in rust by;

  1. Splitting the runtime into a "transaction runtime" and the "full runtime".
  2. Splitting the blockstore into a read/write half.
trait ReadStore {
    fn get(&self, mh_code: Code, block: &Block) -> Result<Cid>;
}

trait WriteStore: ReadStore {
    fn put(&self, mh_code: Code, block: &Block) -> Result<Cid>;
}

trait TransactionRuntime {
    type WriteStore: WriteStore;
    type ReadStore: ReadStore;

    // Reading state is always fine.
    fn state<C: Cbor>(&self) -> Result<C, ActorError>;
    fn store(&self) -> Result<&Self::ReadStore, ActorError>;

    fn resolve_address(&self, address: &Address) -> Option<Address>;
    fn current_balance(&self) -> TokenAmount;
    // etc...
}

trait FullRuntime: TransactionRuntime {
    type TransactionRuntime: TransactionRuntime;

    // 1. Inside the closure, the actor cannot use the FullRuntime
    //    (cannot send, cannot open new transactions).
    // 2. Outside the closure, the actor cannot create new blocks. The actor cannot
    //    keep a reference to the writeable blockstore either.
    fn transaction<R>(
        &mut self,
        f: impl FnOnce(
            &mut Self::TransactionRuntime, &Self::WriteStore, &mut impl Cbor,
        ) -> Result<R, ActorError>,
    );

    // Cannot be called in a transaction.
    fn send(
        &mut self,
        to: Address,
        method: MethodNum,
        params: RawBytes,
        value: TokenAmount,
    ) -> Result<RawBytes, ActorError>;
}
jennijuju commented 2 years ago

(This is not required for FVM M1 and can be potentially built by the rust SDK level.