ref-fvm icon indicating copy to clipboard operation
ref-fvm copied to clipboard

FIP: Mechanism to ensure sufficient resources

Open Stebalien opened this issue 1 year ago • 8 comments

We need a mechanism to ensure that an actor is running with sufficient resources to perform an operation. Specifically, a way to assert that:

  1. There's at least X amount of memory remaining.
  2. The stack depth is at most Y.

Without this, a malicious caller M can:

  1. Call into some target actor T.
  2. T then calls into some victim V.
  3. V fails because it doesn't have enough memory, call stack, etc.
  4. T thinks there's a bug in V, ignores the failure, and continues.

Right now, there's no way for T to know that V's failure is actually M's fault.

However, this would change if T could somehow assert the current call depth and current memory usage.

Stebalien avatar Mar 01 '23 03:03 Stebalien

We have two real options here:

  1. Provide some way to lookup the current call depth and memory used.
  2. Provide some way to assert, in a call, that some amount of memory, call stack, and gas is available.

The second option is likely more convenient as it would provide a way to assert the exact conditions under which the callee is running. Personally, I'd propose adding two send flags:

  • A flag to say that there must be room for at least N (256?) recursive calls and at least M (256 or 512?) MiB of memory left.
  • ~A flag to say that the the call's gas limit must not exceed the gas available (by default, the gas limit is capped at the available gas).~ (edit: we don't need this second one)

These should cover most cases and should be relatively hard to misuse.

Stebalien avatar Mar 01 '23 03:03 Stebalien

What is the benefit of A) T doing lookup or assertion vs. B) V providing a clear error message when it runs out of memory or exceeds the call depth which T can check?

maciejwitowski avatar Mar 01 '23 12:03 maciejwitowski

V could be lying (I probably shouldn't have called it the "victim"). Basically, T needs to know whom to blame: M or V.

  • A malicious M forces V to fail.
  • A malicious (or buggy) V fails on its own (intentionally or otherwise).

T now needs to know whether to:

  1. Abort the entire operation (e.g., because M forced V to fail).
  2. Ignore the failure from V.

Stebalien avatar Mar 01 '23 14:03 Stebalien

The concrete use-case here is a "notification". On completion of some operation, we want T to be able to call into V to notify it that something has happened.

If something goes wrong (e.g., V spends too much gas, uses too much memory, or just has a bug), that's not T's problem. T shouldn't be forced to abort just because T has a bug.

However, if some malicious entity M can setup the call to T such that the call to V is guaranteed to fail, though no fault of V, we don't wan to just blame V and move on. In that case, we want to blame M and abort the call to T.

Stebalien avatar Mar 01 '23 14:03 Stebalien

Ok, makes sense.

T shouldn't be forced to abort just because T has a bug.

"because V has a bug", right?

maciejwitowski avatar Mar 01 '23 16:03 maciejwitowski

Er, yes.

Stebalien avatar Mar 01 '23 17:03 Stebalien

TODO: create a FIP discussion.

Stebalien avatar Mar 01 '23 17:03 Stebalien

FIP discussion https://github.com/filecoin-project/FIPs/discussions/646

Stebalien avatar Mar 02 '23 05:03 Stebalien