Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FLIP GOV-6 - Addition of @bluesign as a multi-sig signer #207

Closed
wants to merge 9 commits into from
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ will solve it. Specifically, the FLIP will:

Once the FLIP is ready for review:

1. Recruit a [sponsor](#flip-sponsors) from the maintainers or the active contributors of the project for which your FLIP concerns. A sponsor may help streamline the review process and moderate the discussion with the community

1. Recruit a [sponsor](#flip-sponsors) from the community. A sponsor would usually be a past FLIP author or a core community member who has expertise in the topic that your FLIP concerns, and may help streamline the review process and moderate the discussion with the community.

2. Create an [issue](https://github.com/onflow/flips/issues/new/choose) by using one of the FLIP issue templates based on the type of the FLIP - `application`, `governance`, `cadence` or `protocol`.
The title of the issue should be the title of your FLIP, e.g., "Dynamic Inclusion fees".
Expand Down Expand Up @@ -156,9 +155,10 @@ the [community forum](https://forum.onflow.org/), or file an issue in this repos
## Proposal states

* **Proposed:** The FLIP has been proposed and is awaiting review.
* **Rejected:** The FLIP has been reviewed and been rejected.
* **Rejected:** The FLIP has been reviewed and rejected.
* **Accepted:** The FLIP has been accepted and is either awaiting implementation or is actively being implemented.
* **Implemented (in VERSION):** The FLIP has been implemented.
* **Implemented:** All changes for the FLIP have been implemented and merged into the main branch of the respective repositories.
* **Released:** The FLIP is live on Flow mainnet.

## Community members

Expand Down
2 changes: 1 addition & 1 deletion application/20201125-bip-44-multi-account.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
status: implemented
status: released
flip: 200
authors: Peter Siemens ([email protected]), Jeffery Doyle ([email protected])
sponsor: Peter Siemens ([email protected])
Expand Down
2 changes: 1 addition & 1 deletion application/20221108-fcl-specification.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
status: implemented
status: released
flip: 45
authors: Greg Santos ([email protected])
sponsor: Justin Barry ([email protected])
Expand Down
187 changes: 187 additions & 0 deletions cadence/20230713-random-function.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
---
status: accepted
flip: 120
authors: Tarak Ben Youssef ([email protected])
sponsor:
updated: 2023-08-22
---

# FLIP 120: Update unsafeRandom function

## Objective

The purpose of this FLIP is to:
- Rename the current `fun unsafeRandom(): UInt64` function to
`fun revertibleRandom(): UInt64`.
This can be done by introducing a new `revertibleRandom` function, and eventually
deprecating `unsafeRandom` (breaking change).
- Expand the current function to a more safe and convenient `fun revertibleRandom<T: UnsignedInteger>([modulo: T]): T`,
where `UnsignedInteger` covers all Cadence's fixed-size unsigned integer types, and `modulo` is an optional upper-bound argument.

## Motivation

### Function Rename

#### Safe randomness

The Flow Virtual Machine (FVM) provides the implementation of `unsafeRandom` as part of the Flow protocol.
The FVM implementation has been using the block hash as a source of entropy.
This source can be manipulated by miners (i.e consensus nodes)
and should not be relied on to derive secure randomness,
hence the `unsafe` suffix in the function name.

FVM [underwent changes](https://github.com/onflow/flow-go/pull/4498) that update the source of entropy
to rely on the secure distributed randomness generated within the Flow
protocol by [the random beacon](https://arxiv.org/pdf/2002.07403.pdf) component.
The Flow beacon is designed to generate decentralized, unbiased, unpredictable and verifiable
randomness.
Miners have negligible control to bias or predict the beacon
output.

Moreover, FVM is using extra measures to safely extend the secure source of entropy into
randoms in the transaction execution environment:
- FVM uses a unique diversified seed for each transaction execution.
- It uses a crypto-secure pseudo-random generator (PRG) to extend the seed entropy into a
deterministic sequence of randoms.
- FVM does not expose the PRG seed or state to the execution environment.

These measures make the `unsafeRandom` unpredictable to the transaction execution environment
and unbiasable by all transaction code prior to the random function call (for instance a transaction that calls
`revertibleRandom()` multiple times in order to predict the future random output).

All the reasons above support dropping the `unsafe` prefix.

#### Revertible randomness

It is important to note that while the new implementation provides
safe randomness that cannot be biased or predicted by the network miners
or by the transaction execution prior to the call, developers
should still be mindful about using the function very carefully.

In particular, a transaction sender can atomically abort the transaction execution
and revert all its state changes if they judge the random output is not favorable **after it is
revealed**. The function is not immune to post-selection manipulation by a non-trusted party where a random number is sampled and then rejected.
As an example, imagine a transaction
that calls an on-chain casino contract, that rolls a dice to find out if the
transaction sender wins. The transaction can be written so that it triggers an
error if the game outcome is a loss.
Developers writing a similar casino contract should be aware of the transaction
abortion scenario by non-trusted users. This limitation is inherent to any smart contract platform that allows transactions to roll back atomically and cannot be solved through safe randomness alone.
Note that post-selection is not an issue when the transaction sender is trusted.

Removing the `unsafe` prefix completely would suggest to developers that the function is immune to all exploits.
Users may not realize that post-selection needs to be addressed using other patterns or techniques without an explicit warning.
The FLIP suggests to replace the `unsafe` prefix by the `revertible` prefix.
`revertible` is descriptive of the remaining issue of the function,
and serves as a reminder to developers to read more about the function documentation and be aware of the post-selection issue.

### function generalized header

Many applications require a random number less than an upper-bound `N` rather than a random number without constraints. For example, sampling a random element from an array requires picking a random index less than the array size.
`N` is commonly called the modulo. In security-sensitive applications, it is important to maintain a uniform distribution of the random output.
Returning the remainder of the division of a 64-bits number by `N` (using the modulo operation `%`) is known to result in a biased distribution where smaller outputs are more likely to be sampled than larger ones.
This is known as the "modulo bias".
There are safe solutions to avoid the modulo bias such as rejection sampling and large modulo reduction. Although these solutions can be implemented purely in Cadence, it is safer to provide the secure functions and abstract the complexity away from developers.
This also avoids using unsafe methods. The FLIP suggests to add an optional unsigned-integer argument `N` to the `revertibleRandom` function.
If `N` is provided, the returned random is uniformly sampled strictly less than `N`. The function errors if `N` is equal to `0`.
If `N` is not provided, the returned output has no constraints.

A more convenient way of using `random` is to cover all fixed-size unsigned integer types (`UInt8`, `UInt16`, `UInt32`, `UInt64`, `UInt128`, `UInt256`, `Word8`, `Word16`, `Word32`, `Word64`).
The type applies to the optional argument `modulo` as well as the returned value.
This would abstract the complexity of generating randoms of different types using 64-bits values as a building block.
The new suggested function signature is therefore `fun revertibleRandom<T: UnsignedInteger>([modulo: T]): T`,
where `T` can be any type from the above list.
Note that `UInt` is a variable-size type and is not supported by the function.

## User Benefit

Cadence uses the prefix `unsafe` to warn developers of the risks of using
the random function.

Risks related to the safety of the random source are addressed by the FVM recent updates.
However, post-selecting randoms after they are revealed is not addressed by the function and developers should be reminded of the remaining risk.
Replacing `unsafe` by `revertible` clarifies the assumption about the random source safety while being descriptive of the possible issue.
If developers are not familiar with using randomness, the prefix serves as an invitation to look at the documentation and learn about the function risks.

The generalized function signature offers safe and more flexible ways to use randomness.
Without such change, developers are required to implement extra logic and take the risk of making mistakes.

## Design Proposal

1. As a first step:
- Update Cadence's [runtime interface](https://github.com/onflow/cadence/blob/8a128022e0a5171f4c3a173911944a2f43548b98/runtime/interface.go#L107) `UnsafeRandom() (uint64, error)` to `ReadRandom(byte[]) error`.
- Add a new Cadence function `fun revertibleRandom<T: UnsignedInteger>([modulo: T]): T`, backed by a safe FVM implementation.
`fun unsafeRandom(): UInt64` remains available to avoid immediate breaking changes.
Note that both functions will be backed by the same safe FVM implementation.
2. As a second step, deprecate `fun unsafeRandom(): UInt64` as part of the
Stable Cadence release (aka Cadence v1.0).

### Drawbacks

Step (2) in [Design Proposal](#design-proposal) introduces a breaking change.

### Alternatives Considered

Renaming the random function to simply `random` has been considered. Below are some points supporting this alternative:
- Although any transaction with a random call can be reverted, some applications require randomness and have no incentive in reverting the result. Flow-core contracts for instance use randomness without reverting risks. A well-respected dapp also (assigning random NFTs for example) wouldn't want to add a reverting logic to their contract. For these applications, the new exposed randomness is considered safe. Adding `unsafe` would mean there is something wrong with the contract while there isn't.
- Result abortion is an inherent property of atomic smart-contract platforms, rather than a property of specific functions like randomness. The non-safety comes from the natural language property rather than the randomness itself. We can argue that any logic written with Cadence is revertible, while the prefix `unsafe` or `revertible` is not added for other Cadence functions. Developers should be aware that a state change in a transaction is revertible, not only when it calls randomness (a deterministic game transaction can abort if the player isn't happy with the result for instance).
- A language should try to provide as-safe-as-possible tools, but it can't guarantee that any program written in that language is totally safe. There is always some responsibility that falls on the language developer. It is possible to write very unsafe contracts and Cadence can't prevent it (using the cryptography functions as an example).


The generalized function signature could be omitted from the proposal because it is possible to implement `fun revertibleRandom<T: UnsignedInteger>([modulus; T]): T` purely on Cadence using `fun revertibleRandom(): UInt64`.
However, this requires developers to be familiar with safe low-level implementations and it may result in bugs and vulnerabilities.
It is safer to have these tools provided natively by Cadence.

### Performance Implications

The `revertibleRandom` function using the optional modulo argument `N` is obviously slower than when `N` is not provided. The extra cost is required to provide the safety and uniformity of the output distribution.

### Dependencies

None

### Engineering Impact

The Cadence repository needs to implement the generalized function signature (optional argument and extra types).

### Best Practices
The current proposal and the new FVM implementation
do not propose solutions for the transaction abortion issue.
Solutions to abortion such as safe design patterns and commit-reveal schemes can be discussed outside this FLIP (for instance this [separate FLIP](https://github.com/onflow/flips/pull/123) suggests a safe pattern to use randomness).


### Tutorials and Examples

```
let r1 = revertibleRandom<UInt8>() // r1 is of type `UInt8`
let r2 = revertibleRandom<Word16>() // r2 is of type `Word16`
let r3 = revertibleRandom<UInt128>(3) // r3 is of type `UInt128` and is strictly less than 3
let r4 = revertibleRandom<UInt128>(1 << 100) // r4 is of type `UInt128` and is of at most 100 bits
let r5 = revertibleRandom<Word64>(Word64(r1)) // r5 is of type `Word64` and is strictly less than `r1`
let r6 = revertibleRandom<UInt64>(0) // panics
```

### Compatibility

The step 2 of the [Design Proposal](#design-proposal) includes a breaking change.

### User Impact

Please refer to [Design Proposal](#design-proposal) for details on user impact.

## Related Issues

Please refer to [Best Practices](#best-practices) section.

## Questions and Discussion Topics

### Randomness in script execution

`executeScriptAtBlock` and `ExecuteScriptAtLatestBlock` are used to execute Cadence read-only code against the execution state at a past sealed block or the latest sealed blocked, respectively.
The FVM implementation of `revertibleRandom` uses the transaction hash to diversify the random sequence per transaction. This does not add new entropy but prevents generating the same randoms for different transactions. For this reason, it is not possible to replicate Cadence's `revertibleRandom` behavior in scripts.

The FLIP suggests to use the same source of randomness for scripts as for transactions, and to diversify the random sequence per script using the hash of the script code.
Although scripts use the same randomness source as transactions to derive randoms, it is not possible to retrieve the same random numbers when calling `revertibleRandom` as a transaction or as a script, the additional diversifier being different (transaction hash vs script hash).



22 changes: 18 additions & 4 deletions governance/20230122-revisiting-storage-fee.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,27 @@ Given that the state of Flow needs to be stored only across a handful of executi

1. storage pricing function would remain a constant multiple of the byte-size of the data to be stored on-chain
2. pricing (storage capacity per reserved Flow) would increase 100 times, as tabulated below.
3. minimum account balance however would increase 10 times such that minimum storage capacity reduces from 100kB to 10kB and the minimum balance required changes from 0.001 FLOW providing 100kB storage capacity, to 0.01 FLOW providing 10kB capacity (at a 100x multiple of the current pricing).
3. minimum account balance however would increase 10 times such that minimum balance required is 0.01 FLOW
4. 90kb bonus storage would be given to each account, such that storage_available = 90kb + storage_capacity per the pricing function tabulated below



| **Current Prices** | **Proposed Prices** |
|:---------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------:|
| 100 MB per 1 reserved FLOW <br>10 MB per 0.1 reserved FLOW<br>1 MB per 0.01 reserved FLOW<br>100 kB per 0.001 reserved FLOW | 100 MB per 100 reserved FLOW<br>10 MB per 10 reserved FLOW<br>1 MB per 1 reserved FLOW<br>10 kB per 0.01 reserved FLOW |
| 100 MB per 1 reserved FLOW <br>10 MB per 0.1 reserved FLOW<br>1 MB per 0.01 reserved FLOW<br>100 kB per 0.001 reserved FLOW | 100 MB (+90kB bonus) per 100 reserved FLOW<br>10 MB (+90kB bonus) per 10 reserved FLOW<br>1 MB (+90kB bonus) per 1 reserved FLOW<br>10 kB (+90kB bonus) per 0.01 reserved FLOW |

Note that if the proposal is accepted and implemented, all account balance requirements will be calculated based on the prices recommended above and the byte-size of data stored by the account. Here are a few examples to explain how the minimum balance requirement will be calculated -

• 0.01 FLOW provides 10kB storage capacity (at the new price rate) and a 90kB bonus, thus giving the account a storage capacity of 100kB. In other words, an account that stores < 100kB will be required to maintain a balance of 0.01 FLOW.

• 0.1 FLOW provides 100kB storage capacity (at the new price rate) and a 90kB bonus, thus a total storage capacity of 190kB.

• 0.11 FLOW provides 110kB storage capacity and a 90kB bonus, thus a total storage capacity of 200kB.

• 1 FLOW will provide 1MB storage capacity and a 90kB bonus, and so on.


If the proposal is accepted and implemented, users would require a minimum account balance of 0.01 FLOW as part of the account-creation transaction, providing them with up to 10kB of storage capacity, which is what >95% of all accounts use today. As the minimum account balance corresponds to account-creation transactions, this change makes the network more robust to sybil attacks. If the storage used by an account exceeds 10kB, account balance requirements will be calculated based on the prices recommended above and the byte-size of data stored by the account.
Note that users would require a minimum account balance of 0.01 FLOW as part of the account-creation transaction (which is 10 times than today’s requirement), providing them with up to 100kB of storage capacity (due to the 90kB bonus); this is equivalent to what new accounts get today. As the minimum account balance corresponds to account-creation transactions, this change makes the network more robust to sybil attacks.

With the proposed change in the pricing, Flow would continue to remain ~20x and 140x cheaper than NEAR protocol’s and Solana’s storage prices. Nevertheless, with this increase, Flow would **make deliberate storage-exhaustion attacks more costly, reduce token liquidity to drive broader network benefits, and allow for a sustainable and regulated growth of state.**

Expand Down Expand Up @@ -119,7 +133,7 @@ Flow's core team is working towards **strengthening FLOW token economics**, and

14. **Can users completely destruct accounts and reclaim locked FLOW?**

Today, users have the capability to erase data and unlock FLOW tokens, except that they cannot erase their account to retrieve the minimum balance. At present, with a mere 0.001 FLOW minimum balance, this seems reasonable. However, I understand that if the minimum account balance were to increase 100x (to 0.1 FLOW), having the capability to deactivate and recover funds would become more desirable and I urge the community to take up the capability to recover storage space as a separate FLIP.
Today, users have the capability to erase data and unlock FLOW tokens, except that they cannot erase their account to retrieve the minimum balance. At present, with a mere 0.001 FLOW minimum balance, this seems reasonable. However, I understand that if the minimum account balance were to increase 100x, having the capability to deactivate and recover funds would become more desirable and I urge the community to take up the capability to recover storage space as a separate FLIP.

15. **How will users know if they have enough balance. In other words, how can users differentiate between total balance and withdraw-able balance?**

Expand Down
Loading