Skip to content

Commit 413a85a

Browse files
authored
Merge pull request #2054 from kleros/feat/rng-fallback2
RNG Fallback
2 parents 0f31e0e + 78f180a commit 413a85a

31 files changed

+643
-388
lines changed

contracts/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ The format is based on [Common Changelog](https://common-changelog.org/).
99
### Changed
1010

1111
- **Breaking:** Replace `require()` with `revert()` and custom errors outside KlerosCore for consistency and smaller bytecode ([#2084](https://github.com/kleros/kleros-v2/issues/2084))
12+
- **Breaking:** Rename the interface from `RNG` to `IRNG` ([#2054](https://github.com/kleros/kleros-v2/issues/2054))
13+
- **Breaking:** Remove the `_block` parameter from `IRNG.requestRandomness()` and `IRNG.receiveRandomness()`, not needed for the primary VRF-based RNG ([#2054](https://github.com/kleros/kleros-v2/issues/2054))
14+
- Make the primary VRF-based RNG fall back to `BlockhashRNG` if the VRF request is not fulfilled within a timeout ([#2054](https://github.com/kleros/kleros-v2/issues/2054))
15+
- Authenticate the calls to the RNGs to prevent 3rd parties from depleting the Chainlink VRF subscription funds ([#2054](https://github.com/kleros/kleros-v2/issues/2054))
16+
- Use `block.timestamp` rather than `block.number` for `BlockhashRNG` for better reliability on Arbitrum as block production is sporadic depending on network conditions. ([#2054](https://github.com/kleros/kleros-v2/issues/2054))
1217
- Set the Hardhat Solidity version to v0.8.30 and enable the IR pipeline ([#2069](https://github.com/kleros/kleros-v2/issues/2069))
1318
- Set the Foundry Solidity version to v0.8.30 and enable the IR pipeline ([#2073](https://github.com/kleros/kleros-v2/issues/2073))
1419
- Widen the allowed solc version to any v0.8.x for the interfaces only ([#2083](https://github.com/kleros/kleros-v2/issues/2083))

contracts/deploy/00-ethereum-pnk.ts

Lines changed: 0 additions & 31 deletions
This file was deleted.

contracts/deploy/00-home-chain-arbitration-neo.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@ import { changeCurrencyRate } from "./utils/klerosCoreHelper";
66
import { HomeChains, isSkipped, isDevnet, PNK, ETH } from "./utils";
77
import { getContractOrDeploy, getContractOrDeployUpgradable } from "./utils/getContractOrDeploy";
88
import { deployERC20AndFaucet, deployERC721 } from "./utils/deployTokens";
9-
import { ChainlinkRNG, DisputeKitClassic, KlerosCoreNeo } from "../typechain-types";
9+
import { ChainlinkRNG, DisputeKitClassic, KlerosCoreNeo, RNGWithFallback } from "../typechain-types";
1010

1111
const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
1212
const { ethers, deployments, getNamedAccounts, getChainId } = hre;
1313
const { deploy } = deployments;
1414
const { ZeroAddress } = hre.ethers;
15-
const RNG_LOOKAHEAD = 20;
1615

1716
// fallback to hardhat node signers on local network
1817
const deployer = (await getNamedAccounts()).deployer ?? (await hre.ethers.getSigners())[0].address;
@@ -45,7 +44,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
4544
const devnet = isDevnet(hre.network);
4645
const minStakingTime = devnet ? 180 : 1800;
4746
const maxFreezingTime = devnet ? 600 : 1800;
48-
const rng = (await ethers.getContract("ChainlinkRNG")) as ChainlinkRNG;
47+
const rngWithFallback = await ethers.getContract<RNGWithFallback>("RNGWithFallback");
4948
const maxStakePerJuror = PNK(2_000);
5049
const maxTotalStaked = PNK(2_000_000);
5150
const sortitionModule = await deployUpgradable(deployments, "SortitionModuleNeo", {
@@ -55,8 +54,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
5554
klerosCoreAddress,
5655
minStakingTime,
5756
maxFreezingTime,
58-
rng.target,
59-
RNG_LOOKAHEAD,
57+
rngWithFallback.target,
6058
maxStakePerJuror,
6159
maxTotalStaked,
6260
],
@@ -94,11 +92,11 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
9492
await disputeKitContract.changeCore(klerosCore.address);
9593
}
9694

97-
// rng.changeSortitionModule() only if necessary
98-
const rngSortitionModule = await rng.sortitionModule();
99-
if (rngSortitionModule !== sortitionModule.address) {
100-
console.log(`rng.changeSortitionModule(${sortitionModule.address})`);
101-
await rng.changeSortitionModule(sortitionModule.address);
95+
// rngWithFallback.changeConsumer() only if necessary
96+
const rngConsumer = await rngWithFallback.consumer();
97+
if (rngConsumer !== sortitionModule.address) {
98+
console.log(`rngWithFallback.changeConsumer(${sortitionModule.address})`);
99+
await rngWithFallback.changeConsumer(sortitionModule.address);
102100
}
103101

104102
const core = (await hre.ethers.getContract("KlerosCoreNeo")) as KlerosCoreNeo;

contracts/deploy/00-home-chain-arbitration.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@ import { changeCurrencyRate } from "./utils/klerosCoreHelper";
66
import { HomeChains, isSkipped, isDevnet, PNK, ETH, Courts } from "./utils";
77
import { getContractOrDeploy, getContractOrDeployUpgradable } from "./utils/getContractOrDeploy";
88
import { deployERC20AndFaucet } from "./utils/deployTokens";
9-
import { ChainlinkRNG, DisputeKitClassic, KlerosCore } from "../typechain-types";
9+
import { ChainlinkRNG, DisputeKitClassic, KlerosCore, RNGWithFallback } from "../typechain-types";
1010

1111
const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
1212
const { ethers, deployments, getNamedAccounts, getChainId } = hre;
1313
const { deploy } = deployments;
1414
const { ZeroAddress } = hre.ethers;
15-
const RNG_LOOKAHEAD = 20;
1615

1716
// fallback to hardhat node signers on local network
1817
const deployer = (await getNamedAccounts()).deployer ?? (await hre.ethers.getSigners())[0].address;
@@ -50,10 +49,10 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
5049
const devnet = isDevnet(hre.network);
5150
const minStakingTime = devnet ? 180 : 1800;
5251
const maxFreezingTime = devnet ? 600 : 1800;
53-
const rng = (await ethers.getContract("ChainlinkRNG")) as ChainlinkRNG;
52+
const rngWithFallback = await ethers.getContract<RNGWithFallback>("RNGWithFallback");
5453
const sortitionModule = await deployUpgradable(deployments, "SortitionModule", {
5554
from: deployer,
56-
args: [deployer, klerosCoreAddress, minStakingTime, maxFreezingTime, rng.target, RNG_LOOKAHEAD],
55+
args: [deployer, klerosCoreAddress, minStakingTime, maxFreezingTime, rngWithFallback.target],
5756
log: true,
5857
}); // nonce (implementation), nonce+1 (proxy)
5958

@@ -80,18 +79,18 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
8079
}); // nonce+2 (implementation), nonce+3 (proxy)
8180

8281
// disputeKit.changeCore() only if necessary
83-
const disputeKitContract = (await ethers.getContract("DisputeKitClassic")) as DisputeKitClassic;
82+
const disputeKitContract = await ethers.getContract<DisputeKitClassic>("DisputeKitClassic");
8483
const currentCore = await disputeKitContract.core();
8584
if (currentCore !== klerosCore.address) {
8685
console.log(`disputeKit.changeCore(${klerosCore.address})`);
8786
await disputeKitContract.changeCore(klerosCore.address);
8887
}
8988

90-
// rng.changeSortitionModule() only if necessary
91-
const rngSortitionModule = await rng.sortitionModule();
92-
if (rngSortitionModule !== sortitionModule.address) {
93-
console.log(`rng.changeSortitionModule(${sortitionModule.address})`);
94-
await rng.changeSortitionModule(sortitionModule.address);
89+
// rngWithFallback.changeConsumer() only if necessary
90+
const rngConsumer = await rngWithFallback.consumer();
91+
if (rngConsumer !== sortitionModule.address) {
92+
console.log(`rngWithFallback.changeConsumer(${sortitionModule.address})`);
93+
await rngWithFallback.changeConsumer(sortitionModule.address);
9594
}
9695

9796
const core = (await hre.ethers.getContract("KlerosCore")) as KlerosCore;

contracts/deploy/00-home-chain-pnk-faucet.ts

Lines changed: 0 additions & 36 deletions
This file was deleted.

contracts/deploy/00-home-chain-resolver.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { HardhatRuntimeEnvironment } from "hardhat/types";
22
import { DeployFunction } from "hardhat-deploy/types";
33
import { HomeChains, isSkipped } from "./utils";
4-
import { deployUpgradable } from "./utils/deployUpgradable";
4+
import { getContractOrDeploy } from "./utils/getContractOrDeploy";
55

66
const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
77
const { deployments, getNamedAccounts, getChainId } = hre;
@@ -15,7 +15,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
1515
const klerosCore = await deployments.get("KlerosCore");
1616
const disputeTemplateRegistry = await deployments.get("DisputeTemplateRegistry");
1717

18-
await deploy("DisputeResolver", {
18+
await getContractOrDeploy(hre, "DisputeResolver", {
1919
from: deployer,
2020
args: [klerosCore.address, disputeTemplateRegistry.address],
2121
log: true,

contracts/deploy/00-chainlink-rng.ts renamed to contracts/deploy/00-rng-chainlink.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import { HardhatRuntimeEnvironment } from "hardhat/types";
22
import { DeployFunction } from "hardhat-deploy/types";
33
import { HomeChains, isSkipped } from "./utils";
44
import { getContractOrDeploy } from "./utils/getContractOrDeploy";
5+
import { RNGWithFallback } from "../typechain-types";
56

67
const deployRng: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
7-
const { deployments, getNamedAccounts, getChainId } = hre;
8-
const { deploy } = deployments;
8+
const { getNamedAccounts, getChainId, ethers } = hre;
99

1010
// fallback to hardhat node signers on local network
1111
const deployer = (await getNamedAccounts()).deployer ?? (await hre.ethers.getSigners())[0].address;
@@ -57,11 +57,16 @@ const deployRng: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
5757
const requestConfirmations = 200; // between 1 and 200 L2 blocks
5858
const callbackGasLimit = 100000;
5959

60-
await deploy("ChainlinkRNG", {
60+
const oldRng = await ethers.getContractOrNull("ChainlinkRNG");
61+
if (!oldRng) {
62+
console.log("Register this Chainlink consumer here: http://vrf.chain.link/");
63+
}
64+
65+
const rng = await getContractOrDeploy(hre, "ChainlinkRNG", {
6166
from: deployer,
6267
args: [
6368
deployer,
64-
deployer, // The consumer is configured as the SortitionModule later
69+
deployer, // The consumer is configured as the RNGWithFallback later
6570
ChainlinkVRFCoordinator.target,
6671
keyHash,
6772
subscriptionId,
@@ -70,6 +75,26 @@ const deployRng: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
7075
],
7176
log: true,
7277
});
78+
79+
const fallbackTimeoutSeconds = 30 * 60; // 30 minutes
80+
await getContractOrDeploy(hre, "RNGWithFallback", {
81+
from: deployer,
82+
args: [
83+
deployer,
84+
deployer, // The consumer is configured as the SortitionModule later
85+
fallbackTimeoutSeconds,
86+
rng.target,
87+
],
88+
log: true,
89+
});
90+
91+
// rng.changeConsumer() only if necessary
92+
const rngWithFallback = await ethers.getContract<RNGWithFallback>("RNGWithFallback");
93+
const rngConsumer = await rng.consumer();
94+
if (rngConsumer !== rngWithFallback.target) {
95+
console.log(`rng.changeConsumer(${rngWithFallback.target})`);
96+
await rng.changeConsumer(rngWithFallback.target);
97+
}
7398
};
7499

75100
deployRng.tags = ["ChainlinkRNG"];

contracts/deploy/00-randomizer-rng.ts renamed to contracts/deploy/00-rng-randomizer.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import { HardhatRuntimeEnvironment } from "hardhat/types";
22
import { DeployFunction } from "hardhat-deploy/types";
33
import { HomeChains, isSkipped } from "./utils";
44
import { getContractOrDeploy } from "./utils/getContractOrDeploy";
5+
import { RNGWithFallback } from "../typechain-types";
56

67
const deployRng: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
7-
const { deployments, getNamedAccounts, getChainId } = hre;
8-
const { deploy } = deployments;
8+
const { getNamedAccounts, getChainId, ethers } = hre;
99

1010
// fallback to hardhat node signers on local network
1111
const deployer = (await getNamedAccounts()).deployer ?? (await hre.ethers.getSigners())[0].address;
@@ -20,11 +20,35 @@ const deployRng: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
2020
log: true,
2121
});
2222

23-
await getContractOrDeploy(hre, "RandomizerRNG", {
23+
const rng = await getContractOrDeploy(hre, "RandomizerRNG", {
2424
from: deployer,
25-
args: [deployer, deployer, randomizerOracle.target], // The consumer is configured as the SortitionModule later
25+
args: [
26+
deployer,
27+
deployer, // The consumer is configured as the RNGWithFallback later
28+
randomizerOracle.target,
29+
],
2630
log: true,
2731
});
32+
33+
const fallbackTimeoutSeconds = 30 * 60; // 30 minutes
34+
await getContractOrDeploy(hre, "RNGWithFallback", {
35+
from: deployer,
36+
args: [
37+
deployer,
38+
deployer, // The consumer is configured as the SortitionModule later
39+
fallbackTimeoutSeconds,
40+
rng.target,
41+
],
42+
log: true,
43+
});
44+
45+
// rng.changeConsumer() only if necessary
46+
const rngWithFallback = await ethers.getContract<RNGWithFallback>("RNGWithFallback");
47+
const rngConsumer = await rng.consumer();
48+
if (rngConsumer !== rngWithFallback.target) {
49+
console.log(`rng.changeConsumer(${rngWithFallback.target})`);
50+
await rng.changeConsumer(rngWithFallback.target);
51+
}
2852
};
2953

3054
deployRng.tags = ["RandomizerRNG"];

contracts/deploy/00-rng.ts

Lines changed: 0 additions & 47 deletions
This file was deleted.
File renamed without changes.

0 commit comments

Comments
 (0)