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

RNG: Chainlink VRF + Fallback mechanism #966

Closed
wants to merge 30 commits into from

Conversation

zmalatrax
Copy link
Contributor

@zmalatrax zmalatrax commented Jun 21, 2023

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}

@netlify
Copy link

netlify bot commented Jun 21, 2023

Deploy Preview for kleros-v2-contracts ready!

Name Link
🔨 Latest commit 2149884
🔍 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
Copy link

netlify bot commented Jun 21, 2023

Deploy Preview for kleros-v2 ready!

Name Link
🔨 Latest commit 4b69a12
🔍 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.

@zmalatrax zmalatrax self-assigned this Jun 21, 2023
@jaybuidl jaybuidl self-requested a review June 22, 2023 13:15
@zmalatrax zmalatrax force-pushed the feat/chainlink-vrf-as-rng branch from b1217ab to 2149884 Compare June 22, 2023 13:25
@sonarcloud
Copy link

sonarcloud bot commented Jun 22, 2023

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

@jaybuidl jaybuidl modified the milestone: alpha-1 Jun 28, 2023
@jaybuidl jaybuidl marked this pull request as ready for review June 29, 2023 13:12
@unknownunknown1 unknownunknown1 force-pushed the feat/chainlink-vrf-as-rng branch from 2149884 to acfcd1b Compare October 29, 2023 14:15
@codeclimate
Copy link

codeclimate bot commented Oct 29, 2023

Code Climate has analyzed commit 0428693 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.

@sonarcloud
Copy link

sonarcloud bot commented Oct 29, 2023

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

@unknownunknown1
Copy link
Contributor

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.

@jaybuidl jaybuidl linked an issue Dec 6, 2023 that may be closed by this pull request
@jaybuidl jaybuidl changed the title feat(RNG): add Chainlink VRF v2 as a rng source RNG: Chainlink VRF + Fallback mechanism Dec 6, 2023
@jaybuidl jaybuidl linked an issue Dec 6, 2023 that may be closed by this pull request
Copy link

netlify bot commented Mar 12, 2024

Deploy Preview for kleros-v2-university ready!

Name Link
🔨 Latest commit 4b69a12
🔍 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.

@jaybuidl jaybuidl assigned jaybuidl and unassigned zmalatrax Nov 27, 2024
This was referenced Dec 6, 2024
@jaybuidl
Copy link
Member

Superseded by #1778 and #1782

@jaybuidl jaybuidl closed this Dec 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RNG fallback mechanism RNG: Chainlink VRF
3 participants