From bc4ee67e858a5fa7bdf16bb50981f2eb8b998731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Thu, 3 Oct 2019 13:27:51 +0300 Subject: [PATCH 01/19] store previous randomness values --- packages/protocol/contracts/identity/Random.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index 56badc66807..d26f09237ed 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -13,6 +13,8 @@ contract Random is IRandom { bytes32 public _random; + mapping (uint256 => bytes32) public history; + function initialize() external { } @@ -44,6 +46,7 @@ contract Random is IRandom { // add entropy _random = keccak256(abi.encodePacked(_random, randomness)); + history[block.number] = _random; commitments[proposer] = newCommitment; } From d75a4e6fa7a9e62694d7587070dc4e999b4be1af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Fri, 4 Oct 2019 22:36:46 +0300 Subject: [PATCH 02/19] limited size of history --- packages/protocol/contracts/identity/Random.sol | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index d26f09237ed..e16c4028cca 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -13,9 +13,12 @@ contract Random is IRandom { bytes32 public _random; - mapping (uint256 => bytes32) public history; + uint256 constant HISTORY_LENGTH = 256; + + bytes32[] private history; function initialize() external { + history.length = HISTORY_LENGTH; } /** @@ -46,7 +49,7 @@ contract Random is IRandom { // add entropy _random = keccak256(abi.encodePacked(_random, randomness)); - history[block.number] = _random; + history[block.number % HISTORY_LENGTH] = _random; commitments[proposer] = newCommitment; } @@ -58,4 +61,10 @@ contract Random is IRandom { function random() external view returns (bytes32) { return _random; } + + function getBlockRandomness(uint256 bn) external view returns (bytes32) { + require(bn <= block.number, "Cannot query randomness of future blocks"); + require(bn > block.number - HISTORY_LENGTH, "Cannot query randomness of old blocks"); + return history[bn % HISTORY_LENGTH]; + } } From 5ab9df2971214cc0c79fa35293d2a02ab73405c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Wed, 9 Oct 2019 15:03:16 +0300 Subject: [PATCH 03/19] this won't work --- .../protocol/contracts/identity/Random.sol | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index e16c4028cca..345fb5e2368 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -13,12 +13,21 @@ contract Random is IRandom { bytes32 public _random; - uint256 constant HISTORY_LENGTH = 256; + uint256 public randomnessBlockRetentionWindow = 256; - bytes32[] private history; + mapping (uint256 => bytes32) private history; + uint256 private historyFirst; + uint256 private historySize; function initialize() external { - history.length = HISTORY_LENGTH; + randomnessBlockRetentionWindow = 256; + history.length = randomnessBlockRetentionWindow; + } + + function setRandomnessBlockRetentionWindow(uint value) external { + historyIndex = (block.number - historyIndex) % ; + randomnessBlockRetentionWindow = value; + if (history.length < randomnessBlockRetentionWindow) history.length = randomnessBlockRetentionWindow; } /** @@ -37,7 +46,14 @@ contract Random is IRandom { address proposer ) external { require(msg.sender == address(0)); + _revealAndCommit(randomness, newCommitment, proposer); + } + function _revealAndCommit( + bytes32 randomness, + bytes32 newCommitment, + address proposer + ) internal { // ensure revealed randomness matches previous commitment if (commitments[proposer] != 0) { require(randomness != 0); @@ -48,12 +64,17 @@ contract Random is IRandom { } // add entropy - _random = keccak256(abi.encodePacked(_random, randomness)); - history[block.number % HISTORY_LENGTH] = _random; + addRandomness(keccak256(abi.encodePacked(_random, randomness))); + if (historySize < history.length) historySize++; commitments[proposer] = newCommitment; } + function addRandomness(bytes32 randomness) internal { + _random = randomness; + history[(block.number-historyIndex) % history.length] = randomness; + } + function computeCommitment(bytes32 randomness) public pure returns (bytes32) { return keccak256(abi.encodePacked(randomness)); } @@ -64,7 +85,7 @@ contract Random is IRandom { function getBlockRandomness(uint256 bn) external view returns (bytes32) { require(bn <= block.number, "Cannot query randomness of future blocks"); - require(bn > block.number - HISTORY_LENGTH, "Cannot query randomness of old blocks"); - return history[bn % HISTORY_LENGTH]; + require(bn > block.number - historySize, "Cannot query randomness of old blocks"); + return history[(bn-historyIndex) % history.length]; } } From e5b179484501096c5fb72153561f5a0c7b463c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Wed, 9 Oct 2019 16:05:46 +0300 Subject: [PATCH 04/19] added first tests --- .../protocol/contracts/identity/Random.sol | 40 ++++++-- .../contracts/identity/test/TestRandom.sol | 13 +++ packages/protocol/test/identity/random.ts | 96 +++++++++++++++++++ 3 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 packages/protocol/contracts/identity/test/TestRandom.sol create mode 100644 packages/protocol/test/identity/random.ts diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index 345fb5e2368..781cb886f00 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -21,13 +21,10 @@ contract Random is IRandom { function initialize() external { randomnessBlockRetentionWindow = 256; - history.length = randomnessBlockRetentionWindow; } function setRandomnessBlockRetentionWindow(uint value) external { - historyIndex = (block.number - historyIndex) % ; randomnessBlockRetentionWindow = value; - if (history.length < randomnessBlockRetentionWindow) history.length = randomnessBlockRetentionWindow; } /** @@ -64,15 +61,31 @@ contract Random is IRandom { } // add entropy - addRandomness(keccak256(abi.encodePacked(_random, randomness))); - if (historySize < history.length) historySize++; + addRandomness(block.number, keccak256(abi.encodePacked(_random, randomness))); commitments[proposer] = newCommitment; } - function addRandomness(bytes32 randomness) internal { + function addRandomness(uint bn, bytes32 randomness) internal { _random = randomness; - history[(block.number-historyIndex) % history.length] = randomness; + history[bn] = randomness; + if (historySize == 0) { + historyFirst = block.number; + historySize = 1; + } + else if (historySize > randomnessBlockRetentionWindow) { + delete history[historyFirst]; + delete history[historyFirst+1]; + historyFirst += 2; + historySize--; + } + else if (historySize == randomnessBlockRetentionWindow) { + delete history[historyFirst]; + historyFirst++; + } + else /* historySize < randomnessBlockRetentionWindow) */ { + historySize++; + } } function computeCommitment(bytes32 randomness) public pure returns (bytes32) { @@ -84,8 +97,15 @@ contract Random is IRandom { } function getBlockRandomness(uint256 bn) external view returns (bytes32) { - require(bn <= block.number, "Cannot query randomness of future blocks"); - require(bn > block.number - historySize, "Cannot query randomness of old blocks"); - return history[(bn-historyIndex) % history.length]; + return _getBlockRandomness(bn, block.number); + } + + function _getBlockRandomness(uint256 bn, uint256 cur) internal view returns (bytes32) { + require(bn <= cur, "Cannot query randomness of future blocks"); + require(bn > cur - historySize, "Cannot query randomness of old blocks"); + if (randomnessBlockRetentionWindow < cur) { + require(bn > cur - randomnessBlockRetentionWindow, "Cannot query randomness of old blocks"); + } + return history[bn]; } } diff --git a/packages/protocol/contracts/identity/test/TestRandom.sol b/packages/protocol/contracts/identity/test/TestRandom.sol new file mode 100644 index 00000000000..0245dd41242 --- /dev/null +++ b/packages/protocol/contracts/identity/test/TestRandom.sol @@ -0,0 +1,13 @@ +pragma solidity ^0.5.3; + +import "../Random.sol"; + +contract TestRandom is Random { + function testRandomness(uint bn, bytes32 randomness) external { + addRandomness(bn, randomness); + } + function getTestRandomness(uint bn, uint cur) external view returns (bytes32) { + return _getBlockRandomness(bn, cur); + } +} + diff --git a/packages/protocol/test/identity/random.ts b/packages/protocol/test/identity/random.ts new file mode 100644 index 00000000000..3fa42c76f53 --- /dev/null +++ b/packages/protocol/test/identity/random.ts @@ -0,0 +1,96 @@ +// import Web3 = require('web3') + +import { assertRevert } from '@celo/protocol/lib/test-utils' + +/* +import { CeloContractName } from '@celo/protocol/lib/registry-utils' +import { + assertLogMatches2, + assertRevert, + NULL_ADDRESS, + timeTravel, +} from '@celo/protocol/lib/test-utils' +import { attestToIdentifier } from '@celo/utils' +import { getPhoneHash } from '@celo/utils/lib/phoneNumbers' +import BigNumber from 'bignumber.js' +import { uniq } from 'lodash' +*/ +import { TestRandomContract, TestRandomInstance } from 'types' + +const Random: TestRandomContract = artifacts.require('TestRandom') + +contract('Random', (/* accounts: string[] */) => { + let random: TestRandomInstance + // const provider = new Web3.providers.HttpProvider('http://localhost:8545') + // const web3: Web3 = new Web3(provider) + + beforeEach(async () => { + random = await Random.new() + }) + + describe('#testRandomness', () => { + it('should be able to simulate adding randomness', async () => { + await random.testRandomness(1, '0x01') + await random.testRandomness(2, '0x02') + await random.testRandomness(3, '0x03') + await random.testRandomness(4, '0x04') + assert.equal( + '0x0100000000000000000000000000000000000000000000000000000000000000', + await random.getTestRandomness(1, 4) + ) + assert.equal( + '0x0200000000000000000000000000000000000000000000000000000000000000', + await random.getTestRandomness(2, 4) + ) + assert.equal( + '0x0300000000000000000000000000000000000000000000000000000000000000', + await random.getTestRandomness(3, 4) + ) + assert.equal( + '0x0400000000000000000000000000000000000000000000000000000000000000', + await random.getTestRandomness(4, 4) + ) + }) + + describe('when changing history smaller', () => { + beforeEach(async () => { + await random.testRandomness(1, '0x01') + await random.testRandomness(2, '0x02') + await random.testRandomness(3, '0x03') + await random.testRandomness(4, '0x04') + await random.setRandomnessBlockRetentionWindow(2) + }) + it('can still add randomness', async () => { + await random.testRandomness(5, '0x05') + assert.equal( + '0x0500000000000000000000000000000000000000000000000000000000000000', + await random.getTestRandomness(5, 5) + ) + }) + it('cannot read old blocks', async () => { + assertRevert(random.getTestRandomness(1, 5)) + }) + }) + + describe('when changing history larger', () => { + beforeEach(async () => { + await random.setRandomnessBlockRetentionWindow(2) + await random.testRandomness(1, '0x01') + await random.testRandomness(2, '0x02') + await random.testRandomness(3, '0x03') + await random.testRandomness(4, '0x04') + await random.setRandomnessBlockRetentionWindow(4) + }) + it('can still add randomness', async () => { + await random.testRandomness(5, '0x05') + assert.equal( + '0x0500000000000000000000000000000000000000000000000000000000000000', + await random.getTestRandomness(5, 5) + ) + }) + it('cannot read old blocks', async () => { + assertRevert(random.getTestRandomness(1, 5)) + }) + }) + }) +}) From 876259c1ab9f27a17df56b5a7c6c35317d3aa8de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Wed, 9 Oct 2019 16:14:23 +0300 Subject: [PATCH 05/19] cleanup --- packages/protocol/test/identity/random.ts | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/packages/protocol/test/identity/random.ts b/packages/protocol/test/identity/random.ts index 3fa42c76f53..9fa6e83ea81 100644 --- a/packages/protocol/test/identity/random.ts +++ b/packages/protocol/test/identity/random.ts @@ -1,28 +1,11 @@ -// import Web3 = require('web3') - import { assertRevert } from '@celo/protocol/lib/test-utils' -/* -import { CeloContractName } from '@celo/protocol/lib/registry-utils' -import { - assertLogMatches2, - assertRevert, - NULL_ADDRESS, - timeTravel, -} from '@celo/protocol/lib/test-utils' -import { attestToIdentifier } from '@celo/utils' -import { getPhoneHash } from '@celo/utils/lib/phoneNumbers' -import BigNumber from 'bignumber.js' -import { uniq } from 'lodash' -*/ import { TestRandomContract, TestRandomInstance } from 'types' const Random: TestRandomContract = artifacts.require('TestRandom') contract('Random', (/* accounts: string[] */) => { let random: TestRandomInstance - // const provider = new Web3.providers.HttpProvider('http://localhost:8545') - // const web3: Web3 = new Web3(provider) beforeEach(async () => { random = await Random.new() From 5ffe71665191437a965e3d599db38bc27d5a88da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Fri, 11 Oct 2019 09:44:02 +0300 Subject: [PATCH 06/19] review changes --- .../protocol/contracts/identity/Random.sol | 59 ++++++---- .../contracts/identity/test/TestRandom.sol | 8 +- packages/protocol/migrations/12_random.ts | 12 +- packages/protocol/migrations/16_governance.ts | 3 +- packages/protocol/migrationsConfig.js | 37 ++++--- packages/protocol/test/identity/random.ts | 104 +++++++++++------- 6 files changed, 138 insertions(+), 85 deletions(-) diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index 781cb886f00..e38d384d4c4 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -1,12 +1,17 @@ pragma solidity ^0.5.3; import "./interfaces/IRandom.sol"; +import "openzeppelin-solidity/contracts/math/SafeMath.sol"; +import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; +import "../common/Initializable.sol"; /** * @title Provides randomness for verifier selection */ -contract Random is IRandom { +contract Random is IRandom, Ownable, Initializable { + + using SafeMath for uint256; /* Stores most recent commitment per address */ mapping(address => bytes32) public commitments; @@ -19,12 +24,22 @@ contract Random is IRandom { uint256 private historyFirst; uint256 private historySize; - function initialize() external { - randomnessBlockRetentionWindow = 256; + event RandomnessBlockRetentionWindowSet(uint256 value); + + function initialize(uint256 _randomnessBlockRetentionWindow) external initializer { + _transferOwnership(msg.sender); + require(_randomnessBlockRetentionWindow > 0, "randomnessBlockRetetionWindow cannot be zero"); + randomnessBlockRetentionWindow = _randomnessBlockRetentionWindow; } - function setRandomnessBlockRetentionWindow(uint value) external { + /** + * @notice Sets the number of old random blocks whose randomness values can be queried. + * @param value Number of old random blocks whose randomness values can be queried. + */ + function setRandomnessBlockRetentionWindow(uint256 value) external onlyOwner { + require(value > 0, "randomnessBlockRetetionWindow cannot be zero"); randomnessBlockRetentionWindow = value; + emit RandomnessBlockRetentionWindowSet(value); } /** @@ -66,24 +81,21 @@ contract Random is IRandom { commitments[proposer] = newCommitment; } - function addRandomness(uint bn, bytes32 randomness) internal { + function addRandomness(uint blockNumber, bytes32 randomness) internal { _random = randomness; - history[bn] = randomness; + history[blockNumber] = randomness; if (historySize == 0) { historyFirst = block.number; historySize = 1; - } - else if (historySize > randomnessBlockRetentionWindow) { + } else if (historySize > randomnessBlockRetentionWindow) { delete history[historyFirst]; delete history[historyFirst+1]; historyFirst += 2; historySize--; - } - else if (historySize == randomnessBlockRetentionWindow) { + } else if (historySize == randomnessBlockRetentionWindow) { delete history[historyFirst]; historyFirst++; - } - else /* historySize < randomnessBlockRetentionWindow) */ { + } else /* historySize < randomnessBlockRetentionWindow) */ { historySize++; } } @@ -96,16 +108,21 @@ contract Random is IRandom { return _random; } - function getBlockRandomness(uint256 bn) external view returns (bytes32) { - return _getBlockRandomness(bn, block.number); + /** + * @notice Get randomness values of previous blocks. + * @param blockNumber The number of block whose randomness value we want to know. + */ + function getBlockRandomness(uint256 blockNumber) external view returns (bytes32) { + return _getBlockRandomness(blockNumber, block.number); } - function _getBlockRandomness(uint256 bn, uint256 cur) internal view returns (bytes32) { - require(bn <= cur, "Cannot query randomness of future blocks"); - require(bn > cur - historySize, "Cannot query randomness of old blocks"); - if (randomnessBlockRetentionWindow < cur) { - require(bn > cur - randomnessBlockRetentionWindow, "Cannot query randomness of old blocks"); - } - return history[bn]; + function _getBlockRandomness(uint256 blockNumber, uint256 cur) internal view returns (bytes32) { + require(blockNumber <= cur, "Cannot query randomness of future blocks"); + require( + blockNumber > cur.sub(historySize) && + (randomnessBlockRetentionWindow >= cur || + blockNumber > cur.sub(randomnessBlockRetentionWindow)), + "Cannot query randomness older than the stored history"); + return history[blockNumber]; } } diff --git a/packages/protocol/contracts/identity/test/TestRandom.sol b/packages/protocol/contracts/identity/test/TestRandom.sol index 0245dd41242..c80dafa0be2 100644 --- a/packages/protocol/contracts/identity/test/TestRandom.sol +++ b/packages/protocol/contracts/identity/test/TestRandom.sol @@ -3,11 +3,11 @@ pragma solidity ^0.5.3; import "../Random.sol"; contract TestRandom is Random { - function testRandomness(uint bn, bytes32 randomness) external { - addRandomness(bn, randomness); + function addTestRandomness(uint256 blockNumber, bytes32 randomness) external { + addRandomness(blockNumber, randomness); } - function getTestRandomness(uint bn, uint cur) external view returns (bytes32) { - return _getBlockRandomness(bn, cur); + function getTestRandomness(uint blockNumber, uint cur) external view returns (bytes32) { + return _getBlockRandomness(blockNumber, cur); } } diff --git a/packages/protocol/migrations/12_random.ts b/packages/protocol/migrations/12_random.ts index a1ef4117110..0069a349c9a 100644 --- a/packages/protocol/migrations/12_random.ts +++ b/packages/protocol/migrations/12_random.ts @@ -1,5 +1,15 @@ import { CeloContractName } from '@celo/protocol/lib/registry-utils' import { deploymentForCoreContract } from '@celo/protocol/lib/web3-utils' +import { config } from '@celo/protocol/migrationsConfig' import { RandomInstance } from 'types' -module.exports = deploymentForCoreContract(web3, artifacts, CeloContractName.Random) +const initializeArgs = async (_: string): Promise => { + return [config.random.randomnessBlockRetentionWindow] +} + +module.exports = deploymentForCoreContract( + web3, + artifacts, + CeloContractName.Random, + initializeArgs +) diff --git a/packages/protocol/migrations/16_governance.ts b/packages/protocol/migrations/16_governance.ts index 450d40a7438..fbe6b688afc 100644 --- a/packages/protocol/migrations/16_governance.ts +++ b/packages/protocol/migrations/16_governance.ts @@ -45,7 +45,7 @@ module.exports = deploymentForCoreContract( ) await reserve.addSpender(governance.address) - const proxyOwnedByGovernance = ['GoldToken', 'Random'] + const proxyOwnedByGovernance = ['GoldToken'] await Promise.all( proxyOwnedByGovernance.map((contractName) => transferOwnershipOfProxy(contractName, governance.address, artifacts) @@ -61,6 +61,7 @@ module.exports = deploymentForCoreContract( 'GasPriceMinimum', 'Governance', 'LockedGold', + 'Random', 'Registry', 'Reserve', 'SortedOracles', diff --git a/packages/protocol/migrationsConfig.js b/packages/protocol/migrationsConfig.js index 2e696aa4eec..71b62266d0c 100644 --- a/packages/protocol/migrationsConfig.js +++ b/packages/protocol/migrationsConfig.js @@ -11,11 +11,12 @@ const DefaultConfig = { attestationExpirySeconds: 60 * 60, // 1 hour, attestationRequestFeeInDollars: 0.05, }, - lockedGold: { - maxNoticePeriod: 60 * 60 * 24 * 365 * 3, // 3 years - }, - oracles: { - reportExpiry: 60 * 60, // 1 hour + blockchainParameters: { + minimumClientVersion: { + major: 1, + minor: 8, + patch: 23, + }, }, exchange: { spread: 5 / 1000, @@ -23,6 +24,12 @@ const DefaultConfig = { updateFrequency: 3600, minimumReports: 1, }, + gasPriceMinimum: { + initialMinimum: 10000, + targetDensity: 1 / 2, + adjustmentSpeed: 1 / 2, + proposerFraction: 1 / 2, + }, governance: { approvalStageDuration: 15 * 60, // 15 minutes concurrentProposals: 10, @@ -36,11 +43,14 @@ const DefaultConfig = { participationBaselineUpdateFactor: 1 / 5, participationBaselineQuorumFactor: 1, }, - gasPriceMinimum: { - initialMinimum: 10000, - targetDensity: 1 / 2, - adjustmentSpeed: 1 / 2, - proposerFraction: 1 / 2, + lockedGold: { + maxNoticePeriod: 60 * 60 * 24 * 365 * 3, // 3 years + }, + oracles: { + reportExpiry: 60 * 60, // 1 hour + }, + random: { + randomnessBlockRetentionWindow: 256, }, registry: { predeployedProxyAddress: '0x000000000000000000000000000000000000ce10', @@ -73,13 +83,6 @@ const DefaultConfig = { groupName: 'C-Labs', groupUrl: 'https://www.celo.org', }, - blockchainParameters: { - minimumClientVersion: { - major: 1, - minor: 8, - patch: 23, - }, - }, } const linkedLibraries = { diff --git a/packages/protocol/test/identity/random.ts b/packages/protocol/test/identity/random.ts index 9fa6e83ea81..72e3ce700f4 100644 --- a/packages/protocol/test/identity/random.ts +++ b/packages/protocol/test/identity/random.ts @@ -1,79 +1,101 @@ -import { assertRevert } from '@celo/protocol/lib/test-utils' +import { assertRevert, assertEqualBN, assertContainSubset } from '@celo/protocol/lib/test-utils' import { TestRandomContract, TestRandomInstance } from 'types' +import { BigNumber } from 'bignumber.js' const Random: TestRandomContract = artifacts.require('TestRandom') +// @ts-ignore +// TODO(mcortesi): Use BN +Random.numberFormat = 'BigNumber' + contract('Random', (/* accounts: string[] */) => { let random: TestRandomInstance beforeEach(async () => { random = await Random.new() + random.initialize(256) }) - describe('#testRandomness', () => { + describe('#setRandomnessRetentionWindow()', () => { + it('should set the variable', async () => { + await random.setRandomnessBlockRetentionWindow(1000) + assertEqualBN(new BigNumber(1000), await random.randomnessBlockRetentionWindow()) + }) + + it('should emit the event', async () => { + const response = await random.setRandomnessBlockRetentionWindow(1000) + assert.equal(response.logs.length, 1) + const log = response.logs[0] + assertContainSubset(log, { + event: 'RandomnessBlockRetentionWindowSet', + args: { + value: new BigNumber(1000), + }, + }) + }) + }) + + describe('#addTestRandomness', () => { + const randomValues = [ + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000000000000000000000000000002', + '0x0000000000000000000000000000000000000000000000000000000000000003', + '0x0000000000000000000000000000000000000000000000000000000000000004', + '0x0000000000000000000000000000000000000000000000000000000000000005', + '0x0000000000000000000000000000000000000000000000000000000000000006', + '0x0000000000000000000000000000000000000000000000000000000000000007', + ] it('should be able to simulate adding randomness', async () => { - await random.testRandomness(1, '0x01') - await random.testRandomness(2, '0x02') - await random.testRandomness(3, '0x03') - await random.testRandomness(4, '0x04') - assert.equal( - '0x0100000000000000000000000000000000000000000000000000000000000000', - await random.getTestRandomness(1, 4) - ) - assert.equal( - '0x0200000000000000000000000000000000000000000000000000000000000000', - await random.getTestRandomness(2, 4) - ) - assert.equal( - '0x0300000000000000000000000000000000000000000000000000000000000000', - await random.getTestRandomness(3, 4) - ) - assert.equal( - '0x0400000000000000000000000000000000000000000000000000000000000000', - await random.getTestRandomness(4, 4) - ) + await random.addTestRandomness(1, randomValues[1]) + await random.addTestRandomness(2, randomValues[2]) + await random.addTestRandomness(3, randomValues[3]) + await random.addTestRandomness(4, randomValues[4]) + assert.equal(randomValues[1], await random.getTestRandomness(1, 4)) + assert.equal(randomValues[2], await random.getTestRandomness(2, 4)) + assert.equal(randomValues[3], await random.getTestRandomness(3, 4)) + assert.equal(randomValues[4], await random.getTestRandomness(4, 4)) }) describe('when changing history smaller', () => { beforeEach(async () => { - await random.testRandomness(1, '0x01') - await random.testRandomness(2, '0x02') - await random.testRandomness(3, '0x03') - await random.testRandomness(4, '0x04') + await random.addTestRandomness(1, randomValues[1]) + await random.addTestRandomness(2, randomValues[2]) + await random.addTestRandomness(3, randomValues[3]) + await random.addTestRandomness(4, randomValues[4]) await random.setRandomnessBlockRetentionWindow(2) }) it('can still add randomness', async () => { - await random.testRandomness(5, '0x05') - assert.equal( - '0x0500000000000000000000000000000000000000000000000000000000000000', - await random.getTestRandomness(5, 5) - ) + await random.addTestRandomness(5, randomValues[5]) + assert.equal(randomValues[5], await random.getTestRandomness(5, 5)) }) it('cannot read old blocks', async () => { - assertRevert(random.getTestRandomness(1, 5)) + assertRevert(random.getTestRandomness(3, 5)) }) }) describe('when changing history larger', () => { beforeEach(async () => { await random.setRandomnessBlockRetentionWindow(2) - await random.testRandomness(1, '0x01') - await random.testRandomness(2, '0x02') - await random.testRandomness(3, '0x03') - await random.testRandomness(4, '0x04') + await random.addTestRandomness(1, randomValues[1]) + await random.addTestRandomness(2, randomValues[2]) + await random.addTestRandomness(3, randomValues[3]) + await random.addTestRandomness(4, randomValues[4]) await random.setRandomnessBlockRetentionWindow(4) }) it('can still add randomness', async () => { - await random.testRandomness(5, '0x05') - assert.equal( - '0x0500000000000000000000000000000000000000000000000000000000000000', - await random.getTestRandomness(5, 5) - ) + await random.addTestRandomness(5, randomValues[5]) + assert.equal(randomValues[5], await random.getTestRandomness(5, 5)) }) it('cannot read old blocks', async () => { assertRevert(random.getTestRandomness(1, 5)) }) + it('old values are preserved', async () => { + await random.addTestRandomness(5, randomValues[5]) + await random.addTestRandomness(6, randomValues[6]) + assert.equal(randomValues[3], await random.getTestRandomness(3, 6)) + }) }) }) }) From 0fb543a17cb1611de2326e83fc196f0294b7a0e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Fri, 11 Oct 2019 11:07:12 +0300 Subject: [PATCH 07/19] fixing lint --- packages/protocol/contracts/identity/Random.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index e38d384d4c4..29948532474 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -121,7 +121,7 @@ contract Random is IRandom, Ownable, Initializable { require( blockNumber > cur.sub(historySize) && (randomnessBlockRetentionWindow >= cur || - blockNumber > cur.sub(randomnessBlockRetentionWindow)), + blockNumber > cur.sub(randomnessBlockRetentionWindow)), "Cannot query randomness older than the stored history"); return history[blockNumber]; } From faf1ac389f889ea83849036347f353080089d723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Tue, 15 Oct 2019 20:16:39 +0300 Subject: [PATCH 08/19] remove _random, checking if something is broken --- packages/protocol/contracts/identity/Random.sol | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index 29948532474..da0e021142b 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -16,8 +16,6 @@ contract Random is IRandom, Ownable, Initializable { /* Stores most recent commitment per address */ mapping(address => bytes32) public commitments; - bytes32 public _random; - uint256 public randomnessBlockRetentionWindow = 256; mapping (uint256 => bytes32) private history; @@ -76,13 +74,12 @@ contract Random is IRandom, Ownable, Initializable { } // add entropy - addRandomness(block.number, keccak256(abi.encodePacked(_random, randomness))); + addRandomness(block.number, keccak256(abi.encodePacked(history[block.number-1], randomness))); commitments[proposer] = newCommitment; } function addRandomness(uint blockNumber, bytes32 randomness) internal { - _random = randomness; history[blockNumber] = randomness; if (historySize == 0) { historyFirst = block.number; @@ -105,7 +102,11 @@ contract Random is IRandom, Ownable, Initializable { } function random() external view returns (bytes32) { - return _random; + return _getBlockRandomness(block.number, block.number); + } + + function _random() external view returns (bytes32) { + return _getBlockRandomness(block.number, block.number); } /** From 4cadc871fd2ab051885e4c140d047195da10a13a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Tue, 15 Oct 2019 20:21:50 +0300 Subject: [PATCH 09/19] added require errors --- packages/protocol/contracts/identity/Random.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index da0e021142b..79346e01841 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -55,7 +55,7 @@ contract Random is IRandom, Ownable, Initializable { bytes32 newCommitment, address proposer ) external { - require(msg.sender == address(0)); + require(msg.sender == address(0), "only VM can call"); _revealAndCommit(randomness, newCommitment, proposer); } @@ -66,11 +66,11 @@ contract Random is IRandom, Ownable, Initializable { ) internal { // ensure revealed randomness matches previous commitment if (commitments[proposer] != 0) { - require(randomness != 0); + require(randomness != 0, "randomness cannot be zero if there is a previous commitment"); bytes32 expectedCommitment = computeCommitment(randomness); - require(expectedCommitment == commitments[proposer]); + require(expectedCommitment == commitments[proposer], "commitment didn't match the posted randomness"); } else { - require(randomness == 0); + require(randomness == 0, "randomness should be zero if there is no previous commitment"); } // add entropy From dd89be9a2cc8e61eb37c4316f8cb302309f81fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Tue, 15 Oct 2019 20:22:57 +0300 Subject: [PATCH 10/19] fixed lint --- packages/protocol/contracts/identity/Random.sol | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index 79346e01841..43d34bf9d3d 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -68,7 +68,10 @@ contract Random is IRandom, Ownable, Initializable { if (commitments[proposer] != 0) { require(randomness != 0, "randomness cannot be zero if there is a previous commitment"); bytes32 expectedCommitment = computeCommitment(randomness); - require(expectedCommitment == commitments[proposer], "commitment didn't match the posted randomness"); + require( + expectedCommitment == commitments[proposer], + "commitment didn't match the posted randomness" + ); } else { require(randomness == 0, "randomness should be zero if there is no previous commitment"); } From a4045cf38f1fcd02330364ee62f043a0d5c241b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Tue, 15 Oct 2019 20:41:16 +0300 Subject: [PATCH 11/19] bump --- packages/protocol/contracts/identity/Random.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index 43d34bf9d3d..e137b73a917 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -95,7 +95,7 @@ contract Random is IRandom, Ownable, Initializable { } else if (historySize == randomnessBlockRetentionWindow) { delete history[historyFirst]; historyFirst++; - } else /* historySize < randomnessBlockRetentionWindow) */ { + } else /* historySize < randomnessBlockRetentionWindow */ { historySize++; } } From 2862f3366903d66c2a34c7a40b85f37bfcc72311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Tue, 15 Oct 2019 21:12:40 +0300 Subject: [PATCH 12/19] bump --- packages/protocol/contracts/identity/Random.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index e137b73a917..2e8962e326d 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -77,7 +77,8 @@ contract Random is IRandom, Ownable, Initializable { } // add entropy - addRandomness(block.number, keccak256(abi.encodePacked(history[block.number-1], randomness))); + uint blockNumber = block.number == 0 ? 0 : block.number.sub(0); + addRandomness(block.number, keccak256(abi.encodePacked(history[blockNumber], randomness))); commitments[proposer] = newCommitment; } From 346a220ba5988d377069b004e33a3e3072bf6507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Tue, 15 Oct 2019 21:16:08 +0300 Subject: [PATCH 13/19] oops --- packages/protocol/contracts/identity/Random.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index 2e8962e326d..8e0f32bbd68 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -77,7 +77,7 @@ contract Random is IRandom, Ownable, Initializable { } // add entropy - uint blockNumber = block.number == 0 ? 0 : block.number.sub(0); + uint blockNumber = block.number == 0 ? 0 : block.number.sub(1); addRandomness(block.number, keccak256(abi.encodePacked(history[blockNumber], randomness))); commitments[proposer] = newCommitment; From 02a3c25a36f0b0e86be55064f69a16aef877a227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Tue, 15 Oct 2019 23:55:06 +0300 Subject: [PATCH 14/19] fixed tests --- packages/protocol/contracts/identity/Random.sol | 4 ---- packages/protocol/test/identity/attestations.ts | 9 +++++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index 8e0f32bbd68..fcb3ad929e2 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -109,10 +109,6 @@ contract Random is IRandom, Ownable, Initializable { return _getBlockRandomness(block.number, block.number); } - function _random() external view returns (bytes32) { - return _getBlockRandomness(block.number, block.number); - } - /** * @notice Get randomness values of previous blocks. * @param blockNumber The number of block whose randomness value we want to know. diff --git a/packages/protocol/test/identity/attestations.ts b/packages/protocol/test/identity/attestations.ts index d3d582d053e..ab86fd68baa 100644 --- a/packages/protocol/test/identity/attestations.ts +++ b/packages/protocol/test/identity/attestations.ts @@ -21,8 +21,8 @@ import { MockStableTokenInstance, MockValidatorsContract, MockValidatorsInstance, - RandomContract, - RandomInstance, + TestRandomContract, + TestRandomInstance, RegistryContract, RegistryInstance, } from 'types' @@ -32,7 +32,7 @@ const Attestations: AttestationsContract = artifacts.require('Attestations') const MockStableToken: MockStableTokenContract = artifacts.require('MockStableToken') const MockValidators: MockValidatorsContract = artifacts.require('MockValidators') const MockLockedGold: MockLockedGoldContract = artifacts.require('MockLockedGold') -const Random: RandomContract = artifacts.require('Random') +const Random: TestRandomContract = artifacts.require('TestRandom') const Registry: RegistryContract = artifacts.require('Registry') const dataEncryptionKey = '0x02f2f48ee19680706196e2e339e5da3491186e0c4c5030670656b0e01611111111' @@ -44,7 +44,7 @@ contract('Attestations', (accounts: string[]) => { let attestations: AttestationsInstance let mockStableToken: MockStableTokenInstance let otherMockStableToken: MockStableTokenInstance - let random: RandomInstance + let random: TestRandomInstance let mockValidators: MockValidatorsInstance let mockLockedGold: MockLockedGoldInstance let registry: RegistryInstance @@ -137,6 +137,7 @@ contract('Attestations', (accounts: string[]) => { otherMockStableToken = await MockStableToken.new() attestations = await Attestations.new() random = await Random.new() + random.addTestRandomness(0, '0x00') mockValidators = await MockValidators.new() await Promise.all( accounts.map((account) => mockValidators.addValidator(getValidatingKeyAddress(account))) From eabd05327692f1335c9e7bc540c90938b6d1afd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Fri, 18 Oct 2019 06:58:11 +0300 Subject: [PATCH 15/19] added comments --- .../protocol/contracts/identity/Random.sol | 42 ++++++++++++++++--- .../contracts/identity/test/TestRandom.sol | 2 +- packages/protocol/test/identity/random.ts | 6 ++- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index fcb3ad929e2..d3814affb04 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -24,17 +24,20 @@ contract Random is IRandom, Ownable, Initializable { event RandomnessBlockRetentionWindowSet(uint256 value); + /** + * @notice Initializes the contract with initial parameters. + * @param _randomnessBlockRetentionWindow Number of old random blocks whose randomness values can be queried. + */ function initialize(uint256 _randomnessBlockRetentionWindow) external initializer { _transferOwnership(msg.sender); - require(_randomnessBlockRetentionWindow > 0, "randomnessBlockRetetionWindow cannot be zero"); - randomnessBlockRetentionWindow = _randomnessBlockRetentionWindow; + setRandomnessBlockRetentionWindow(_randomnessBlockRetentionWindow); } /** * @notice Sets the number of old random blocks whose randomness values can be queried. * @param value Number of old random blocks whose randomness values can be queried. */ - function setRandomnessBlockRetentionWindow(uint256 value) external onlyOwner { + function setRandomnessBlockRetentionWindow(uint256 value) public onlyOwner { require(value > 0, "randomnessBlockRetetionWindow cannot be zero"); randomnessBlockRetentionWindow = value; emit RandomnessBlockRetentionWindowSet(value); @@ -59,6 +62,12 @@ contract Random is IRandom, Ownable, Initializable { _revealAndCommit(randomness, newCommitment, proposer); } + /** + * @notice Implements step of the randomness protocol. + * @param randomness Bytes that will be added to the entropy pool. + * @param newCommitment The hash of randomness that will be revealed in the future. + * @param proposer Address of the block proposer. + */ function _revealAndCommit( bytes32 randomness, bytes32 newCommitment, @@ -77,13 +86,20 @@ contract Random is IRandom, Ownable, Initializable { } // add entropy - uint blockNumber = block.number == 0 ? 0 : block.number.sub(1); + uint256 blockNumber = block.number == 0 ? 0 : block.number.sub(1); addRandomness(block.number, keccak256(abi.encodePacked(history[blockNumber], randomness))); commitments[proposer] = newCommitment; } - function addRandomness(uint blockNumber, bytes32 randomness) internal { + /** + * @notice Add a value to the randomness history. + * @param blockNumber Current block number. + * @param randomness The new randomness added to history. + * @dev The calls to this function should be made so that on the next call, blockNumber will + * be the previous one, incremented by one. + */ + function addRandomness(uint256 blockNumber, bytes32 randomness) internal { history[blockNumber] = randomness; if (historySize == 0) { historyFirst = block.number; @@ -101,10 +117,19 @@ contract Random is IRandom, Ownable, Initializable { } } + /** + * @notice Compute the commitment hash for a given randomness value. + * @param randomness The value for which the commitment hash is computed. + * @return Commitment parameter. + */ function computeCommitment(bytes32 randomness) public pure returns (bytes32) { return keccak256(abi.encodePacked(randomness)); } + /** + * @notice Querying the current randomness value. + * @return Returns the current randomness value. + */ function random() external view returns (bytes32) { return _getBlockRandomness(block.number, block.number); } @@ -112,11 +137,18 @@ contract Random is IRandom, Ownable, Initializable { /** * @notice Get randomness values of previous blocks. * @param blockNumber The number of block whose randomness value we want to know. + * @return The associated randomness value. */ function getBlockRandomness(uint256 blockNumber) external view returns (bytes32) { return _getBlockRandomness(blockNumber, block.number); } + /** + * @notice Get randomness values of previous blocks. + * @param blockNumber The number of block whose randomness value we want to know. + * @param cur Number of the current block. + * @return The associated randomness value. + */ function _getBlockRandomness(uint256 blockNumber, uint256 cur) internal view returns (bytes32) { require(blockNumber <= cur, "Cannot query randomness of future blocks"); require( diff --git a/packages/protocol/contracts/identity/test/TestRandom.sol b/packages/protocol/contracts/identity/test/TestRandom.sol index c80dafa0be2..8930cc9e145 100644 --- a/packages/protocol/contracts/identity/test/TestRandom.sol +++ b/packages/protocol/contracts/identity/test/TestRandom.sol @@ -6,7 +6,7 @@ contract TestRandom is Random { function addTestRandomness(uint256 blockNumber, bytes32 randomness) external { addRandomness(blockNumber, randomness); } - function getTestRandomness(uint blockNumber, uint cur) external view returns (bytes32) { + function getTestRandomness(uint256 blockNumber, uint256 cur) external view returns (bytes32) { return _getBlockRandomness(blockNumber, cur); } } diff --git a/packages/protocol/test/identity/random.ts b/packages/protocol/test/identity/random.ts index 72e3ce700f4..2ffca631849 100644 --- a/packages/protocol/test/identity/random.ts +++ b/packages/protocol/test/identity/random.ts @@ -9,7 +9,7 @@ const Random: TestRandomContract = artifacts.require('TestRandom') // TODO(mcortesi): Use BN Random.numberFormat = 'BigNumber' -contract('Random', (/* accounts: string[] */) => { +contract('Random', (accounts: string[]) => { let random: TestRandomInstance beforeEach(async () => { @@ -34,6 +34,10 @@ contract('Random', (/* accounts: string[] */) => { }, }) }) + + it('only owner can set', async () => { + assertRevert(random.setRandomnessBlockRetentionWindow(1000, { from: accounts[1] })) + }) }) describe('#addTestRandomness', () => { From 911e8a9245e9c50ad193f24e7fab08e37f3a5f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Fri, 18 Oct 2019 07:30:20 +0300 Subject: [PATCH 16/19] fixing lint --- packages/protocol/contracts/identity/Random.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/protocol/contracts/identity/Random.sol b/packages/protocol/contracts/identity/Random.sol index d3814affb04..cdc9e4afca6 100644 --- a/packages/protocol/contracts/identity/Random.sol +++ b/packages/protocol/contracts/identity/Random.sol @@ -26,7 +26,8 @@ contract Random is IRandom, Ownable, Initializable { /** * @notice Initializes the contract with initial parameters. - * @param _randomnessBlockRetentionWindow Number of old random blocks whose randomness values can be queried. + * @param _randomnessBlockRetentionWindow Number of old random blocks whose randomness + * values can be queried. */ function initialize(uint256 _randomnessBlockRetentionWindow) external initializer { _transferOwnership(msg.sender); From a4af20bc0e89d46fac1d24768af6478b664d021e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Fri, 18 Oct 2019 17:31:31 +0300 Subject: [PATCH 17/19] trying to remove some flakiness --- packages/protocol/test/stability/stabletoken.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/test/stability/stabletoken.ts b/packages/protocol/test/stability/stabletoken.ts index a78d5b3575c..b6c2c04b95a 100644 --- a/packages/protocol/test/stability/stabletoken.ts +++ b/packages/protocol/test/stability/stabletoken.ts @@ -28,7 +28,7 @@ contract('StableToken', (accounts: string[]) => { beforeEach(async () => { registry = await Registry.new() stableToken = await StableToken.new() - await stableToken.initialize( + const response = await stableToken.initialize( 'Celo Dollar', 'cUSD', 18, @@ -36,7 +36,7 @@ contract('StableToken', (accounts: string[]) => { fixed1, SECONDS_IN_A_WEEK ) - initializationTime = (await web3.eth.getBlock('latest')).timestamp + initializationTime = (await web3.eth.getBlock(response.receipt.blockNumber)).timestamp }) describe('#initialize()', () => { From 92eaeb6b435a77ae509c5fc2249289f6ea07725c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Fri, 18 Oct 2019 22:19:09 +0300 Subject: [PATCH 18/19] reverting changes From ec33e520c1a62d883edc3502fa8e675fe77bd10f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Fri, 18 Oct 2019 22:28:05 +0300 Subject: [PATCH 19/19] trying to reset --- README-dev.md | 20 ++++++++++---------- packages/mobile/README.md | 22 +++++++++++----------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/README-dev.md b/README-dev.md index 97d29247eae..e8587875919 100644 --- a/README-dev.md +++ b/README-dev.md @@ -4,10 +4,10 @@ Many packages depend on other packages within the monorepo. When this happens, follow these rules: -1. All packages must use **master version** of sibling packages. -2. Exception to (1) are packages that represent a GAE/firebase app which must use the last published version. -3. To differentiate published vs unpublished version. Master version (in package.json) must end with suffix `-dev` and should not be published. -4. If a developer want to publish a version; then after publishing it needs to set master version to next `-dev` version and change all package.json that require on it. + 1. All packages must use **master version** of sibling packages. + 2. Exception to (1) are packages that represent a GAE/firebase app which must use the last published version. + 3. To differentiate published vs unpublished version. Master version (in package.json) must end with suffix `-dev` and should not be published. + 4. If a developer want to publish a version; then after publishing it needs to set master version to next `-dev` version and change all package.json that require on it. To check which pakages need amending, you can run (in the root pkg): @@ -15,12 +15,12 @@ To check which pakages need amending, you can run (in the root pkg): A practical example: -- In any given moment, `contractkit/package.json#version` field **must** of the form `x.y.z-dev` -- If current version of contractkit is: `0.1.6-dev` and we want to publish a new version, we should: - - publish version `0.1.6` - - change `package.json#version` to `0.1.7-dev` - - change in other packages within monorepo that were using `0.1.6-dev` to `0.1.7-dev` - + * In any given moment, `contractkit/package.json#version` field **must** of the form `x.y.z-dev` + * If current version of contractkit is: `0.1.6-dev` and we want to publish a new version, we should: + * publish version `0.1.6` + * change `package.json#version` to `0.1.7-dev` + * change in other packages within monorepo that were using `0.1.6-dev` to `0.1.7-dev` + ## How to publish a new npm package First checkout the alfajores branch. diff --git a/packages/mobile/README.md b/packages/mobile/README.md index b0ee1074257..01eaff317a4 100644 --- a/packages/mobile/README.md +++ b/packages/mobile/README.md @@ -180,16 +180,16 @@ GraphQL queries. If you make a change to a query, run `yarn build:gen-graphql-ty By default, the mobile wallet app runs geth in ultralight sync mode where all the epoch headers are fetched. The default sync mode is defined in [packages/mobile/.env](https://github.com/celo-org/celo-monorepo/blob/master/packages/mobile/.env#L4) file. -# To run wallet in zero sync mode, where it would connect to the remote nodes and sign transactions in web3, change the default sync mode in the aforementioned file to -1. The mode has only been tested on Android and is hard-coded to be [crash](https://github.com/celo-org/celo-monorepo/blob/aeddeefbfb230db51d2ef76d50c5f882644a1cd3/packages/mobile/src/web3/contracts.ts#L73) on iOS. - +To run wallet in zero sync mode, where it would connect to the remote nodes and sign transactions in web3, change the default sync mode in the aforementioned file to -1. The mode has only been tested on Android and is hard-coded to be [crash](https://github.com/celo-org/celo-monorepo/blob/aeddeefbfb230db51d2ef76d50c5f882644a1cd3/packages/mobile/src/web3/contracts.ts#L73) on iOS. +======= ## How we handle Geth crashes in wallet app on Android Our Celo app has three types of codes. -1. Javascript code - generated from Typescript, this runs in Javascript interpreter. -2. Java bytecode - This runs on Dalvik/Art Virtual Machine. -3. Native code - Geth code is written in Golang which compiles to native code - this runs directly on the - CPU, no virtual machines involved. +1. Javascript code - generated from Typescript, this runs in Javascript interpreter. +2. Java bytecode - This runs on Dalvik/Art Virtual Machine. +3. Native code - Geth code is written in Golang which compiles to native code - this runs directly on the +CPU, no virtual machines involved. One should note that, on iOS, there is no byte code and therefore, there are only two layers, one is the Javascript code, and the other is the Native code. Till now, we have been blind towards native crashes except Google Playstore logs. @@ -199,14 +199,14 @@ We cannot use libraries like [Bugsnag](https://www.bugsnag.com) since they do no Relevant code references: -1. [NDKCrashService](https://github.com/celo-org/celo-monorepo/blob/master/packages/mobile/android/app/src/main/java/org/celo/mobile/NdkCrashService.java) -2. [Initialization](https://github.com/celo-org/celo-monorepo/blob/8689634a1d10d74ba6d4f3b36b2484db60a95bdb/packages/mobile/android/app/src/main/java/org/celo/mobile/MainApplication.java#L156) of the NDKCrashService -3. [Sentry code](https://github.com/celo-org/celo-monorepo/blob/799d74675dc09327543c210e88cbf5cc796721a0/packages/mobile/src/sentry/Sentry.ts#L53) to read NDK crash logs on restart +1. [NDKCrashService](https://github.com/celo-org/celo-monorepo/blob/master/packages/mobile/android/app/src/main/java/org/celo/mobile/NdkCrashService.java) +2. [Initialization](https://github.com/celo-org/celo-monorepo/blob/8689634a1d10d74ba6d4f3b36b2484db60a95bdb/packages/mobile/android/app/src/main/java/org/celo/mobile/MainApplication.java#L156) of the NDKCrashService +3. [Sentry code](https://github.com/celo-org/celo-monorepo/blob/799d74675dc09327543c210e88cbf5cc796721a0/packages/mobile/src/sentry/Sentry.ts#L53) to read NDK crash logs on restart There are two major differencs in ZeroSync mode: -1. Geth won't run at all. The web3 would instead connect to -infura.celo-testnet.org using an https provider, for example, [https://integration-infura.celo-testnet.org](https://integration-infura.celo-testnet.org). -2. Changes to [sendTransactionAsyncWithWeb3Signing](https://github.com/celo-org/celo-monorepo/blob/8689634a1d10d74ba6d4f3b36b2484db60a95bdb/packages/walletkit/src/contract-utils.ts#L362) in walletkit to poll after sending a transaction for the transaction to succeed. This is needed because http provider, unliked web sockets and IPC provider, does not support subscriptions. +1. Geth won't run at all. The web3 would instead connect to -infura.celo-testnet.org using an https provider, for example, [https://integration-infura.celo-testnet.org](https://integration-infura.celo-testnet.org). +2. Changes to [sendTransactionAsyncWithWeb3Signing](https://github.com/celo-org/celo-monorepo/blob/8689634a1d10d74ba6d4f3b36b2484db60a95bdb/packages/walletkit/src/contract-utils.ts#L362) in walletkit to poll after sending a transaction for the transaction to succeed. This is needed because http provider, unliked web sockets and IPC provider, does not support subscriptions. #### Why http(s) provider?