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

chore: scripts to populate the subcourts #293

Merged
merged 2 commits into from
Sep 8, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion contracts/README.md
Original file line number Diff line number Diff line change
@@ -163,12 +163,13 @@ yarn hardhat --network <arbitrumGoerli|arbitrumRinkeby|arbitrum|goerli|rinkeby|m

## Ad-hoc procedures

### Populating the policy registry
### Populating the policy registry and courts

#### 1/ Export the registry data from V1

```bash
yarn hardhat run scripts/getPoliciesV1.ts --network mainnet | tee policies.v1.json
yarn hardhat run scripts/getCourtsV1.ts --network mainnet | tee courts.v1.json
```

#### 2/ Import the data to V2 - Local Network
@@ -183,10 +184,12 @@ Shell 2:

```bash
yarn hardhat run scripts/populatePolicyRegistry.ts --network localhost
yarn hardhat run scripts/populateCourts.ts --network localhost
```

#### 3/ Import the data to V2 - Public Testnet

```bash
yarn hardhat run scripts/populatePolicyRegistry.ts --network arbitrumRinkeby
yarn hardhat run scripts/populateCourts.ts --network arbitrumRinkeby
```
56 changes: 56 additions & 0 deletions contracts/scripts/getCourtsV1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { BigNumber } from "ethers";
import { ethers } from "hardhat";
import { IKlerosLiquid } from "../typechain-types";

interface Court {
id: number;
parent: number;
hiddenVotes: boolean;
minStake: number;
alpha: number;
feeForJuror: number;
jurorsForCourtJump: number;
timesPerPeriod: number[];
}

async function main() {
const courtsV1 = (await ethers.getContractAt(
"IKlerosLiquid",
"0x988b3A538b618C7A603e1c11Ab82Cd16dbE28069"
)) as IKlerosLiquid;

const courts: Court[] = [];
for (let courtId = 0; courtId < 24; ++courtId) {
const court: Court = await courtsV1.courts(courtId).then(
(result) =>
({
id: courtId,
parent: result.parent.toString(),
hiddenVotes: result.hiddenVotes,
minStake: result.minStake.toString(),
alpha: result.alpha.toString(),
feeForJuror: result.feeForJuror.toString(),
jurorsForCourtJump: result.feeForJuror.toString(),
timesPerPeriod: [],
} as unknown as Court)
);

court.timesPerPeriod = await courtsV1.getSubcourt(courtId).then((result) => {
return result.timesPerPeriod.map((bn) => bn.toNumber());
});

court.id = courtId;

// console.log("CourtId %d -> %O", courtId, court);

courts.push(court);
}
console.log(JSON.stringify(courts, null, "\t"));
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
125 changes: 125 additions & 0 deletions contracts/scripts/populateCourts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { deployments, getNamedAccounts, getChainId, ethers } from "hardhat";
import { KlerosCore } from "../typechain-types";
import { BigNumber } from "ethers";
import courtsV1 from "../courts.v1.json";

enum HomeChains {
ARBITRUM_ONE = 42161,
ARBITRUM_RINKEBY = 421611,
ARBITRUM_GOERLI = 421613,
HARDHAT = 31337,
}

const DISPUTE_KIT_CLASSIC = BigNumber.from(1);

async function main() {
// fallback to hardhat node signers on local network
const deployer = (await getNamedAccounts()).deployer ?? (await ethers.getSigners())[0].address;

const chainId = Number(await getChainId());
if (!HomeChains[chainId]) {
console.error(`Aborting: script is not compatible with ${chainId}`);
return;
} else {
console.log("deploying to %s with deployer %s", HomeChains[chainId], deployer);
}

// WARNING: skip the Forking court at id 0, so the v1 courts are shifted by 1
const courtsV2 = courtsV1.map((court) => ({
...court,
id: BigNumber.from(court.id).add(1),
parent: BigNumber.from(court.parent).add(1),
}));

console.log("courtsV2 = %O", courtsV2);

const klerosCoreDeployment = await deployments.get("KlerosCore");
const core = (await ethers.getContractAt("KlerosCore", klerosCoreDeployment.address)) as KlerosCore;

for (const court of courtsV2) {
const subcourtPresent = await core.courts(court.id).catch(() => {});
if (subcourtPresent) {
console.log("Subcourt %d found: %O", court.id, subcourtPresent);

// Subcourt.parent and sortitionSumTreeK cannot be changed.

if (subcourtPresent.hiddenVotes !== court.hiddenVotes) {
console.log(
"Subcourt %d: changing hiddenVotes from %d to %d",
court.id,
subcourtPresent.hiddenVotes,
court.hiddenVotes
);
await core.changeSubcourtHiddenVotes(court.id, court.hiddenVotes);
}

if (!subcourtPresent.minStake.eq(court.minStake)) {
console.log("Subcourt %d: changing minStake from %d to %d", court.id, subcourtPresent.minStake, court.minStake);
await core.changeSubcourtMinStake(court.id, court.minStake);
}

if (!subcourtPresent.alpha.eq(court.alpha)) {
console.log("Subcourt %d: changing alpha from %d to %d", court.id, subcourtPresent.alpha, court.alpha);
await core.changeSubcourtAlpha(court.id, court.alpha);
}

if (!subcourtPresent.feeForJuror.eq(court.feeForJuror)) {
console.log(
"Subcourt %d: changing feeForJuror from %d to %d",
court.id,
subcourtPresent.feeForJuror,
court.feeForJuror
);
await core.changeSubcourtJurorFee(court.id, court.feeForJuror);
}

if (!subcourtPresent.jurorsForCourtJump.eq(court.jurorsForCourtJump)) {
console.log(
"Subcourt %d: changing jurorsForCourtJump from %d to %d",
court.id,
subcourtPresent.jurorsForCourtJump,
court.jurorsForCourtJump
);
await core.changeSubcourtJurorsForJump(court.id, court.jurorsForCourtJump);
}

const timesPerPeriodPresent = (await core.getTimesPerPeriod(court.id)).map((bn) => bn.toNumber());
if (!timesPerPeriodPresent.every((val, index) => val === court.timesPerPeriod[index])) {
console.log(
"Subcourt %d: changing timesPerPeriod from %O to %O",
court.id,
timesPerPeriodPresent,
court.timesPerPeriod
);
await core.changeSubcourtTimesPerPeriod(court.id, [
court.timesPerPeriod[0],
court.timesPerPeriod[1],
court.timesPerPeriod[2],
court.timesPerPeriod[3],
]);
}
} else {
console.log("Subcourt %d not found, creating it with", court.id, court);
await core.createSubcourt(
court.parent,
court.hiddenVotes,
court.minStake,
court.alpha,
court.feeForJuror,
court.jurorsForCourtJump,
[court.timesPerPeriod[0], court.timesPerPeriod[1], court.timesPerPeriod[2], court.timesPerPeriod[3]],
5, // Not accessible on-chain, but has always been set to the same value so far.
[DISPUTE_KIT_CLASSIC]
);
}

await new Promise((resolve) => setTimeout(resolve, 100));
}
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
2 changes: 1 addition & 1 deletion contracts/src/arbitration/KlerosCore.sol
Original file line number Diff line number Diff line change
@@ -453,7 +453,7 @@ contract KlerosCore is IArbitrator {
* @param _subcourtID The ID of the subcourt.
* @param _hiddenVotes The new value for the `hiddenVotes` property value.
*/
function changeHiddenVotes(uint96 _subcourtID, bool _hiddenVotes) external onlyByGovernor {
function changeSubcourtHiddenVotes(uint96 _subcourtID, bool _hiddenVotes) external onlyByGovernor {
courts[_subcourtID].hiddenVotes = _hiddenVotes;
emit SubcourtModified(_subcourtID, "hiddenVotes");
}
24 changes: 24 additions & 0 deletions contracts/src/kleros-v1/IKlerosLiquid.sol
Original file line number Diff line number Diff line change
@@ -19,6 +19,18 @@ interface IKlerosLiquid is IArbitrator {
drawing // Jurors can be drawn. Pass after all disputes have jurors or `maxDrawingTime` passes.
}

struct Court {
uint96 parent; // The parent court.
uint256[] children; // List of child courts.
bool hiddenVotes; // Whether to use commit and reveal or not.
uint256 minStake; // Minimum tokens needed to stake in the court.
uint256 alpha; // Basis point of tokens that are lost when incoherent.
uint256 feeForJuror; // Arbitration fee paid per juror.
// The appeal after the one that reaches this number of jurors will go to the parent court if any, otherwise, no more appeals are possible.
uint256 jurorsForCourtJump;
uint256[4] timesPerPeriod; // The time allotted to each dispute period in the form `timesPerPeriod[period]`.
}

struct Dispute {
// Note that appeal `0` is equivalent to the first round of the dispute.
uint96 subcourtID; // The ID of the subcourt the dispute is in.
@@ -37,6 +49,18 @@ interface IKlerosLiquid is IArbitrator {
uint256 lockedTokens; // The juror's total amount of tokens locked in disputes.
}

function courts(uint256 _index)
external
view
returns (
uint96 parent,
bool hiddenVotes,
uint256 minStake,
uint256 alpha,
uint256 feeForJuror,
uint256 jurorsForCourtJump
);

function phase() external view returns (Phase);

function lockInsolventTransfers() external view returns (bool);