Skip to content

Commit

Permalink
owner + submission bits tests
Browse files Browse the repository at this point in the history
  • Loading branch information
XertroV committed Aug 15, 2018
1 parent 67abffd commit e310419
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 94 deletions.
64 changes: 35 additions & 29 deletions contracts/BBFarmRemote.sol
Expand Up @@ -36,6 +36,8 @@ library CalcBallotId {
* deterministically calculate ballotId
*/
contract RemoteBBFarmProxy is BBFarmIface {
using BBLibV7 for BBLibV7.DB;

bytes4 namespace;
bytes32 foreignNetworkDetails;
uint constant VERSION = 3;
Expand All @@ -46,25 +48,25 @@ contract RemoteBBFarmProxy is BBFarmIface {
/* storing info about ballots */
struct BallotPx {
bytes32 specHash;
uint256 packed;
IxIface index;
address bbOwner;
bytes16 extraData;
uint creationTs;
bool deprecated;
bytes32 secKey;
}
mapping(uint => BallotPx) ballots;
// struct BallotPx {
// bytes32 specHash;
// uint256 packed;
// IxIface index;
// address bbOwner;
// bytes16 extraData;
// uint creationTs;
// bool deprecated;
// bytes32 secKey;
// }
mapping(uint224 => BBLibV7.DB) dbs;
mapping(uint => uint) ballotNToId;
uint nBallots = 0;
/* ballot owner modifier */
modifier bOwner(uint ballotId) {
require(ballots[ballotId].bbOwner == msg.sender, "!owner");
require(getDb(ballotId).ballotOwner == msg.sender, "!owner");
_;
}
Expand All @@ -86,6 +88,12 @@ contract RemoteBBFarmProxy is BBFarmIface {
foreignNetworkDetails = bytes32(uint(fNetworkId) << 192 | uint(fChainId) << 160 | uint(fBBFarm));
}
// helper
function getDb(uint ballotId) internal view returns (BBLibV7.DB storage) {
// cut off anything above 224 bits (where the namespace goes)
return dbs[uint224(ballotId)];
}
/* global getters */
function getNamespace() external view returns (bytes4) {
Expand Down Expand Up @@ -122,16 +130,14 @@ contract RemoteBBFarmProxy is BBFarmIface {
) only_editors() external returns (uint ballotId) {
// calculate the ballotId based on the last 224 bits of the specHash.
ballotId = ballotId = CalcBallotId.calc(namespace, specHash, packed, bbOwner, extraData);
// we need to call the init functions on our libraries
getDb(ballotId).init(specHash, packed, ix, bbOwner, bytes16(uint128(extraData)));
// we just store a log of the ballot here; no additional logic
uint bN = nBallots;
nBallots = bN + 1;
ballotNToId[bN] = ballotId;
ballots[ballotId].specHash = specHash;
ballots[ballotId].packed = packed;
ballots[ballotId].index = ix;
ballots[ballotId].bbOwner = bbOwner;
ballots[ballotId].extraData = bytes16(uint128(extraData));
ballots[ballotId].creationTs = now;
emit BallotCreatedWithID(ballotId);
emit BallotOnForeignNetwork(foreignNetworkDetails, ballotId);
Expand Down Expand Up @@ -172,20 +178,20 @@ contract RemoteBBFarmProxy is BBFarmIface {
, bool deprecated
, address ballotOwner
, bytes16 extraData) {
BallotPx storage b = ballots[ballotId];
BBLibV7.DB storage b = getDb(ballotId);
uint packed = b.packed;
return (
false,
// this is a very big number (>2^255) that is obviously non arbitrary
// - idea is to deliberately cause a failure case if using bbFarmPx incorrectly.
113370313370313370313370313370313370313370313370313370313370313370313370313370,
b.secKey,
b.ballotEncryptionSeckey,
BPackedUtils.packedToSubmissionBits(packed),
BPackedUtils.packedToStartTime(packed),
BPackedUtils.packedToEndTime(packed),
b.specHash,
b.deprecated,
b.bbOwner,
b.ballotOwner,
b.extraData
);
}
Expand Down Expand Up @@ -215,33 +221,33 @@ contract RemoteBBFarmProxy is BBFarmIface {
}

function getCreationTs(uint ballotId) external view returns (uint) {
return ballots[ballotId].creationTs;
return getDb(ballotId).creationTs;
}

/* ADMIN */

// Allow the owner to reveal the secret key after ballot conclusion
function revealSeckey(uint ballotId, bytes32 secKey) external bOwner(ballotId) {
BallotPx storage b = ballots[ballotId];
BBLibV7.DB storage b = getDb(ballotId);
require(BPackedUtils.packedToEndTime(b.packed) < now, "!ended");
b.secKey = secKey;
b.ballotEncryptionSeckey = secKey;
}

// note: testing only.
function setEndTime(uint ballotId, uint64 newEndTime) external bOwner(ballotId) {
BallotPx storage b = ballots[ballotId];
BBLibV7.DB storage b = getDb(ballotId);
require(BBLibV7.isTesting(BPackedUtils.packedToSubmissionBits(b.packed)), "!testing");
b.packed = BPackedUtils.setEndTime(b.packed, newEndTime);
}

function setDeprecated(uint ballotId) external bOwner(ballotId) {
BallotPx storage b = ballots[ballotId];
BBLibV7.DB storage b = getDb(ballotId);
b.deprecated = true;
}

function setBallotOwner(uint ballotId, address newOwner) external bOwner(ballotId) {
BallotPx storage b = ballots[ballotId];
b.bbOwner = newOwner;
BBLibV7.DB storage b = getDb(ballotId);
b.ballotOwner = newOwner;
}
}

Expand Down
59 changes: 28 additions & 31 deletions test/bbFarmRemote.js
Expand Up @@ -25,9 +25,9 @@ var hexPk = "0xba781ed1006bd7694282a210485265f1c503f4e6721858b4269ae6d745f7bb4b"
var specHash = "0x418781fb172c2a30c072d58628f5df3f12052a0b785450fb0105f1b98b504561";


const genPxBB = async bbPx => {
const genPxBB = async (bbPx, owner = zeroAddr) => {
const specHash = genRandomBytes32()
const txr = await bbPx.initBallot(specHash, await genStdPacked(), zeroAddr, zeroAddr, zeroAddr);
const txr = await bbPx.initBallot(specHash, await genStdPacked(), zeroAddr, owner, zeroAddr);
const {args: {ballotId}} = getEventFromTxR('BallotCreatedWithID', txr)
return ballotId
}
Expand Down Expand Up @@ -81,7 +81,7 @@ async function testSetOwner({accounts, BB}) {
}


async function testEncryptionBranching({accounts, BB, bbaux}) {
async function testEncryptionBranching({owner, accounts, farmPx, farmRemote, doLog}) {
var [startTime, endTime] = await genStartEndTimes();
var shortEndTime = 0;

Expand Down Expand Up @@ -135,7 +135,7 @@ async function testEncryptionBranching({accounts, BB, bbaux}) {
}


async function testTestMode({accounts, BB, bbaux}) {
async function testTestMode({owner, accounts, farmPx, farmRemote, doLog}) {
const [s, e] = await genStartEndTimes();
var vc = await BB.new(specHash, mkPacked(s, e, USE_ETH | USE_NO_ENC), zeroAddr);
await assertErrStatus(ERR_TESTING_REQ, vc.setEndTime(0), "throws on set end time when not in testing");
Expand Down Expand Up @@ -180,7 +180,7 @@ const _genSigned = () => {
}


async function testDeprecation({accounts, BB, bbaux}) {
async function testDeprecation({owner, accounts, farmPx, farmRemote, doLog}) {
const [startTime, endTime] = await genStartEndTimes();
const bb = await BB.new(specHash, mkPacked(startTime, endTime, USE_ETH | USE_NO_ENC | USE_TESTING), zeroAddr);
const aux = mkBBPx(bb, bbaux);
Expand All @@ -201,8 +201,8 @@ const testVersion = async ({BB, bbaux}) => {
}


const testSponsorship = async ({accounts, BB, bbaux}) => {
const [owner, u1, u2, u3, u4, u5, u6, u7, u8, emergencyAdmin] = accounts;
const testSponsorship = async ({owner, accounts, farmPx, farmRemote, doLog}) => {
const [, u1, u2, u3, u4, u5, u6, u7, u8, emergencyAdmin] = accounts;

const [startTime, endTime] = await genStartEndTimes();
const payments = await SvPayments.new(emergencyAdmin);
Expand Down Expand Up @@ -235,7 +235,7 @@ const testSponsorship = async ({accounts, BB, bbaux}) => {
}


const testBadSubmissionBits = async ({accounts, BB, bbaux}) => {
const testBadSubmissionBits = async ({owner, accounts, farmPx, farmRemote, doLog}) => {
const [s, e] = await genStartEndTimes();

const flags = [USE_ENC, USE_NO_ENC];
Expand All @@ -246,23 +246,23 @@ const testBadSubmissionBits = async ({accounts, BB, bbaux}) => {
const badPacked2 = [mkPacked(s, e, USE_ETH)];

await Promise.all(R.map(p => {
return assertRevert(BB.new(specHash, p, zeroAddr), "bad submission bits (conflicting) should fail");
return assertRevert(farmPx.initBallot(specHash, p, zeroAddr, zeroAddr, "0x00"), "bad submission bits (conflicting) should fail");
}, badPacked1));

await Promise.all(R.map(p => {
return assertRevert(BB.new(specHash, p, zeroAddr), "bad submission bits (not enough) should fail");
return assertRevert(farmPx.initBallot(specHash, p, zeroAddr, zeroAddr, "0x00"), "bad submission bits (not enough) should fail");
}, badPacked2));

await assertRevert(BB.new(specHash, mkPacked(s, e, 32 | USE_ETH | USE_ENC), zeroAddr), "sub bits in middle banned");
await assertRevert(farmPx.initBallot(specHash, mkPacked(s, e, 32 | USE_ETH | USE_ENC), zeroAddr, zeroAddr, "0x00"), "sub bits in middle banned");
// make sure the ballot works excluding the `32` in subBits above
await BB.new(specHash, mkPacked(s, e, USE_ETH | USE_ENC), zeroAddr);
await assertRevert(BB.new(specHash, mkPacked(s, e, USE_SIGNED | USE_ENC), zeroAddr), "no signed ballots");
await farmPx.initBallot(specHash, mkPacked(s, e, USE_ETH | USE_ENC), zeroAddr, zeroAddr, "0x00");
await assertRevert(farmPx.initBallot(specHash, mkPacked(s, e, USE_SIGNED | USE_ENC), zeroAddr, zeroAddr, "0x00"), "no signed ballots");

const bannedBits = R.map(i => 2 ** i, [1,4,5,6,7,8,9,10,11,12])
const bannedPacked = R.map(i => mkPacked(s, e, i | USE_ETH | USE_NO_ENC), bannedBits)

await Promise.all(R.map(p => {
return assertRevert(BB.new(specHash, p, zeroAddr), "banned submission bits should not be allowed")
return assertRevert(farmPx.initBallot(specHash, p, zeroAddr, zeroAddr, "0x00"), "banned submission bits should not be allowed")
}, bannedPacked))
}

Expand Down Expand Up @@ -303,18 +303,18 @@ const testCommStatus = async ({accounts, BB, bbaux, bbName}) => {
}


const testOwner = async ({accounts, BB, bbaux}) => {
const bb = await genStdBB(BB);
assert.equal(await bb.owner(), accounts[0], "owner should be as expected");
const testOwner = async ({owner, accounts, farmPx, farmRemote, doLog}) => {
const ballotId = await genPxBB(farmPx, owner)
assert.equal((await farmPx.getDetails(ballotId, zeroAddr))[8], owner, "owner should be as expected");

await bb.setOwner(accounts[1], {from: accounts[0]});
assert.equal(await bb.owner(), accounts[1], "owner should be as expected after update");
await farmPx.setBallotOwner(ballotId, accounts[1], {from: owner});
assert.equal((await farmPx.getDetails(ballotId, zeroAddr))[8], accounts[1], "owner should be as expected after update");

await assertRevert(bb.setOwner(accounts[2], {from: accounts[0]}), "setOwner permissions okay");
await assertRevert(farmPx.setBallotOwner(ballotId, accounts[1], {from: owner}), "setOwner permissions okay");
}


const testGetVotes = async ({accounts, BB, bbaux, doLog}) => {
const testGetVotes = async ({owner, accounts, farmPx, farmRemote, doLog}) => {
const [s, e] = await genStartEndTimes();

const zeroSig = [bytes32zero, bytes32zero]
Expand Down Expand Up @@ -377,7 +377,7 @@ const testGetVotes = async ({accounts, BB, bbaux, doLog}) => {
}


const testBBFarmAux2 = async ({accounts, BB, bbaux, doLog, owner}) => {
const testBBFarmAux2 = async ({owner, accounts, farmPx, farmRemote, doLog}) => {
const [_, u1, u2, u3, u4] = accounts

let [s, e] = await genStartEndTimes();
Expand Down Expand Up @@ -410,10 +410,10 @@ const testBBFarmAux2 = async ({accounts, BB, bbaux, doLog, owner}) => {
}


const testEndTimeFuture = async ({BB, accounts}) => {
const testEndTimePast = async ({owner, accounts, farmPx, farmRemote, doLog}) => {
const [s, e] = await genStartEndTimes();
const packed = mkPacked(s, s - 10, USE_ETH | USE_NO_ENC);
await assertRevert(BB.new(genRandomBytes32(), packed, accounts[0]), 'should throw on end time in past')
await assertRevert(farmPx.initBallot(genRandomBytes32(), packed, accounts[0], accounts[0], "0x00"), 'should throw on end time in past')
}


Expand Down Expand Up @@ -557,21 +557,18 @@ const _wrapTest = ({accounts}, f) => {
contract("BBFarm Remote", function(accounts) {
const tests = [
["should instantiate correctly", testInstantiation],
// ["test bbFarmAux2", testBBFarmAux2],
// ["test sponsorship", testSponsorship],
["test proxy vote", testProxyVote],
["test proxy vote replay attacks", testProxyVoteReplayProtection],
// ["test getBallots*From", testGetVotes],
// ["should allow setting owner", testSetOwner],
// ["should enforce encryption based on PK submitted", testEncryptionBranching],
// ["should not allow testing functions if testing mode is false", testTestMode],
// ["should throw on early ballot", testEarlyBallot],
// ["should allow deprecation", testDeprecation],
// ["should have correct version", testVersion],
// ["test bad submission bits", testBadSubmissionBits],
// ["test community status", testCommStatus],
// ["test owner", testOwner],
// ["test end time must be in future", testEndTimeFuture],
// ["should have correct version", testVersion],
["test bad submission bits", testBadSubmissionBits],
["test owner", testOwner],
["test end time must be in future", testEndTimePast],
["test revert conditions", testRevertConditions],
]
R.map(([desc, f]) => {
Expand Down

0 comments on commit e310419

Please sign in to comment.