kleros-v2 icon indicating copy to clipboard operation
kleros-v2 copied to clipboard

RNG: Chainlink VRF + Fallback mechanism

Open zmalatrax opened this issue 1 year ago β€’ 7 comments

This PR implements the Chainlink VRF Mechanism using the Subscription Method.

Rationale Subscription Method vs Direct Funding

Cost Efficiency

The Subscription Method reduces the gas cost of using VRF by pre-funding the subscription account with LINK when the direct funding method needs to calculate the cost of the request and fund it before actually making the request.

It is particularly efficient when many requests are made, which is the case as a random number is generated whenever jurors are drawn.

Simplified Management

Using a subscription centralizes the management:

  • A UI is provided to monitor the different requests made and their state.
  • LINK tokens funding is directed toward a single contract rather than each consumer (in case of having multiple consumers, i.e. multiple functionality where random number generation is needed).
  • The same applies to withdrawing. Withdrawing LINK tokens only has to be done from the subscription, not the consumers.

Scalability

One subscription can support up to 100 consuming contracts. It allows for potential future expansion, which may require random number generation.

Contracts

VRFConsumerV2.sol

VRF Consumer tailored to the SortitionModule.

It inherits from VRFConsumerBaseV2.sol, provided by Chainlink

Compared to the RandomizerRNG, only the SortitionModule can make a request, and the callback function calls sortitionModule.passPhase() once the random number is ready.

Implementation doc: Chainlink - Get a random number

VRFSubscriptionManagerV2.sol

A contract allowing programmatic management of the VRF subscription.

Without this contract, the subscription must be managed through the Subscription Manager UI.

A subscription is created in the constructor.

Implementation doc: Chainlink - Programmatic Subscription

Mock Contracts

To locally test the contract, we need to emulate the Chainlink VRF Coordinator.

VRFCoordinatorV2Mock.sol

This coordinator is provided by Chainlink: VRFCoordinationV2Mock.sol

VRFSubscriptionManagerV2Mock

The mock coordinator doesn't use LINK tokens, and the interface is different from the coordinator on public networks. Therefore a Subscription Manager mock had to be done.

Implementation doc: Chainlink - Local testing using a Mock contract

Deployment

The deployment scripts which deployed the Randomizer are 00-rng.ts and 00-home-chain-arbitration.ts.

I updated them to also deploy the VRFConsumerV2 and the VRFSubscriptionManagerV2Mock on the different networks.

The deployment scripts don't change the SortitionModule rng source (SortitionModule.changeRandomNumberGenerator(address rngAddress, uint256 rngLookAhead)), which is deployed with Randomizer as rng source.

Parameters

Most parameters are network-dependent (e.g. address of the vrf coordinator) but some have to be defined:

KeyHash

Gas lane: The maximum gas price you are willing to pay for a request in wei. Define this limit by specifying the appropriate keyHash in your request. The limits of each gas lane are important for handling gas price spikes when Chainlink VRF bumps the gas price to fulfill your request quickly.

Network Available key hashes
Arbitrum One 2 gwei, 30 gwei, 150 gwei
Arbitrum Goerli 50 gwei
localhost irrelevant

I've set it to 30 gwei as it is the medium lane.

callbackGasLimit

Callback gas limit: Specifies the maximum amount of gas you are willing to spend on the callback request. Define this limit by specifying the callbackGasLimit value in your request.

The Randomizer sets a callbackGasLimit to 50 000, as the VRFConsumerV2 callback function makes an external call to sortitionModule.passPhase(), I chose to set it at 100 000.

requestConfirmations

requestConfirmations: How many confirmations the Chainlink node should wait before responding. The longer the node waits, the more secure the random value is.

The range on Arbitrum: 1 - 200. I've arbitrarily set it to 3.

numWords

How many random values to request. If you can use several random values in a single callback, you can reduce the amount of gas that you spend per random value. The total cost of the callback request depends on how your fulfillRandomWords() function processes and stores the received random values, so adjust your callbackGasLimit accordingly.

I've set it to 1, as only one random number is needed to draw jurors.

Public Networks

  • Deploy VRFSubscriptionManagerV2
  • Deploy VRFConsumerV2
  • Add the deployed VRFConsumerV2 as a consumer of the subscription

Funds need to be added to the subscription.

Localhost

  • Deploy VRFSubscriptionManagerV2
  • Fund the subscription with 100 LINK (arbitrary amount)
  • Deploy VRFConsumerV2
  • Add the deployed VRFConsumerV2 as a consumer of the subscription

Hardhat Task - Credit LINK

To fund the subscription with LINK on public networks (Arbitrum One & Arbitrum Goerli), I wrote a hardhat task that transfers amountInWei LINK tokens from the deployer to the VRFSubscriptionManagerV2, which then funds the subscription by calling VRFSubscriptionManagerV2.topUpSubscription(amountInWei).

The amount passed as a parameter is "normal values" (e.g. 100 LINK), and not in wei to avoid errors. The amountInWei is computed from it.

Tests

Local tests making use of the Randomizer are arbitration/draw.ts, arbitration/unstake.ts, and integrations/index.ts.

I duplicated the tests, the first running with the default rng source (Randomizer from deployment) and the copy changing the rng source to VRFConsumerV2 and accordingly using it. (Mock contracts: VRFCoordinator triggered manually in the test).


PR-Codex overview

This PR introduces a fallback mechanism for receiving randomness and updates Chainlink VRF interactions.

Detailed summary

  • Added a receiveRandomnessFallback function to RNG contracts.
  • Updated RNG configuration in deploy/upgrade-sortition-module.ts.
  • Added Chainlink VRF functionality in scripts/creditLink.ts.
  • Modified tests to include Chainlink VRF interactions.
  • Updated SortitionModule.sol with rngFallbackTimeout parameter.

The following files were skipped due to too many changes: contracts/src/arbitration/SortitionModule.sol, contracts/test/arbitration/draw.ts, contracts/src/rng/interfaces/VRFCoordinatorV2Interface.sol, contracts/src/rng/mock/VRFSubscriptionManagerV2Mock.sol, contracts/deploy/00-home-chain-arbitration.ts, contracts/src/rng/VRFSubscriptionManagerV2.sol, contracts/src/rng/VRFConsumerBaseV2.sol, contracts/test/integration/index.ts, contracts/src/rng/mock/VRFCoordinatorV2Mock.sol, contracts/src/rng/VRFConsumerV2.sol

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

zmalatrax avatar Jun 21 '23 12:06 zmalatrax

Deploy Preview for kleros-v2-contracts ready!

Name Link
Latest commit 2149884ef61983cb4533e774fa0f90ba9f8fd236
Latest deploy log https://app.netlify.com/sites/kleros-v2-contracts/deploys/64944bcf8e730e00084ade81
Deploy Preview https://deploy-preview-966--kleros-v2-contracts.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

netlify[bot] avatar Jun 21 '23 12:06 netlify[bot]

Deploy Preview for kleros-v2 ready!

Name Link
Latest commit 4b69a12487750766398258e84a3fcee4ce8fa861
Latest deploy log https://app.netlify.com/sites/kleros-v2/deploys/65f05e84db9c0c0008547c19
Deploy Preview https://deploy-preview-966--kleros-v2.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

netlify[bot] avatar Jun 21 '23 12:06 netlify[bot]

Kudos, SonarCloud Quality Gate passed!Β  Β  Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 7 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

sonarqubecloud[bot] avatar Jun 22 '23 13:06 sonarqubecloud[bot]

Code Climate has analyzed commit 04286933 and detected 63 issues on this pull request.

Here's the issue category breakdown:

Category Count
Complexity 3
Duplication 26
Style 34

View more on Code Climate.

codeclimate[bot] avatar Oct 29 '23 17:10 codeclimate[bot]

Kudos, SonarCloud Quality Gate passed!Β  Β  Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 5 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

sonarqubecloud[bot] avatar Oct 29 '23 17:10 sonarqubecloud[bot]

RNG lookahead is removed since it's not needed with this fallback setup. It won't be used by ChainlinkRNG itself and is irrelevant for BlockhashRNG since rngFallback will ensure that enough time has passed when it'll be used.

unknownunknown1 avatar Oct 29 '23 17:10 unknownunknown1

Deploy Preview for kleros-v2-university ready!

Name Link
Latest commit 4b69a12487750766398258e84a3fcee4ce8fa861
Latest deploy log https://app.netlify.com/sites/kleros-v2-university/deploys/65f05e84b7db2800082bb53a
Deploy Preview https://deploy-preview-966--kleros-v2-university.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

netlify[bot] avatar Mar 12 '24 13:03 netlify[bot]