From 291a544693308306d93c4d68e201425926c66967 Mon Sep 17 00:00:00 2001 From: Yondon Fu Date: Mon, 15 Jan 2018 15:09:12 -0500 Subject: [PATCH 1/2] Inflation change and verifier solver setters. Tweak initial parameters --- contracts/token/Minter.sol | 9 +++++ contracts/verification/LivepeerVerifier.sol | 8 ++++ migrations/migrations.config.js | 20 +++++----- test/integration/Delegation.js | 12 +++--- test/unit/Minter.js | 13 ++++++ truffle.js | 5 +-- verification_test/LivepeerVerifier.js | 44 +++++++++++++++------ 7 files changed, 81 insertions(+), 30 deletions(-) diff --git a/contracts/token/Minter.sol b/contracts/token/Minter.sol index ebda74cd..e19ab1b8 100644 --- a/contracts/token/Minter.sol +++ b/contracts/token/Minter.sol @@ -67,6 +67,15 @@ contract Minter is Manager, IMinter { ParameterUpdate("targetBondingRate"); } + function setInflationChange(uint256 _inflationChange) external onlyControllerOwner { + // Must be valid percentage + require(MathUtils.validPerc(_inflationChange)); + + inflationChange = _inflationChange; + + ParameterUpdate("inflationChange"); + } + function transferTokenOwnership(address _newOwner) external onlyControllerOwner { livepeerToken().transferOwnership(_newOwner); } diff --git a/contracts/verification/LivepeerVerifier.sol b/contracts/verification/LivepeerVerifier.sol index 711d328b..7c74ebe8 100644 --- a/contracts/verification/LivepeerVerifier.sol +++ b/contracts/verification/LivepeerVerifier.sol @@ -55,6 +55,14 @@ contract LivepeerVerifier is Manager, IVerifier { verificationCodeHash = _verificationCodeHash; } + function addSolver(address _solver) external onlyControllerOwner { + // Must not already be a solver + require(!isSolver[_solver]); + + solvers.push(_solver); + isSolver[_solver] = true; + } + /* * @dev Fire VerifyRequest event which solvers should listen for to retrieve verification parameters */ diff --git a/migrations/migrations.config.js b/migrations/migrations.config.js index abab0a0c..dca76d5a 100644 --- a/migrations/migrations.config.js +++ b/migrations/migrations.config.js @@ -11,28 +11,28 @@ module.exports = { unbondingPeriod: 2 }, jobsManager: { - verificationRate: 1, + verificationRate: 100, verificationPeriod: 50, slashingPeriod: 50, - failedVerificationSlashAmount: 20 * PERC_MULTIPLIER, - missedVerificationSlashAmount: 30 * PERC_MULTIPLIER, - doubleClaimSegmentSlashAmount: 40 * PERC_MULTIPLIER, - finderFee: 4 * PERC_MULTIPLIER + failedVerificationSlashAmount: 1, + missedVerificationSlashAmount: .1 * PERC_MULTIPLIER, + doubleClaimSegmentSlashAmount: 3 * PERC_MULTIPLIER, + finderFee: 5 * PERC_MULTIPLIER }, roundsManager: { roundLength: 50, roundLockAmount: 100000 }, faucet: { - faucetAmount: new BigNumber(1000000000000000000000).mul(TOKEN_UNIT), - requestAmount: new BigNumber(1000000).mul(TOKEN_UNIT), + faucetAmount: new BigNumber(10000000).mul(TOKEN_UNIT), + requestAmount: new BigNumber(10).mul(TOKEN_UNIT), requestWait: 2, whitelist: [] }, minter: { - inflation: 26 * PERC_MULTIPLIER, - inflationChange: .02 * PERC_MULTIPLIER, - targetBondingRate: 50 * PERC_MULTIPLIER + inflation: .0137 * PERC_MULTIPLIER, + inflationChange: .001 * PERC_MULTIPLIER, + targetBondingRate: 10 * PERC_MULTIPLIER }, verifier: { verificationCodeHash: "QmZmvi1BaYSdxM1Tgwhi2mURabh46xCkzuH9PWeAkAZZGc", diff --git a/test/integration/Delegation.js b/test/integration/Delegation.js index e633c1e0..333eb813 100644 --- a/test/integration/Delegation.js +++ b/test/integration/Delegation.js @@ -51,7 +51,7 @@ contract("Delegation", accounts => { }) it("registers transcoder 1 that self bonds", async () => { - const amount = new BigNumber(10).mul(TOKEN_UNIT) + const amount = new BigNumber(1).mul(TOKEN_UNIT) await token.approve(bondingManager.address, amount, {from: transcoder1}) await bondingManager.bond(amount, transcoder1, {from: transcoder1}) await bondingManager.transcoder(10, 5, 100, {from: transcoder1}) @@ -60,7 +60,7 @@ contract("Delegation", accounts => { }) it("registers transcoder 2 that self bonds", async () => { - const amount = new BigNumber(10).mul(TOKEN_UNIT) + const amount = new BigNumber(1).mul(TOKEN_UNIT) await token.approve(bondingManager.address, amount, {from: transcoder2}) await bondingManager.bond(amount, transcoder2, {from: transcoder2}) await bondingManager.transcoder(10, 5, 100, {from: transcoder2}) @@ -69,7 +69,7 @@ contract("Delegation", accounts => { }) it("delegator 1 bonds to transcoder 1", async () => { - const amount = new BigNumber(10).mul(TOKEN_UNIT) + const amount = new BigNumber(1).mul(TOKEN_UNIT) await token.approve(bondingManager.address, amount, {from: delegator1}) await bondingManager.bond(amount, transcoder1, {from: delegator1}) @@ -78,7 +78,7 @@ contract("Delegation", accounts => { }) it("delegator 2 bonds to transcoder 1", async () => { - const amount = new BigNumber(10).mul(TOKEN_UNIT) + const amount = new BigNumber(1).mul(TOKEN_UNIT) await token.approve(bondingManager.address, amount, {from: delegator2}) await bondingManager.bond(amount, transcoder1, {from: delegator2}) @@ -89,8 +89,8 @@ contract("Delegation", accounts => { it("delegator 1 delegates to transcoder 2", async () => { await bondingManager.bond(0, transcoder2, {from: delegator1}) - const bond = (await bondingManager.getDelegator(delegator1))[2] - assert.equal(bond, transcoder2, "delegator 1 delegate incorrect") + const delegate = (await bondingManager.getDelegator(delegator1))[2] + assert.equal(delegate, transcoder2, "delegator 1 delegate incorrect") }) it("delegator 2 delegates to transcoder 2", async () => { diff --git a/test/unit/Minter.js b/test/unit/Minter.js index 25b1555a..8f6ccdeb 100644 --- a/test/unit/Minter.js +++ b/test/unit/Minter.js @@ -36,6 +36,19 @@ contract("Minter", accounts => { await fixture.tearDown() }) + describe("setInflationChange", () => { + it("should fail if not called by the Controller's owner", async () => { + await expectThrow(minter.setInflationChange(5, {from: accounts[4]})) + }) + + it("should set the inflation change", async () => { + await minter.setInflationChange(.1 * PERC_MULTIPLIER) + + const inflationChange = await minter.inflationChange.call() + assert.equal(inflationChange, .1 * PERC_MULTIPLIER, "wrong inflation change") + }) + }) + describe("createRewards", () => { it("should throw if sender is not bonding manager", async () => { await expectThrow(minter.createReward(10, 100)) diff --git a/truffle.js b/truffle.js index 31c2951b..ed8eea2c 100644 --- a/truffle.js +++ b/truffle.js @@ -28,11 +28,10 @@ module.exports = { gas: 6700000 }, lpTestNet: { - from: "0x0161e041aad467a890839d5b08b138c1e6373072", host: "localhost", port: 8545, - network_id: 777, - gas: 6700000 + network_id: 858585, + gas: 6600000 } }, solc: { diff --git a/verification_test/LivepeerVerifier.js b/verification_test/LivepeerVerifier.js index 97e561cc..5749357c 100644 --- a/verification_test/LivepeerVerifier.js +++ b/verification_test/LivepeerVerifier.js @@ -1,5 +1,7 @@ import Fixture from "../test/helpers/fixture" import expectThrow from "../test/helpers/expectThrow" +import ethUtil from "ethereumjs-util" +import ethAbi from "ethereumjs-abi" const LivepeerVerifier = artifacts.require("LivepeerVerifier") @@ -35,27 +37,44 @@ contract("LivepeerVerifier", accounts => { }) }) + describe("addSolver", () => { + it("should fail if solver is already whitelisted", async () => { + await expectThrow(verifier.addSolver(accounts[0])) + }) + + it("should whitelist a new solver", async () => { + await verifier.addSolver(accounts[3]) + + const isSolver = await verifier.isSolver.call(accounts[3]) + assert.isOk(isSolver, "did not whitelist new solver") + const solverAddress = await verifier.solvers.call(2) + assert.equal(solverAddress, accounts[3], "wrong solver address") + }) + }) + describe("verify", () => { const jobId = 0 const claimId = 0 const segmentNumber = 0 const transcodingOptions = "0x123" const dataStorageHash = "0x123" - const transcodedDataHash = web3.sha3("hello") + const dataHashes = [web3.sha3("apple"), web3.sha3("pear")] it("should fail if sender is not the JobsManager", async () => { - await expectThrow(verifier.verify(jobId, claimId, segmentNumber, transcodingOptions, dataStorageHash, transcodedDataHash)) + await expectThrow(verifier.verify(jobId, claimId, segmentNumber, transcodingOptions, dataStorageHash, dataHashes)) }) it("should store a request", async () => { - await fixture.jobsManager.setVerifyParams(jobId, claimId, segmentNumber, transcodingOptions, dataStorageHash, transcodedDataHash) + await fixture.jobsManager.setVerifyParams(jobId, claimId, segmentNumber, transcodingOptions, dataStorageHash, dataHashes) await fixture.jobsManager.callVerify() + const commitHash = ethUtil.bufferToHex(ethAbi.soliditySHA3(["bytes", "bytes"], [ethUtil.toBuffer(dataHashes[0]), ethUtil.toBuffer(dataHashes[1])])) + const request = await verifier.requests.call(0) assert.equal(request[0], jobId, "job id incorrect") assert.equal(request[1], claimId, "claim id incorrect") assert.equal(request[2], segmentNumber, "segment number incorrect") - assert.equal(request[3], transcodedDataHash, "transcoded data hash incorrect") + assert.equal(request[3], commitHash, "commit hash incorrect") }) it("should fire a VerifyRequest event", async () => { @@ -70,10 +89,11 @@ contract("LivepeerVerifier", accounts => { assert.equal(result.args.segmentNumber, segmentNumber, "event segmentNumber incorrect") assert.equal(result.args.transcodingOptions, transcodingOptions, "event transcodingOptions incorrect") assert.equal(result.args.dataStorageHash, dataStorageHash, "event dataStorageHash incorrect") - assert.equal(result.args.transcodedDataHash, transcodedDataHash, "event transcodedDataHash incorrect") + assert.equal(result.args.dataHash, dataHashes[0], "event dataHash incorrect") + assert.equal(result.args.transcodedDataHash, dataHashes[1], "event transcodedDataHash incorrect") }) - await fixture.jobsManager.setVerifyParams(jobId, claimId, segmentNumber, transcodingOptions, dataStorageHash, transcodedDataHash) + await fixture.jobsManager.setVerifyParams(jobId, claimId, segmentNumber, transcodingOptions, dataStorageHash, dataHashes) await fixture.jobsManager.callVerify() }) }) @@ -84,14 +104,14 @@ contract("LivepeerVerifier", accounts => { const segmentNumber = 0 const transcodingOptions = "0x123" const dataStorageHash = "0x123" - const transcodedDataHash = web3.sha3("hello") + const dataHashes = [web3.sha3("apple"), web3.sha3("pear")] it("should fail if sender is not a solver", async () => { await expectThrow(verifier.__callback(0, "0x123", {from: accounts[3]})) }) it("should fire a callback event with result set to true if verification succeeded", async () => { - await fixture.jobsManager.setVerifyParams(jobId, claimId, segmentNumber, transcodingOptions, dataStorageHash, transcodedDataHash) + await fixture.jobsManager.setVerifyParams(jobId, claimId, segmentNumber, transcodingOptions, dataStorageHash, dataHashes) await fixture.jobsManager.callVerify() let e = verifier.Callback({}) @@ -106,11 +126,12 @@ contract("LivepeerVerifier", accounts => { assert.equal(result.args.result, true, "callback result incorrect") }) - await verifier.__callback(0, web3.sha3("hello"), {from: accounts[0]}) + const commitHash = ethUtil.bufferToHex(ethAbi.soliditySHA3(["bytes", "bytes"], [ethUtil.toBuffer(dataHashes[0]), ethUtil.toBuffer(dataHashes[1])])) + await verifier.__callback(0, commitHash, {from: accounts[0]}) }) it("should fire a callback event with result set to false if verification failed", async () => { - await fixture.jobsManager.setVerifyParams(jobId, claimId, segmentNumber, transcodingOptions, dataStorageHash, transcodedDataHash) + await fixture.jobsManager.setVerifyParams(jobId, claimId, segmentNumber, transcodingOptions, dataStorageHash, dataHashes) await fixture.jobsManager.callVerify() let e = verifier.Callback({}) @@ -125,7 +146,8 @@ contract("LivepeerVerifier", accounts => { assert.equal(result.args.result, false, "callback result incorrect") }) - await verifier.__callback(0, web3.sha3("not hello"), {from: accounts[0]}) + const wrongCommitHash = ethUtil.bufferToHex(ethAbi.soliditySHA3(["bytes", "bytes"], [ethUtil.toBuffer(dataHashes[0]), ethUtil.toBuffer(web3.sha3("not pear"))])) + await verifier.__callback(0, wrongCommitHash, {from: accounts[0]}) }) }) }) From b09add65935ab5e6062022cd0416a9456c247827 Mon Sep 17 00:00:00 2001 From: Yondon Fu Date: Mon, 15 Jan 2018 15:50:46 -0500 Subject: [PATCH 2/2] Add check for null address in addSolver --- contracts/verification/LivepeerVerifier.sol | 2 ++ verification_test/LivepeerVerifier.js | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/contracts/verification/LivepeerVerifier.sol b/contracts/verification/LivepeerVerifier.sol index 7c74ebe8..dfd8399e 100644 --- a/contracts/verification/LivepeerVerifier.sol +++ b/contracts/verification/LivepeerVerifier.sol @@ -56,6 +56,8 @@ contract LivepeerVerifier is Manager, IVerifier { } function addSolver(address _solver) external onlyControllerOwner { + // Must not be null address + require(_solver != address(0)); // Must not already be a solver require(!isSolver[_solver]); diff --git a/verification_test/LivepeerVerifier.js b/verification_test/LivepeerVerifier.js index 5749357c..b73baa51 100644 --- a/verification_test/LivepeerVerifier.js +++ b/verification_test/LivepeerVerifier.js @@ -38,6 +38,10 @@ contract("LivepeerVerifier", accounts => { }) describe("addSolver", () => { + it("should fail for null address", async () => { + await expectThrow(verifier.addSolver("0x0")) + }) + it("should fail if solver is already whitelisted", async () => { await expectThrow(verifier.addSolver(accounts[0])) })