From 9889db4ad2d1f2d444ffe04df84003637ade6c36 Mon Sep 17 00:00:00 2001 From: Aayush Date: Wed, 30 Aug 2023 12:27:10 -0400 Subject: [PATCH] Add FVM Randomness FIP --- FIPS/fip-randomness.md | 164 +++++++++++++++++++++++++++++++++++++++++ README.md | 1 + 2 files changed, 165 insertions(+) create mode 100644 FIPS/fip-randomness.md diff --git a/FIPS/fip-randomness.md b/FIPS/fip-randomness.md new file mode 100644 index 00000000..6d2ae6e6 --- /dev/null +++ b/FIPS/fip-randomness.md @@ -0,0 +1,164 @@ +--- +fip: "" +title: Improvements to the FVM randomness syscalls +author: "Aayush Rajasekaran (@arajasek), Steven Allen (@stebalien)" +discussions-to: https://github.com/filecoin-project/FIPs/discussions/790, https://github.com/filecoin-project/FIPs/discussions/791 +status: Draft +type: Technical (Core) +category: Core +created: <2023-28-28> +--- + + + +## Simple Summary + + +This FIP: + +1. Changes the FVM syscalls that fetch randomness to no longer mix-in user provided "entropy", actors must now do so themselves. +2. Changes the gas costs of the FVM syscalls that fetch randomness and tipset CIDs to be proportional to the lookback distance. + +## Abstract + + +Contracts can today request randomness from the FVM, which forwards the request to the client. +The client looks up the randomness from the chain (with no lookback limit), hashes it to "draw" the requested value, and returns it. + +This FIP proposes: +1. moving the hashing operation out of the FVM/client, and into the calling actor +1. formalizing that no lookback limit is enforced on randomness and tipset CID fetching, and modifying the gas pricing to be linear with the lookback range. + +## Change Motivation + + +The fact that fetching randomness and tipset CID today isn't priced proportional to the lookback is a security risk. This isn't a major issue today since only trusted code (the builtin actors) can request unbounded lookbacks. However, we still want to fix this in order to more accurately charge for costs, and future-proof this operation against both changes to the builtin actors and user-deployed "native" actors. + +The motivation to push the hashing operation into user-space is that the FVM already has a syscall that supports hashing. As a result, the FVM doesn't need to be performing this hashing for the client, and we can allow users (actors) to "draw" their randomness as they please. + +## Specification + + +### Interfaces + +We propose the following changes to the FVM syscalls: +- change the `get_chain_randomness` syscall from `get_chain_randomness(dst: i64, round: ChainEpoch, entropy: &[u8],)` to `get_chain_randomness(round: ChainEpoch)` +- change the `get_beacon_randomness` syscall from `get_beacon_randomness(dst: i64, round: ChainEpoch, entropy: &[u8],)` to `get_beacon_randomness(round: ChainEpoch)` + +The same breaking change should also be made to the `Externs` interface, and all client implementations of this interface. + +### Actor changes + +The implementation of the `Runtime` interface for the FVM has to change to: +- no longer supply the `dst` and `entropy` params when calling into the FVM SDK +- "draw" randomness for the calling actor, by hashing the randomness returned by the FVM with the `dst`, `round`, and `entropy` params + +The randomness drawing operation looks like this: + +``` +pub fn draw_randomness( + rbase: &[u8; RANDOMNESS_LENGTH], + pers: DomainSeparationTag, + round: ChainEpoch, + entropy: &[u8], +) -> [u8; RANDOMNESS_LENGTH] { + let mut data = Vec::with_capacity(RANDOMNESS_LENGTH + 8 + 8 + entropy.len()); + + // Append the personalization value + let i64_bytes = (pers as i64).to_be_bytes(); + data.extend_from_slice(&i64_bytes); + + // Append the randomness + data.extend_from_slice(rbase); + + // Append the round + let i64_bytes = round.to_be_bytes(); + data.extend_from_slice(&i64_bytes); + + // Append the entropy + data.extend_from_slice(entropy); + + // Ask the FVM to now hash this data + fvm::crypto::hash_blake2b(&data) +} +``` + +### Client changes + +Clients no longer receive the `dst` and `entropy` parameters for the randomness Extern methods, and should skip the final step of "drawing" randomness in which this DST and entropy is mixed into the hash. + +We also seek consensus amongst Core Devs that Filecoin clients are expected to be able to support chain walkbacks all the way to genesis, with a performance no _worse_ than that based on a skiplist of length 20. Clients are free to be more performant (eg. constant-time). +Clients can also be less performant, but the gas pricing would not be accurate for such clients. + +### Gas Pricing + +We change the gas pricing for both `get_randomness` operations, as well as the `get_tipset_cid` operation, to be proportional to the lookback distance. + +We charge `75 * lookback + 5800 * 19` for the lookback cost, where `lookback` is equal to the difference between the current epoch, and the requested epoch. +We additionally charge `15000` for the offset (the cost of producing the randomness/tipset CID itself), and `21000` for the extern cost. + +The total gas formula is thus: `75 * lookback + 110200 + 15000 + 21000`. + +## Design Rationale + + +The hashing change is designed to follow the principle of "anything that doesn't have to be done in the FVM shouldn't be done in the FVM". +Following this principle makes it easier to version changes, avoids explicit specialized gas charges, and reduces the risk of critical security issues. + +The gas changes for the lookback are designed to correctly price operations based on clients as they exist today, which is important for security. +We change the randomness gas pricing to be similar to the Tipset CID gas pricing in in line with prior work in [FIP-0054](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0054.md#tipset-cid-gas). + +1. We apply a cost of 1500/20 = 75 gas per epoch +1. We apply an additional cost of 5800*19 = 110200 for tipset traversal after the skipping +1. We apply a flat cost of 15000 for the overhead work (serializing, hashing, etc.), and 21000 as the flat extern gas cost + +This yields the specified formula of `75 * lookback + 110200 + 15000 + 21000`. + +While we could simplify and reduce the cost to be a single constant, doing so requires all Filecoin client implementations to support constant-time lookback, which is not currently a priority. + +We are also simplifying the gas pricing for fetching Tipset CIDs in this FIP. While FIP-0054 special-cased fetching the tipset CID at the current epoch, we are dropping that special-casing. +This makes fetching the tipset CID at the current epoch slightly more expensive, but simplifies the logic, and allows us to unify the gas pricing for fetching randomness and fetching tipset CIDs. + +## Backwards Compatibility + + +These changes are backwards incompatible, and require a network upgrade. Further, clients must: +- modify their support of the FVM extern to no longer receive Domain Separation Tags and entropy as inputs +- no longer hash the returned value + +## Test Cases + + +TODO + +## Security Considerations + + +This FIP is an overall improvement to security: +- it accurately charges for chain walkback operations. This ensures that contracts that force large chain walkbacks (whether due to bugs or malicious intent) cannot slow down state computation for free. +- by pushing the randomness hashing into userspace, it reduces the risky critical path. Any bugs in that logic will now be a problem for the contract, not the system itself. + +These changes are especially important if we plan to support native WASM actors. + +## Incentive Considerations + + +This FIP does not materially impact incentives in any way. + +## Product Considerations + + +This FIP does not materially impact the product in any way. + +## Implementation + + +TODO + +## TODO + + +None. + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/README.md b/README.md index 042cb90f..b9810747 100644 --- a/README.md +++ b/README.md @@ -111,3 +111,4 @@ This improvement protocol helps achieve that objective for all members of the Fi |[0071](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0071.md ) | Deterministic State Access (IPLD Reachability) | FIP |@stebalien| Draft | |[0072](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0072.md) | Improved event syscall API | FIP | @fridrik01, @Stebalien | Draft | |[0073](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0073.md) | : Remove beneficiary from the self_destruct syscall | FIP | @Stebalien | Draft | +|[XXXX](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-randomness.md) | Improvements to the FVM randomness syscalls | FIP | @arajasek, @Stebalien | Draft |