mirror of
https://github.com/logos-storage/logos-storage-contracts-eth.git
synced 2026-01-02 05:13:13 +00:00
feat: move to hardhat ignition for deployments (#231)
* Move to ethers 6 and use hardhat ignition for deployments * Update prettier to the last version * Remove comment * Remove npx call in package.json * Remove useless comment * Add localhost configuration for hardhat ignition * Use contract initial balance instead of const value * Update dependencies and use extract mining to a script in order to use hardhat ignition deploy command * Fix deployment modules for local env * Remove unused function * Export contract deployment custom error assert into a function * Refactoring * Remove old deployments folder * Add process names when running concurrently * Remove conditional allowBlocksWithSameTimestamp, set true everytime * Update dependencies * Update Vault tests for ignition * Update token description * Add vault ignition module * Remove old .tool-versions * Fix formatting * Remove deployments folder and add README for previous files references * Put back the comment related to hardhat automine * Set hardhat gas limit to auto and restore manual mining for Vault tests * Apply prettier formatting and bug test with ignition syntax * Add deployments artifacts * Fix build-info ignore * Use HARDHAT_NETWORK env variable to deploy marketplace contract * Add guard to check that configs has tags * Add testnet deployment addresses * Add TOKEN_ADDRESS to reuse the token contract deployed * Fix token deployment with contractAt * Remove localhost deployment artifacts * Add section in README for deployments * Ignore localhost deployments in git * Set mine script for localhost deployment only and add deploy reset command * Remove previous deployment scripts * Fix typo in documentation * Add log when reusing token address * Update testnet artifact reference * Remove HARDHAT_NETWORK and update documentation * fix md format * Npm audit fix * Update dependencies * Remove default deployer * Update commit for last testnet artifacts * Remove deployments files from linea and testnet and update the last commit hashes to those artifacts
This commit is contained in:
parent
2dddc26015
commit
dee3d7b654
11
.github/workflows/ci.yml
vendored
11
.github/workflows/ci.yml
vendored
@ -10,7 +10,6 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
jobs:
|
||||
formatting:
|
||||
runs-on: ubuntu-latest
|
||||
@ -26,10 +25,9 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
# workaround for https://github.com/NomicFoundation/hardhat/issues/3877
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18.15
|
||||
node-version: 22
|
||||
- run: npm install
|
||||
- run: npm test
|
||||
- uses: actions/cache@v4
|
||||
@ -53,9 +51,9 @@ jobs:
|
||||
- name: Install Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: '11'
|
||||
java-package: 'jre'
|
||||
distribution: "zulu"
|
||||
java-version: "11"
|
||||
java-package: "jre"
|
||||
|
||||
- name: Install Certora CLI
|
||||
run: pip3 install certora-cli==7.10.2
|
||||
@ -88,4 +86,3 @@ jobs:
|
||||
rule:
|
||||
- verify:marketplace
|
||||
- verify:state_changes
|
||||
|
||||
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@ -4,3 +4,10 @@ artifacts
|
||||
deployment-localhost.json
|
||||
crytic-export
|
||||
.certora_internal
|
||||
coverage
|
||||
coverage.json
|
||||
|
||||
# Ignore localhost deployments files
|
||||
ignition/deployments/chain-31337
|
||||
|
||||
ignition/deployments/**/build-info
|
||||
|
||||
@ -1 +0,0 @@
|
||||
nodejs 18.15.0
|
||||
23
Readme.md
23
Readme.md
@ -22,9 +22,28 @@ To start a local Ethereum node with the contracts deployed, execute:
|
||||
|
||||
npm start
|
||||
|
||||
This will create a `deployment-localhost.json` file containing the addresses of
|
||||
the deployed contracts.
|
||||
Deployment
|
||||
----------
|
||||
|
||||
To deploy the marketplace, you need to specify the network using `--network MY_NETWORK`:
|
||||
|
||||
```bash
|
||||
npm run deploy -- --network localhost
|
||||
```
|
||||
|
||||
Hardhat uses [reconciliation](https://hardhat.org/ignition/docs/advanced/reconciliation) to recover from
|
||||
errors or resume a previous deployment. In our case, we will likely redeploy a new contract every time,
|
||||
so we will need to [clear the previous deployment](https://hardhat.org/ignition/docs/guides/modifications#clearing-an-existing-deployment-with-reset):
|
||||
|
||||
```bash
|
||||
npm run deploy -- --network testnet --reset
|
||||
```
|
||||
|
||||
To reuse a previously deployed `Token` contract, define the environment variable `TOKEN_ADDRESS`.
|
||||
The deployment script will use `contractAt` from Hardhat Ignition to retrieve the existing contract
|
||||
instead of deploying a new one.
|
||||
|
||||
The deployment files are kept under version control [as recommended by Hardhat](https://hardhat.org/ignition/docs/advanced/versioning), except the build files, which are 18 MB.
|
||||
|
||||
Running the prover
|
||||
------------------
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
const { loadZkeyHash } = require("../verifier/verifier.js")
|
||||
const { loadConfiguration } = require("../configuration/configuration.js")
|
||||
|
||||
async function mine256blocks({ network, ethers }) {
|
||||
if (network.tags.local) {
|
||||
await ethers.provider.send("hardhat_mine", ["0x100"])
|
||||
}
|
||||
}
|
||||
|
||||
// deploys a marketplace with a real Groth16 verifier
|
||||
async function deployMarketplace({ deployments, getNamedAccounts }) {
|
||||
const token = await deployments.get("TestToken")
|
||||
const verifier = await deployments.get("Groth16Verifier")
|
||||
const zkeyHash = loadZkeyHash(network.name)
|
||||
let configuration = loadConfiguration(network.name)
|
||||
configuration.proofs.zkeyHash = zkeyHash
|
||||
const args = [configuration, token.address, verifier.address]
|
||||
const { deployer: from } = await getNamedAccounts()
|
||||
const marketplace = await deployments.deploy("Marketplace", { args, from })
|
||||
console.log("Deployed Marketplace with Groth16 Verifier at:")
|
||||
console.log(marketplace.address)
|
||||
console.log()
|
||||
}
|
||||
|
||||
// deploys a marketplace with a testing verifier
|
||||
async function deployTestMarketplace({
|
||||
network,
|
||||
deployments,
|
||||
getNamedAccounts,
|
||||
}) {
|
||||
if (network.tags.local) {
|
||||
const token = await deployments.get("TestToken")
|
||||
const verifier = await deployments.get("TestVerifier")
|
||||
const zkeyHash = loadZkeyHash(network.name)
|
||||
let configuration = loadConfiguration(network.name)
|
||||
configuration.proofs.zkeyHash = zkeyHash
|
||||
const args = [configuration, token.address, verifier.address]
|
||||
const { deployer: from } = await getNamedAccounts()
|
||||
const marketplace = await deployments.deploy("Marketplace", { args, from })
|
||||
console.log("Deployed Marketplace with Test Verifier at:")
|
||||
console.log(marketplace.address)
|
||||
console.log()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = async (environment) => {
|
||||
await mine256blocks(environment)
|
||||
await deployMarketplace(environment)
|
||||
await deployTestMarketplace(environment)
|
||||
}
|
||||
|
||||
module.exports.tags = ["Marketplace"]
|
||||
module.exports.dependencies = ["TestToken", "Verifier"]
|
||||
@ -1,36 +0,0 @@
|
||||
const MINTED_TOKENS = 1_000_000_000_000_000
|
||||
|
||||
module.exports = async ({
|
||||
deployments,
|
||||
getNamedAccounts,
|
||||
getUnnamedAccounts,
|
||||
network,
|
||||
}) => {
|
||||
const { deployer } = await getNamedAccounts()
|
||||
const tokenDeployment = await deployments.deploy("TestToken", {
|
||||
from: deployer,
|
||||
skipIfAlreadyDeployed: true,
|
||||
})
|
||||
const token = await hre.ethers.getContractAt(
|
||||
"TestToken",
|
||||
tokenDeployment.address
|
||||
)
|
||||
|
||||
const accounts = [
|
||||
...Object.values(await getNamedAccounts()),
|
||||
...(await getUnnamedAccounts()),
|
||||
]
|
||||
if (network.tags.local) {
|
||||
for (const account of accounts) {
|
||||
console.log(`Minting ${MINTED_TOKENS} tokens to address ${account}`)
|
||||
|
||||
const transaction = await token.mint(account, MINTED_TOKENS, {
|
||||
from: deployer,
|
||||
})
|
||||
await transaction.wait()
|
||||
}
|
||||
console.log()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.tags = ["TestToken"]
|
||||
@ -1,24 +0,0 @@
|
||||
const { loadVerificationKey } = require("../verifier/verifier.js")
|
||||
|
||||
async function deployVerifier({ deployments, getNamedAccounts }) {
|
||||
const { deployer } = await getNamedAccounts()
|
||||
const verificationKey = loadVerificationKey(network.name)
|
||||
await deployments.deploy("Groth16Verifier", {
|
||||
args: [verificationKey],
|
||||
from: deployer,
|
||||
})
|
||||
}
|
||||
|
||||
async function deployTestVerifier({ network, deployments, getNamedAccounts }) {
|
||||
if (network.tags.local) {
|
||||
const { deployer } = await getNamedAccounts()
|
||||
await deployments.deploy("TestVerifier", { from: deployer })
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = async (environment) => {
|
||||
await deployVerifier(environment)
|
||||
await deployTestVerifier(environment)
|
||||
}
|
||||
|
||||
module.exports.tags = ["Verifier"]
|
||||
2
deployments/.gitignore
vendored
2
deployments/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
localhost
|
||||
codexdisttestnetwork
|
||||
@ -1 +0,0 @@
|
||||
789987
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
1660990954
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
167005
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,6 +1,5 @@
|
||||
require("@nomiclabs/hardhat-waffle")
|
||||
require("hardhat-deploy")
|
||||
require("hardhat-deploy-ethers")
|
||||
require("@nomicfoundation/hardhat-toolbox")
|
||||
require("@nomicfoundation/hardhat-ignition-ethers")
|
||||
|
||||
module.exports = {
|
||||
solidity: {
|
||||
@ -25,6 +24,10 @@ module.exports = {
|
||||
hardhat: {
|
||||
tags: ["local"],
|
||||
allowBlocksWithSameTimestamp: true,
|
||||
gas: "auto",
|
||||
},
|
||||
localhost: {
|
||||
tags: ["local"],
|
||||
},
|
||||
codexdisttestnetwork: {
|
||||
url: `${process.env.DISTTEST_NETWORK_URL}`,
|
||||
|
||||
33
ignition/README.md
Normal file
33
ignition/README.md
Normal file
@ -0,0 +1,33 @@
|
||||
# Deployment
|
||||
|
||||
Hardhat Ignition is now used to deploy the contracts, so the old
|
||||
deployment files are no longer relevant.
|
||||
|
||||
However, the ABI of the contracts has changed due to an OpenZeppelin update.
|
||||
If we ever need to recreate the artifacts from the previous ABI contracts (for any reason),
|
||||
we can do so using a small script that imports the previously generated files.
|
||||
Here is an example:
|
||||
|
||||
```js
|
||||
module.exports = buildModule("Token", (m) => {
|
||||
const previousJsonFile = path.join(__dirname, "./TestToken.json");
|
||||
const artifact = JSON.parse(fs.readFileSync(previousJsonFile, "utf8"));
|
||||
const address = artifact.address;
|
||||
const token = m.contractAt("TestToken", address, {});
|
||||
return { token };
|
||||
});
|
||||
```
|
||||
|
||||
Then we can run:
|
||||
|
||||
```bash
|
||||
npx hardhat ignition deploy ignition/modules/migration/token.js --network taiko_test
|
||||
```
|
||||
|
||||
**Note:** Check [this comment](https://github.com/codex-storage/codex-contracts-eth/pull/231#issuecomment-2808996517) for more context.
|
||||
|
||||
Here is the list of previous commits containing the ABI contracts that were deployed:
|
||||
|
||||
- [Taiko](https://github.com/codex-storage/codex-contracts-eth/commit/1854dfba9991a25532de5f6a53cf50e66afb3c8b)
|
||||
- [Testnet](https://github.com/codex-storage/codex-contracts-eth/commit/449d64ffc0dc1478d0690d36f037358084a17b09)
|
||||
- [Linea](https://github.com/codex-storage/codex-contracts-eth/pull/226/commits/2dddc260152b6e9c24ae372397f9b9b2d27ce8e4)
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"Token#TestToken": "0x34a22f3911De437307c6f4485931779670f78764",
|
||||
"Verifier#Groth16Verifier": "0x1f60B2329775545AaeF743dbC3571e699405263e",
|
||||
"Marketplace#Marketplace": "0xDB2908d724a15d05c0B6B8e8441a8b36E67476d3"
|
||||
}
|
||||
9
ignition/modules/endian.js
Normal file
9
ignition/modules/endian.js
Normal file
@ -0,0 +1,9 @@
|
||||
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules")
|
||||
|
||||
module.exports = buildModule("Endian", (m) => {
|
||||
const endian = m.contract("Endian", [], {})
|
||||
|
||||
const testEndian = m.contract("TestEndian", [], {})
|
||||
|
||||
return { endian, testEndian }
|
||||
})
|
||||
43
ignition/modules/marketplace.js
Normal file
43
ignition/modules/marketplace.js
Normal file
@ -0,0 +1,43 @@
|
||||
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules")
|
||||
const { loadZkeyHash } = require("../../verifier/verifier.js")
|
||||
const { loadConfiguration } = require("../../configuration/configuration.js")
|
||||
const TokenModule = require("./token.js")
|
||||
const VerifierModule = require("./verifier.js")
|
||||
|
||||
function getDefaultConfig() {
|
||||
const zkeyHash = loadZkeyHash(hre.network.name)
|
||||
const config = loadConfiguration(hre.network.name)
|
||||
config.proofs.zkeyHash = zkeyHash
|
||||
return config
|
||||
}
|
||||
|
||||
module.exports = buildModule("Marketplace", (m) => {
|
||||
const { token } = m.useModule(TokenModule)
|
||||
const { verifier } = m.useModule(VerifierModule)
|
||||
const configuration = m.getParameter("configuration", getDefaultConfig())
|
||||
|
||||
const marketplace = m.contract(
|
||||
"Marketplace",
|
||||
[configuration, token, verifier],
|
||||
{},
|
||||
)
|
||||
|
||||
let testMarketplace
|
||||
const config = hre.network.config
|
||||
|
||||
if (config && config.tags && config.tags.includes("local")) {
|
||||
const { testVerifier } = m.useModule(VerifierModule)
|
||||
|
||||
testMarketplace = m.contract(
|
||||
"TestMarketplace",
|
||||
[configuration, token, testVerifier],
|
||||
{},
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
marketplace,
|
||||
testMarketplace,
|
||||
token,
|
||||
}
|
||||
})
|
||||
9
ignition/modules/periods.js
Normal file
9
ignition/modules/periods.js
Normal file
@ -0,0 +1,9 @@
|
||||
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules")
|
||||
|
||||
module.exports = buildModule("Periods", (m) => {
|
||||
const secondsPerPeriod = m.getParameter("secondsPerPeriod", 0)
|
||||
|
||||
const periods = m.contract("Periods", [secondsPerPeriod], {})
|
||||
|
||||
return { periods }
|
||||
})
|
||||
11
ignition/modules/proofs.js
Normal file
11
ignition/modules/proofs.js
Normal file
@ -0,0 +1,11 @@
|
||||
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules")
|
||||
const VerifierModule = require("./verifier.js")
|
||||
|
||||
module.exports = buildModule("Proofs", (m) => {
|
||||
const { verifier } = m.useModule(VerifierModule)
|
||||
const configuration = m.getParameter("configuration", null)
|
||||
|
||||
const testProofs = m.contract("TestProofs", [configuration, verifier], {})
|
||||
|
||||
return { testProofs }
|
||||
})
|
||||
13
ignition/modules/slot-reservations.js
Normal file
13
ignition/modules/slot-reservations.js
Normal file
@ -0,0 +1,13 @@
|
||||
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules")
|
||||
|
||||
module.exports = buildModule("SlotReservations", (m) => {
|
||||
const configuration = m.getParameter("configuration", null)
|
||||
|
||||
const testSlotReservations = m.contract(
|
||||
"TestSlotReservations",
|
||||
[configuration],
|
||||
{},
|
||||
)
|
||||
|
||||
return { testSlotReservations }
|
||||
})
|
||||
31
ignition/modules/token.js
Normal file
31
ignition/modules/token.js
Normal file
@ -0,0 +1,31 @@
|
||||
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules")
|
||||
|
||||
const MAX_ACCOUNTS = 20
|
||||
const MINTED_TOKENS = 1_000_000_000_000_000n
|
||||
|
||||
module.exports = buildModule("Token", (m) => {
|
||||
let token
|
||||
|
||||
if (process.env.TOKEN_ADDRESS) {
|
||||
console.log(
|
||||
"Using existing TestToken on address: ",
|
||||
process.env.TOKEN_ADDRESS,
|
||||
)
|
||||
token = m.contractAt("TestToken", process.env.TOKEN_ADDRESS, {})
|
||||
} else {
|
||||
token = m.contract("TestToken", [], {})
|
||||
}
|
||||
|
||||
const config = hre.network.config
|
||||
|
||||
if (config && config.tags && config.tags.includes("local")) {
|
||||
for (let i = 0; i < MAX_ACCOUNTS; i++) {
|
||||
const account = m.getAccount(i)
|
||||
m.call(token, "mint", [account, MINTED_TOKENS], {
|
||||
id: `SendingTestTokens_${i}`,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return { token }
|
||||
})
|
||||
10
ignition/modules/vault.js
Normal file
10
ignition/modules/vault.js
Normal file
@ -0,0 +1,10 @@
|
||||
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules")
|
||||
const TokenModule = require("./token.js")
|
||||
|
||||
module.exports = buildModule("Vault", (m) => {
|
||||
const { token } = m.useModule(TokenModule)
|
||||
|
||||
const vault = m.contract("Vault", [token], {})
|
||||
|
||||
return { vault, token }
|
||||
})
|
||||
11
ignition/modules/verifier.js
Normal file
11
ignition/modules/verifier.js
Normal file
@ -0,0 +1,11 @@
|
||||
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules")
|
||||
const { loadVerificationKey } = require("../../verifier/verifier.js")
|
||||
|
||||
module.exports = buildModule("Verifier", (m) => {
|
||||
const verificationKey = loadVerificationKey(hre.network.name)
|
||||
const verifier = m.contract("Groth16Verifier", [verificationKey], {})
|
||||
|
||||
const testVerifier = m.contract("TestVerifier", [], {})
|
||||
|
||||
return { verifier, testVerifier }
|
||||
})
|
||||
36014
package-lock.json
generated
36014
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
36
package.json
36
package.json
@ -4,29 +4,31 @@
|
||||
"scripts": {
|
||||
"test": "npm run lint && hardhat test",
|
||||
"fuzz": "hardhat compile && fuzzing/fuzz.sh",
|
||||
"start": "hardhat node --export deployment-localhost.json",
|
||||
"start": "concurrently --names \"hardhat,deployment\" --prefix \"[{time} {name}]\" \"hardhat node\" \"sleep 2 && npm run mine && npm run deploy -- --network localhost\"",
|
||||
"compile": "hardhat compile",
|
||||
"format": "prettier --write contracts/*.sol contracts/**/*.sol test/**/*.js",
|
||||
"format:check": "prettier --check contracts/*.sol contracts/**/*.sol test/**/*.js",
|
||||
"format": "prettier --write test/**/*.js --plugin=prettier-plugin-solidity contracts/**/*.sol ",
|
||||
"format:check": "prettier --check test/**/*.js --plugin=prettier-plugin-solidity contracts/**/*.sol",
|
||||
"lint": "solhint contracts/**.sol",
|
||||
"deploy": "hardhat deploy",
|
||||
"deploy": "hardhat ignition deploy ignition/modules/marketplace.js",
|
||||
"mine": "hardhat run scripts/mine.js --network localhost",
|
||||
"verify": "npm run verify:marketplace && npm run verify:state_changes",
|
||||
"verify:marketplace": "certoraRun certora/confs/Marketplace.conf",
|
||||
"verify:state_changes": "certoraRun certora/confs/StateChanges.conf"
|
||||
"verify:state_changes": "certoraRun certora/confs/StateChanges.conf",
|
||||
"coverage": "hardhat coverage",
|
||||
"gas:report": "REPORT_GAS=true hardhat test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nomiclabs/hardhat-ethers": "^2.2.1",
|
||||
"@nomiclabs/hardhat-waffle": "^2.0.3",
|
||||
"@openzeppelin/contracts": "^5.3.0",
|
||||
"@stdlib/stats-binomial-test": "^0.0.7",
|
||||
"chai": "^4.3.7",
|
||||
"ethereum-waffle": "^3.4.4",
|
||||
"ethers": "^5.7.2",
|
||||
"hardhat": "^2.24.2",
|
||||
"hardhat-deploy": "^0.11.34",
|
||||
"hardhat-deploy-ethers": "^0.3.0-beta.13",
|
||||
"prettier": "^2.8.2",
|
||||
"prettier-plugin-solidity": "^1.4.2",
|
||||
"solhint": "^5.0.5"
|
||||
"@nomicfoundation/hardhat-chai-matchers": "^2.0.8",
|
||||
"@nomicfoundation/hardhat-ignition-ethers": "^0.15.11",
|
||||
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
|
||||
"@stdlib/stats-binomial-test": "^0.2.2",
|
||||
"chai": "^4.5.0",
|
||||
"ethers": "6.14.4",
|
||||
"hardhat": "^2.24.3",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-solidity": "^1.4.3",
|
||||
"solhint": "^5.1.0",
|
||||
"concurrently": "^9.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
7
scripts/mine.js
Normal file
7
scripts/mine.js
Normal file
@ -0,0 +1,7 @@
|
||||
const { mine } = require("@nomicfoundation/hardhat-network-helpers")
|
||||
|
||||
async function main() {
|
||||
await mine(256)
|
||||
}
|
||||
|
||||
main().catch(console.error)
|
||||
@ -1,5 +1,5 @@
|
||||
const { expect } = require("chai")
|
||||
const { ethers } = require("hardhat")
|
||||
const EndianModule = require("../ignition/modules/endian")
|
||||
|
||||
describe("Endian", function () {
|
||||
const big =
|
||||
@ -10,8 +10,8 @@ describe("Endian", function () {
|
||||
let endian
|
||||
|
||||
beforeEach(async function () {
|
||||
let Endian = await ethers.getContractFactory("TestEndian")
|
||||
endian = await Endian.deploy()
|
||||
const { testEndian } = await ignition.deploy(EndianModule)
|
||||
endian = testEndian
|
||||
})
|
||||
|
||||
it("converts from little endian to big endian", async function () {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,16 +1,32 @@
|
||||
const { expect } = require("chai")
|
||||
const { ethers } = require("hardhat")
|
||||
const PeriodsModule = require("../ignition/modules/periods")
|
||||
const { assertDeploymentRejectedWithCustomError } = require("./helpers")
|
||||
|
||||
describe("Periods", function () {
|
||||
it("should revert when secondsPerPeriod is 0", async function () {
|
||||
const PeriodsContract = await ethers.getContractFactory("Periods")
|
||||
await expect(PeriodsContract.deploy(0)).to.be.revertedWith(
|
||||
"Periods_InvalidSecondsPerPeriod"
|
||||
const promise = ignition.deploy(PeriodsModule, {
|
||||
parameters: {
|
||||
Periods: {
|
||||
secondsPerPeriod: 0,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
assertDeploymentRejectedWithCustomError(
|
||||
"Periods_InvalidSecondsPerPeriod",
|
||||
promise,
|
||||
)
|
||||
})
|
||||
|
||||
it("should not revert when secondsPerPeriod more than 0", async function () {
|
||||
const PeriodsContract = await ethers.getContractFactory("Periods")
|
||||
await expect(PeriodsContract.deploy(10)).not.to.be.reverted
|
||||
const promise = ignition.deploy(PeriodsModule, {
|
||||
parameters: {
|
||||
Periods: {
|
||||
secondsPerPeriod: 10,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
await expect(promise).not.to.be.rejected
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,20 +1,21 @@
|
||||
const { expect } = require("chai")
|
||||
const { ethers, deployments } = require("hardhat")
|
||||
const { hexlify, randomBytes } = ethers.utils
|
||||
const { ethers } = require("hardhat")
|
||||
const { hexlify, randomBytes } = ethers
|
||||
const {
|
||||
snapshot,
|
||||
revert,
|
||||
mine,
|
||||
ensureMinimumBlockHeight,
|
||||
currentTime,
|
||||
advanceTime,
|
||||
advanceTimeTo,
|
||||
mine,
|
||||
} = require("./evm")
|
||||
const { periodic } = require("./time")
|
||||
const { loadProof, loadPublicInput } = require("../verifier/verifier")
|
||||
const { SlotState } = require("./requests")
|
||||
const binomialTest = require("@stdlib/stats-binomial-test")
|
||||
const { exampleProof } = require("./examples")
|
||||
const ProofsModule = require("../ignition/modules/proofs")
|
||||
|
||||
describe("Proofs", function () {
|
||||
const slotId = hexlify(randomBytes(32))
|
||||
@ -30,13 +31,22 @@ describe("Proofs", function () {
|
||||
beforeEach(async function () {
|
||||
await snapshot()
|
||||
await ensureMinimumBlockHeight(256)
|
||||
const Proofs = await ethers.getContractFactory("TestProofs")
|
||||
await deployments.fixture(["Verifier"])
|
||||
const verifier = await deployments.get("Groth16Verifier")
|
||||
proofs = await Proofs.deploy(
|
||||
{ period, timeout, downtime, zkeyHash: "", downtimeProduct },
|
||||
verifier.address
|
||||
)
|
||||
|
||||
const { testProofs } = await ignition.deploy(ProofsModule, {
|
||||
parameters: {
|
||||
Proofs: {
|
||||
configuration: {
|
||||
period,
|
||||
timeout,
|
||||
downtime,
|
||||
zkeyHash: "",
|
||||
downtimeProduct,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
proofs = testProofs
|
||||
})
|
||||
|
||||
afterEach(async function () {
|
||||
@ -113,7 +123,7 @@ describe("Proofs", function () {
|
||||
let previous = await proofs.getPointer(slotId)
|
||||
await mine()
|
||||
let current = await proofs.getPointer(slotId)
|
||||
expect(current).to.equal((previous + 1) % 256)
|
||||
expect(current).to.equal((previous + 1n) % 256n)
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -202,15 +212,15 @@ describe("Proofs", function () {
|
||||
it("fails proof submission when proof is incorrect", async function () {
|
||||
let invalid = exampleProof()
|
||||
await expect(
|
||||
proofs.proofReceived(slotId, invalid, pubSignals)
|
||||
).to.be.revertedWith("Proofs_InvalidProof")
|
||||
proofs.proofReceived(slotId, invalid, pubSignals),
|
||||
).to.be.revertedWithCustomError(proofs, "Proofs_InvalidProof")
|
||||
})
|
||||
|
||||
it("fails proof submission when public input is incorrect", async function () {
|
||||
let invalid = [1, 2, 3]
|
||||
await expect(
|
||||
proofs.proofReceived(slotId, proof, invalid)
|
||||
).to.be.revertedWith("Proofs_InvalidProof")
|
||||
proofs.proofReceived(slotId, proof, invalid),
|
||||
).to.be.revertedWithCustomError(proofs, "Proofs_InvalidProof")
|
||||
})
|
||||
|
||||
it("emits an event when proof was submitted", async function () {
|
||||
@ -222,8 +232,8 @@ describe("Proofs", function () {
|
||||
it("fails proof submission when already submitted", async function () {
|
||||
await proofs.proofReceived(slotId, proof, pubSignals)
|
||||
await expect(
|
||||
proofs.proofReceived(slotId, proof, pubSignals)
|
||||
).to.be.revertedWith("Proofs_ProofAlreadySubmitted")
|
||||
proofs.proofReceived(slotId, proof, pubSignals),
|
||||
).to.be.revertedWithCustomError(proofs, "Proofs_ProofAlreadySubmitted")
|
||||
})
|
||||
|
||||
it("marks a proof as missing", async function () {
|
||||
@ -239,8 +249,8 @@ describe("Proofs", function () {
|
||||
await waitUntilProofIsRequired(slotId)
|
||||
let currentPeriod = periodOf(await currentTime())
|
||||
await expect(
|
||||
proofs.markProofAsMissing(slotId, currentPeriod)
|
||||
).to.be.revertedWith("Proofs_PeriodNotEnded")
|
||||
proofs.markProofAsMissing(slotId, currentPeriod),
|
||||
).to.be.revertedWithCustomError(proofs, "Proofs_PeriodNotEnded")
|
||||
})
|
||||
|
||||
it("does not mark a proof as missing after timeout", async function () {
|
||||
@ -248,8 +258,8 @@ describe("Proofs", function () {
|
||||
let currentPeriod = periodOf(await currentTime())
|
||||
await advanceTimeTo(periodEnd(currentPeriod) + timeout + 1)
|
||||
await expect(
|
||||
proofs.markProofAsMissing(slotId, currentPeriod)
|
||||
).to.be.revertedWith("Proofs_ValidationTimedOut")
|
||||
proofs.markProofAsMissing(slotId, currentPeriod),
|
||||
).to.be.revertedWithCustomError(proofs, "Proofs_ValidationTimedOut")
|
||||
})
|
||||
|
||||
it("does not mark a received proof as missing", async function () {
|
||||
@ -258,8 +268,8 @@ describe("Proofs", function () {
|
||||
await proofs.proofReceived(slotId, proof, pubSignals)
|
||||
await advanceTimeTo(periodEnd(receivedPeriod) + 1)
|
||||
await expect(
|
||||
proofs.markProofAsMissing(slotId, receivedPeriod)
|
||||
).to.be.revertedWith("Proofs_ProofNotMissing")
|
||||
proofs.markProofAsMissing(slotId, receivedPeriod),
|
||||
).to.be.revertedWithCustomError(proofs, "Proofs_ProofNotMissing")
|
||||
})
|
||||
|
||||
it("does not mark proof as missing when not required", async function () {
|
||||
@ -269,8 +279,8 @@ describe("Proofs", function () {
|
||||
let currentPeriod = periodOf(await currentTime())
|
||||
await advanceTimeTo(periodEnd(currentPeriod) + 1)
|
||||
await expect(
|
||||
proofs.markProofAsMissing(slotId, currentPeriod)
|
||||
).to.be.revertedWith("Proofs_ProofNotRequired")
|
||||
proofs.markProofAsMissing(slotId, currentPeriod),
|
||||
).to.be.revertedWithCustomError(proofs, "Proofs_ProofNotRequired")
|
||||
})
|
||||
|
||||
it("does not mark proof as missing twice", async function () {
|
||||
@ -279,8 +289,11 @@ describe("Proofs", function () {
|
||||
await advanceTimeTo(periodEnd(missedPeriod) + 1)
|
||||
await proofs.markProofAsMissing(slotId, missedPeriod)
|
||||
await expect(
|
||||
proofs.markProofAsMissing(slotId, missedPeriod)
|
||||
).to.be.revertedWith("Proofs_ProofAlreadyMarkedMissing")
|
||||
proofs.markProofAsMissing(slotId, missedPeriod),
|
||||
).to.be.revertedWithCustomError(
|
||||
proofs,
|
||||
"Proofs_ProofAlreadyMarkedMissing",
|
||||
)
|
||||
})
|
||||
|
||||
it("requires no proofs when slot is finished", async function () {
|
||||
|
||||
@ -3,6 +3,7 @@ const { ethers } = require("hardhat")
|
||||
const { exampleRequest, exampleConfiguration } = require("./examples")
|
||||
const { requestId, slotId } = require("./ids")
|
||||
const { SlotState } = require("./requests")
|
||||
const SlotReservationsModule = require("../ignition/modules/slot-reservations")
|
||||
|
||||
describe("SlotReservations", function () {
|
||||
let reservations
|
||||
@ -15,10 +16,18 @@ describe("SlotReservations", function () {
|
||||
const config = exampleConfiguration()
|
||||
|
||||
beforeEach(async function () {
|
||||
let SlotReservations = await ethers.getContractFactory(
|
||||
"TestSlotReservations"
|
||||
const { testSlotReservations } = await ignition.deploy(
|
||||
SlotReservationsModule,
|
||||
{
|
||||
parameters: {
|
||||
SlotReservations: {
|
||||
configuration: config.reservations,
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
reservations = await SlotReservations.deploy(config.reservations)
|
||||
|
||||
reservations = testSlotReservations
|
||||
;[provider, address1, address2, address3] = await ethers.getSigners()
|
||||
|
||||
request = await exampleRequest()
|
||||
@ -76,8 +85,11 @@ describe("SlotReservations", function () {
|
||||
|
||||
it("cannot reserve a slot more than once", async function () {
|
||||
await reservations.reserveSlot(reqId, slotIndex)
|
||||
await expect(reservations.reserveSlot(reqId, slotIndex)).to.be.revertedWith(
|
||||
"SlotReservations_ReservationNotAllowed"
|
||||
await expect(
|
||||
reservations.reserveSlot(reqId, slotIndex),
|
||||
).to.be.revertedWithCustomError(
|
||||
reservations,
|
||||
"SlotReservations_ReservationNotAllowed",
|
||||
)
|
||||
expect(await reservations.length(id)).to.equal(1)
|
||||
})
|
||||
@ -95,8 +107,11 @@ describe("SlotReservations", function () {
|
||||
switchAccount(address3)
|
||||
await reservations.reserveSlot(reqId, slotIndex)
|
||||
switchAccount(provider)
|
||||
await expect(reservations.reserveSlot(reqId, slotIndex)).to.be.revertedWith(
|
||||
"SlotReservations_ReservationNotAllowed"
|
||||
await expect(
|
||||
reservations.reserveSlot(reqId, slotIndex),
|
||||
).to.be.revertedWithCustomError(
|
||||
reservations,
|
||||
"SlotReservations_ReservationNotAllowed",
|
||||
)
|
||||
expect(await reservations.length(id)).to.equal(3)
|
||||
expect(await reservations.contains(id, provider.address)).to.be.false
|
||||
@ -115,8 +130,11 @@ describe("SlotReservations", function () {
|
||||
|
||||
it("cannot reserve a slot if not free or not in repair", async function () {
|
||||
await reservations.setSlotState(id, SlotState.Filled)
|
||||
await expect(reservations.reserveSlot(reqId, slotIndex)).to.be.revertedWith(
|
||||
"SlotReservations_ReservationNotAllowed"
|
||||
await expect(
|
||||
reservations.reserveSlot(reqId, slotIndex),
|
||||
).to.be.revertedWithCustomError(
|
||||
reservations,
|
||||
"SlotReservations_ReservationNotAllowed",
|
||||
)
|
||||
expect(await reservations.length(id)).to.equal(0)
|
||||
})
|
||||
@ -139,7 +157,7 @@ describe("SlotReservations", function () {
|
||||
it("should not emit an event when reservations are not full", async function () {
|
||||
await expect(reservations.reserveSlot(reqId, slotIndex)).to.not.emit(
|
||||
reservations,
|
||||
"SlotReservationsFull"
|
||||
"SlotReservationsFull",
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
53
test/evm.js
53
test/evm.js
@ -1,23 +1,27 @@
|
||||
const { ethers } = require("hardhat")
|
||||
const {
|
||||
time,
|
||||
mine,
|
||||
takeSnapshot,
|
||||
} = require("@nomicfoundation/hardhat-network-helpers")
|
||||
const hre = require("hardhat")
|
||||
const provider = hre.network.provider
|
||||
|
||||
let snapshots = []
|
||||
const snapshots = []
|
||||
|
||||
async function snapshot() {
|
||||
const id = await ethers.provider.send("evm_snapshot")
|
||||
const snapshot = await takeSnapshot()
|
||||
const time = await currentTime()
|
||||
const automine = await ethers.provider.send("hardhat_getAutomine")
|
||||
snapshots.push({ id, time, automine })
|
||||
const automine = await provider.send("hardhat_getAutomine")
|
||||
snapshots.push({ snapshot, automine, time })
|
||||
}
|
||||
|
||||
async function revert() {
|
||||
const { id, time, automine } = snapshots.pop()
|
||||
await ethers.provider.send("evm_revert", [id])
|
||||
|
||||
const current = await currentTime()
|
||||
const nextTime = Math.max(time + 1, current + 1)
|
||||
|
||||
await ethers.provider.send("evm_setNextBlockTimestamp", [nextTime])
|
||||
await ethers.provider.send("evm_setAutomine", [automine])
|
||||
const { snapshot, time, automine } = snapshots.pop()
|
||||
if (snapshot) {
|
||||
await snapshot.restore()
|
||||
await setNextBlockTimestamp(time)
|
||||
await provider.send("evm_setAutomine", [automine])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -26,38 +30,33 @@ async function revert() {
|
||||
* When automine mode is disabled, transactions that revert are silently ignored!
|
||||
*/
|
||||
async function setAutomine(enabled) {
|
||||
await ethers.provider.send("evm_setAutomine", [enabled])
|
||||
}
|
||||
|
||||
async function mine() {
|
||||
await ethers.provider.send("evm_mine")
|
||||
await provider.send("evm_setAutomine", [enabled])
|
||||
}
|
||||
|
||||
async function ensureMinimumBlockHeight(height) {
|
||||
while ((await ethers.provider.getBlockNumber()) < height) {
|
||||
while ((await time.latestBlock()) < height) {
|
||||
await mine()
|
||||
}
|
||||
}
|
||||
|
||||
async function setNextBlockTimestamp(timestamp) {
|
||||
return time.setNextBlockTimestamp(timestamp)
|
||||
}
|
||||
|
||||
async function currentTime() {
|
||||
let block = await ethers.provider.getBlock("latest")
|
||||
return block.timestamp
|
||||
return time.latest()
|
||||
}
|
||||
|
||||
async function advanceTime(seconds) {
|
||||
await ethers.provider.send("evm_increaseTime", [seconds])
|
||||
await time.increase(seconds)
|
||||
await mine()
|
||||
}
|
||||
|
||||
async function advanceTimeTo(timestamp) {
|
||||
await setNextBlockTimestamp(timestamp)
|
||||
await time.setNextBlockTimestamp(timestamp)
|
||||
await mine()
|
||||
}
|
||||
|
||||
async function setNextBlockTimestamp(timestamp) {
|
||||
await ethers.provider.send("evm_setNextBlockTimestamp", [timestamp])
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
snapshot,
|
||||
revert,
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
const { ethers } = require("hardhat")
|
||||
const { hours } = require("./time")
|
||||
const { hexlify, randomBytes } = ethers.utils
|
||||
const { hexlify, randomBytes } = require("hardhat").ethers
|
||||
|
||||
const exampleConfiguration = () => ({
|
||||
collateral: {
|
||||
@ -36,7 +35,7 @@ const exampleRequest = async () => {
|
||||
},
|
||||
content: {
|
||||
cid: Buffer.from("zb2rhheVmk3bLks5MgzTqyznLu1zqGH5jrfTA1eAZXrjx7Vob"),
|
||||
merkleRoot: Array.from(randomBytes(32)),
|
||||
merkleRoot: randomBytes(32),
|
||||
},
|
||||
expiry: hours(1),
|
||||
nonce: hexlify(randomBytes(32)),
|
||||
|
||||
15
test/helpers.js
Normal file
15
test/helpers.js
Normal file
@ -0,0 +1,15 @@
|
||||
module.exports = {
|
||||
assertDeploymentRejectedWithCustomError: async function (
|
||||
customError,
|
||||
deploymentPromise,
|
||||
) {
|
||||
const error = await expect(deploymentPromise).to.be.rejected
|
||||
|
||||
expect(error)
|
||||
.to.have.property("message")
|
||||
.that.contains(
|
||||
customError,
|
||||
`Expected error ${expectedError}, but got ${error.message}`,
|
||||
)
|
||||
},
|
||||
}
|
||||
@ -1,12 +1,11 @@
|
||||
const { ethers } = require("hardhat")
|
||||
const { keccak256, defaultAbiCoder } = ethers.utils
|
||||
const { keccak256, AbiCoder } = require("hardhat").ethers
|
||||
|
||||
function requestId(request) {
|
||||
const Ask = "tuple(uint256, uint256, uint256, uint64, uint64, uint64, int64)"
|
||||
const Content = "tuple(bytes, bytes32)"
|
||||
const Request =
|
||||
"tuple(address, " + Ask + ", " + Content + ", uint64, bytes32)"
|
||||
return keccak256(defaultAbiCoder.encode([Request], requestToArray(request)))
|
||||
return keccak256(new AbiCoder().encode([Request], requestToArray(request)))
|
||||
}
|
||||
|
||||
function askToArray(ask) {
|
||||
@ -40,7 +39,7 @@ function requestToArray(request) {
|
||||
function slotId(slot) {
|
||||
const types = "tuple(bytes32, uint256)"
|
||||
const values = [slot.request, slot.index]
|
||||
const encoding = defaultAbiCoder.encode([types], [values])
|
||||
const encoding = new AbiCoder().encode([types], [values])
|
||||
return keccak256(encoding)
|
||||
}
|
||||
|
||||
|
||||
@ -4,16 +4,16 @@ const { payoutForDuration } = require("./price")
|
||||
const { collateralPerSlot } = require("./collateral")
|
||||
|
||||
async function waitUntilCancelled(contract, request) {
|
||||
const expiry = (await contract.requestExpiry(requestId(request))).toNumber()
|
||||
const expiry = await contract.requestExpiry(requestId(request))
|
||||
// We do +1, because the expiry check in contract is done as `>` and not `>=`.
|
||||
await advanceTimeTo(expiry + 1)
|
||||
return advanceTimeTo(expiry + 1n)
|
||||
}
|
||||
|
||||
async function waitUntilSlotsFilled(contract, request, proof, token, slots) {
|
||||
let collateral = collateralPerSlot(request)
|
||||
await token.approve(contract.address, collateral * slots.length)
|
||||
await token.approve(await contract.getAddress(), collateral * slots.length)
|
||||
|
||||
let requestEnd = (await contract.requestEnd(requestId(request))).toNumber()
|
||||
let requestEnd = await contract.requestEnd(requestId(request))
|
||||
const payouts = []
|
||||
for (let slotIndex of slots) {
|
||||
await contract.reserveSlot(requestId(request), slotIndex)
|
||||
@ -22,7 +22,7 @@ async function waitUntilSlotsFilled(contract, request, proof, token, slots) {
|
||||
payouts[slotIndex] = payoutForDuration(
|
||||
request,
|
||||
await currentTime(),
|
||||
requestEnd
|
||||
requestEnd,
|
||||
)
|
||||
}
|
||||
|
||||
@ -35,14 +35,14 @@ async function waitUntilStarted(contract, request, proof, token) {
|
||||
request,
|
||||
proof,
|
||||
token,
|
||||
Array.from({ length: request.ask.slots }, (_, i) => i)
|
||||
Array.from({ length: request.ask.slots }, (_, i) => i),
|
||||
)
|
||||
}
|
||||
|
||||
async function waitUntilFinished(contract, requestId) {
|
||||
const end = (await contract.requestEnd(requestId)).toNumber()
|
||||
const end = await contract.requestEnd(requestId)
|
||||
// We do +1, because the end check in contract is done as `>` and not `>=`.
|
||||
await advanceTimeTo(end + 1)
|
||||
await advanceTimeTo(end + 1n)
|
||||
}
|
||||
|
||||
async function waitUntilFailed(contract, request) {
|
||||
@ -72,7 +72,7 @@ function patchOverloads(contract) {
|
||||
if (logicalXor(rewardRecipient, collateralRecipient)) {
|
||||
// XOR, if exactly one is truthy
|
||||
throw new Error(
|
||||
"Invalid freeSlot overload, you must specify both `rewardRecipient` and `collateralRecipient` or neither."
|
||||
"Invalid freeSlot overload, you must specify both `rewardRecipient` and `collateralRecipient` or neither.",
|
||||
)
|
||||
}
|
||||
|
||||
@ -96,6 +96,11 @@ function patchOverloads(contract) {
|
||||
}
|
||||
}
|
||||
|
||||
function littleEndianToBigInt(littleEndian) {
|
||||
const buffer = Buffer.from(littleEndian)
|
||||
return BigInt(`0x${buffer.toString("hex")}`)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
waitUntilCancelled,
|
||||
waitUntilStarted,
|
||||
@ -104,4 +109,5 @@ module.exports = {
|
||||
waitUntilFailed,
|
||||
waitUntilSlotFailed,
|
||||
patchOverloads,
|
||||
littleEndianToBigInt,
|
||||
}
|
||||
|
||||
@ -9,7 +9,21 @@ function maxPrice(request) {
|
||||
}
|
||||
|
||||
function payoutForDuration(request, start, end) {
|
||||
return (end - start) * pricePerSlotPerSecond(request)
|
||||
return (Number(end) - Number(start)) * pricePerSlotPerSecond(request)
|
||||
}
|
||||
|
||||
module.exports = { maxPrice, pricePerSlotPerSecond, payoutForDuration }
|
||||
function calculatePartialPayout(request, expiresAt, filledAt) {
|
||||
return (Number(expiresAt) - Number(filledAt)) * pricePerSlotPerSecond(request)
|
||||
}
|
||||
|
||||
function calculateBalance(balance, reward) {
|
||||
return BigInt(balance) + BigInt(reward)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
maxPrice,
|
||||
pricePerSlotPerSecond,
|
||||
payoutForDuration,
|
||||
calculatePartialPayout,
|
||||
calculateBalance,
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
const { Assertion } = require("chai")
|
||||
const { currentTime } = require("./evm")
|
||||
|
||||
const RequestState = {
|
||||
New: 0,
|
||||
@ -10,13 +9,13 @@ const RequestState = {
|
||||
}
|
||||
|
||||
const SlotState = {
|
||||
Free: 0,
|
||||
Filled: 1,
|
||||
Finished: 2,
|
||||
Failed: 3,
|
||||
Paid: 4,
|
||||
Cancelled: 5,
|
||||
Repair: 6,
|
||||
Free: 0n,
|
||||
Filled: 1n,
|
||||
Finished: 2n,
|
||||
Failed: 3n,
|
||||
Paid: 4n,
|
||||
Cancelled: 5n,
|
||||
Repair: 6n,
|
||||
}
|
||||
|
||||
function enableRequestAssertions() {
|
||||
@ -29,21 +28,21 @@ function enableRequestAssertions() {
|
||||
"expected request #{this} to have client #{exp} but got #{act}",
|
||||
"expected request #{this} to not have client #{act}, expected #{exp}",
|
||||
request.client, // expected
|
||||
actual.client // actual
|
||||
actual.client, // actual
|
||||
)
|
||||
this.assert(
|
||||
actual.expiry == request.expiry,
|
||||
"expected request #{this} to have expiry #{exp} but got #{act}",
|
||||
"expected request #{this} to not have expiry #{act}, expected #{exp}",
|
||||
request.expiry, // expected
|
||||
actual.expiry // actual
|
||||
actual.expiry, // actual
|
||||
)
|
||||
this.assert(
|
||||
actual.nonce === request.nonce,
|
||||
"expected request #{this} to have nonce #{exp} but got #{act}",
|
||||
"expected request #{this} to not have nonce #{act}, expected #{exp}",
|
||||
request.nonce, // expected
|
||||
actual.nonce // actual
|
||||
actual.nonce, // actual
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
28
verifier/networks/localhost/example-proof/proof.json
Normal file
28
verifier/networks/localhost/example-proof/proof.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"pi_a": [
|
||||
"6534256117371673392078914918983405561950705741555607896616281548993166767050",
|
||||
"4683704071819826577549511087725295557628226569657977399743888281350488008160",
|
||||
"1"
|
||||
],
|
||||
"pi_b": [
|
||||
[
|
||||
"5214601005301447749408976517903523691026761713935248596363525026084207179898",
|
||||
"12928862018496028019248584699701543976607635004280021323367162829172676142063"
|
||||
],
|
||||
[
|
||||
"6802359022534661924490571652741723715650845080843101596088257121470226373081",
|
||||
"13026065833109947056007317243769626467054545801812125911606045634450472294131"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"pi_c": [
|
||||
"4064922718155280187684708354118623661512911161238889435233679092743470899962",
|
||||
"16109406845320108508342512724551388830826795687369147885401665396548555026064",
|
||||
"1"
|
||||
],
|
||||
"protocol": "groth16",
|
||||
"curve": "bn128"
|
||||
}
|
||||
5
verifier/networks/localhost/example-proof/public.json
Normal file
5
verifier/networks/localhost/example-proof/public.json
Normal file
@ -0,0 +1,5 @@
|
||||
[
|
||||
"10941033813",
|
||||
"16074246370508166450132968585287196391860062495017081813239200574579640171677",
|
||||
"3"
|
||||
]
|
||||
4
verifier/networks/localhost/proof_main.circom
Normal file
4
verifier/networks/localhost/proof_main.circom
Normal file
@ -0,0 +1,4 @@
|
||||
pragma circom 2.0.0;
|
||||
include "sample_cells.circom";
|
||||
// SampleAndProven( maxDepth, maxLog2NSlots, blockTreeDepth, nFieldElemsPerCell, nSamples )
|
||||
component main {public [entropy,dataSetRoot,slotIndex]} = SampleAndProve(32, 8, 5, 67, 5);
|
||||
BIN
verifier/networks/localhost/proof_main.r1cs
Normal file
BIN
verifier/networks/localhost/proof_main.r1cs
Normal file
Binary file not shown.
BIN
verifier/networks/localhost/proof_main.wasm
Normal file
BIN
verifier/networks/localhost/proof_main.wasm
Normal file
Binary file not shown.
BIN
verifier/networks/localhost/proof_main.zkey
Normal file
BIN
verifier/networks/localhost/proof_main.zkey
Normal file
Binary file not shown.
104
verifier/networks/localhost/proof_main_verification_key.json
Normal file
104
verifier/networks/localhost/proof_main_verification_key.json
Normal file
@ -0,0 +1,104 @@
|
||||
{
|
||||
"protocol": "groth16",
|
||||
"curve": "bn128",
|
||||
"nPublic": 3,
|
||||
"vk_alpha_1": [
|
||||
"20491192805390485299153009773594534940189261866228447918068658471970481763042",
|
||||
"9383485363053290200918347156157836566562967994039712273449902621266178545958",
|
||||
"1"
|
||||
],
|
||||
"vk_beta_2": [
|
||||
[
|
||||
"6375614351688725206403948262868962793625744043794305715222011528459656738731",
|
||||
"4252822878758300859123897981450591353533073413197771768651442665752259397132"
|
||||
],
|
||||
[
|
||||
"10505242626370262277552901082094356697409835680220590971873171140371331206856",
|
||||
"21847035105528745403288232691147584728191162732299865338377159692350059136679"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_gamma_2": [
|
||||
[
|
||||
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
|
||||
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
|
||||
],
|
||||
[
|
||||
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
|
||||
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_delta_2": [
|
||||
[
|
||||
"3431611495862121747865613070227194870328323956412989443038622984801922101560",
|
||||
"1839332345901382467668376261123176838724068493614256702976446713083234015641"
|
||||
],
|
||||
[
|
||||
"4267694917739299737209021244200092851467599237028086467255985366439671917679",
|
||||
"14005704598922119245150389324584568926199987543485693236347173598336567030859"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_alphabeta_12": [
|
||||
[
|
||||
[
|
||||
"2029413683389138792403550203267699914886160938906632433982220835551125967885",
|
||||
"21072700047562757817161031222997517981543347628379360635925549008442030252106"
|
||||
],
|
||||
[
|
||||
"5940354580057074848093997050200682056184807770593307860589430076672439820312",
|
||||
"12156638873931618554171829126792193045421052652279363021382169897324752428276"
|
||||
],
|
||||
[
|
||||
"7898200236362823042373859371574133993780991612861777490112507062703164551277",
|
||||
"7074218545237549455313236346927434013100842096812539264420499035217050630853"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"7077479683546002997211712695946002074877511277312570035766170199895071832130",
|
||||
"10093483419865920389913245021038182291233451549023025229112148274109565435465"
|
||||
],
|
||||
[
|
||||
"4595479056700221319381530156280926371456704509942304414423590385166031118820",
|
||||
"19831328484489333784475432780421641293929726139240675179672856274388269393268"
|
||||
],
|
||||
[
|
||||
"11934129596455521040620786944827826205713621633706285934057045369193958244500",
|
||||
"8037395052364110730298837004334506829870972346962140206007064471173334027475"
|
||||
]
|
||||
]
|
||||
],
|
||||
"IC": [
|
||||
[
|
||||
"11919420103024546168896650006162652130022732573970705849225139177428442519914",
|
||||
"17747753383929265689844293401689552935018333420134132157824903795680624926572",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"13158415194355348546090070151711085027834066488127676886518524272551654481129",
|
||||
"18831701962118195025265682681702066674741422770850028135520336928884612556978",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"20882269691461568155321689204947751047717828445545223718893788782534717197527",
|
||||
"11996193054822748526485644723594571195813487505803351159052936325857690315211",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"18155166643053044822201627105588517913195535693446564472247126736722594445000",
|
||||
"13816319482622393060406816684195314200198627617641073470088058848129378231754",
|
||||
"1"
|
||||
]
|
||||
]
|
||||
}
|
||||
1
verifier/networks/localhost/zkey_hash.json
Normal file
1
verifier/networks/localhost/zkey_hash.json
Normal file
@ -0,0 +1 @@
|
||||
"65dfa139e1c6dae5f50102cca2a856b759723c6ec6029343c2c6e926b855a6ca"
|
||||
Loading…
x
Reference in New Issue
Block a user