remove dupe (#6)

pull/7/head
Sally MacFarlane 6 years ago committed by GitHub
parent 247864f045
commit 2c05f4828a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 171
      contracts/Rules.sol
  2. 30
      test/test-get-all-enodes.js
  3. 4
      test/test-rules-authority.js
  4. 44
      test/test-rules.js

@ -16,33 +16,21 @@ contract Rules {
// version of this contract: semver like 1.2.14 represented like 001002014
uint version = 1000000;
struct EnodeIpv6 {
struct Enode {
bytes next;
bytes prev;
bytes32 enodeHigh;
bytes32 enodeLow;
bytes16 enodeHost; // Ipv6
bytes16 enodeHost;
uint16 enodePort;
}
struct EnodeIpv4 {
bytes next;
bytes prev;
bytes32 enodeHigh;
bytes32 enodeLow;
bytes4 enodeHost; // Ipv4
uint16 enodePort;
}
mapping(bytes => EnodeIpv6) private whitelistIpv6; // should there be a size for the whitelists?
mapping(bytes => EnodeIpv4) private whitelistIpv4;
mapping(bytes => Enode) private whitelist; // should there be a size for the whitelists?
// keys
uint countIpv4;
uint countIpv6;
bytes[] keysIpv4;
bytes[] keysIpv6;
uint countWhitelist;
bytes[] keysWhitelist;
// head of linked list
bytes headIpv4;
bytes headIpv6;
bytes headWhitelist;
// AUTHORIZATION
@ -120,154 +108,89 @@ contract Rules {
}
// RULES - IS CONNECTION ALLOWED
function connectionAllowedIpv6(
bytes32 sourceEnodeHigh, bytes32 sourceEnodeLow, bytes16 sourceEnodeIpv6, uint16 sourceEnodePort,
bytes32 destinationEnodeHigh, bytes32 destinationEnodeLow, bytes16 destinationEnodeIpv6, uint16 destinationEnodePort)
public view returns (bool) {
return (enodeAllowedIpv6(sourceEnodeHigh, sourceEnodeLow, sourceEnodeIpv6, sourceEnodePort) &&
enodeAllowedIpv6(destinationEnodeHigh, destinationEnodeLow, destinationEnodeIpv6, destinationEnodePort));
}
function connectionAllowedIpv4(
bytes32 sourceEnodeHigh, bytes32 sourceEnodeLow, bytes4 sourceEnodeIpv4, uint16 sourceEnodePort,
bytes32 destinationEnodeHigh, bytes32 destinationEnodeLow, bytes4 destinationEnodeIpv4, uint16 destinationEnodePort)
function connectionAllowed(
bytes32 sourceEnodeHigh, bytes32 sourceEnodeLow, bytes16 sourceEnodeIp, uint16 sourceEnodePort,
bytes32 destinationEnodeHigh, bytes32 destinationEnodeLow, bytes16 destinationEnodeIp, uint16 destinationEnodePort)
public view returns (bool) {
return (enodeAllowedIpv4(sourceEnodeHigh, sourceEnodeLow, sourceEnodeIpv4, sourceEnodePort) &&
enodeAllowedIpv4(destinationEnodeHigh, destinationEnodeLow, destinationEnodeIpv4, destinationEnodePort));
return (enodeAllowed(sourceEnodeHigh, sourceEnodeLow, sourceEnodeIp, sourceEnodePort) &&
enodeAllowed(destinationEnodeHigh, destinationEnodeLow, destinationEnodeIp, destinationEnodePort));
}
// RULES - IS ENODE ALLOWED
function enodeAllowedIpv6(bytes32 sourceEnodeHigh, bytes32 sourceEnodeLow, bytes16 sourceEnodeIpv6, uint16 sourceEnodePort)
function enodeAllowed(bytes32 sourceEnodeHigh, bytes32 sourceEnodeLow, bytes16 sourceEnodeIp, uint16 sourceEnodePort)
public view returns (bool){
bytes memory key = computeKeyIpv6(sourceEnodeHigh, sourceEnodeLow, sourceEnodeIpv6, sourceEnodePort);
EnodeIpv6 storage whitelistSource = whitelistIpv6[key];
if (enodeExists(whitelistSource)) {
return true;
}
}
function enodeAllowedIpv4(bytes32 sourceEnodeHigh, bytes32 sourceEnodeLow, bytes4 sourceEnodeIpv4, uint16 sourceEnodePort)
public view returns (bool){
bytes memory key = computeKeyIpv4(sourceEnodeHigh, sourceEnodeLow, sourceEnodeIpv4, sourceEnodePort);
EnodeIpv4 storage whitelistSource = whitelistIpv4[key];
bytes memory key = computeKey(sourceEnodeHigh, sourceEnodeLow, sourceEnodeIp, sourceEnodePort);
Enode storage whitelistSource = whitelist[key];
if (enodeExists(whitelistSource)) {
return true;
}
}
// RULES MODIFIERS - ADD
function addEnodeIpv6(bytes32 enodeHigh, bytes32 enodeLow, bytes16 enodeIpv6, uint16 enodePort) public onlyAdmin returns (bool) {
function addEnode(bytes32 enodeHigh, bytes32 enodeLow, bytes16 enodeIp, uint16 enodePort) public onlyAdmin returns (bool) {
require(readOnlyMode == false);
bytes memory key = computeKeyIpv6(enodeHigh, enodeLow, enodeIpv6, enodePort);
bytes memory key = computeKey(enodeHigh, enodeLow, enodeIp, enodePort);
// return false if already in the list
if (enodeExists(whitelistIpv6[key])) {
if (enodeExists(whitelist[key])) {
return false;
}
bytes memory next;
bytes memory prev;
if (countIpv6 == 0) {
if (countWhitelist == 0) {
next = key;
prev = key;
headIpv6 = key;
headWhitelist = key;
} else {
next = whitelistIpv6[headIpv6].next;
prev = headIpv6;
}
EnodeIpv6 memory newEnode = EnodeIpv6(next, prev, enodeHigh, enodeLow, enodeIpv6, enodePort);
whitelistIpv6[key] = newEnode;
keysIpv6.push(key);
countIpv6 = countIpv6 + 1;
whitelistIpv6[newEnode.next].prev = key;
whitelistIpv6[headIpv6].next = key;
return true;
}
function addEnodeIpv4(bytes32 enodeHigh, bytes32 enodeLow, bytes4 enodeIpv4, uint16 enodePort) public onlyAdmin returns (bool) {
require(readOnlyMode == false);
bytes memory key = computeKeyIpv4(enodeHigh, enodeLow, enodeIpv4, enodePort);
// return false if already in the list
if (enodeExists(whitelistIpv4[key])) {
return false;
}
bytes memory next;
bytes memory prev;
if (countIpv4 == 0) {
next = key;
prev = key;
headIpv4 = key;
} else {
next = whitelistIpv4[headIpv4].next;
prev = headIpv4;
}
EnodeIpv4 memory newEnode = EnodeIpv4(next, prev, enodeHigh, enodeLow, enodeIpv4, enodePort);
whitelistIpv4[key] = newEnode;
keysIpv4.push(key);
countIpv4 = countIpv4 + 1;
whitelistIpv4[newEnode.next].prev = key;
whitelistIpv4[headIpv4].next = key;
next = whitelist[headWhitelist].next;
prev = headWhitelist;
}
Enode memory newEnode = Enode(next, prev, enodeHigh, enodeLow, enodeIp, enodePort);
whitelist[key] = newEnode;
keysWhitelist.push(key);
countWhitelist = countWhitelist + 1;
whitelist[newEnode.next].prev = key;
whitelist[headWhitelist].next = key;
return true;
}
// RULES MODIFIERS - REMOVE
function removeEnodeIpv6(bytes32 enodeHigh, bytes32 enodeLow, bytes16 enodeIpv6, uint16 enodePort) public onlyAdmin returns (bool) {
require(readOnlyMode == false);
bytes memory key = computeKeyIpv6(enodeHigh, enodeLow, enodeIpv6, enodePort);
if (!enodeExists(whitelistIpv6[key])) {
return false;
}
EnodeIpv6 memory e = whitelistIpv6[key];
// TODO only if removing the head, reset the head to head.next
headIpv6 = e.next;
whitelistIpv6[e.prev].next = e.next;
whitelistIpv6[e.next].prev = e.prev;
countIpv6 = countIpv6 - 1;
delete whitelistIpv6[key];
return true;
}
function removeEnodeIpv4(bytes32 enodeHigh, bytes32 enodeLow, bytes4 enodeIpv4, uint16 enodePort) public onlyAdmin returns (bool) {
function removeEnode(bytes32 enodeHigh, bytes32 enodeLow, bytes16 enodeIp, uint16 enodePort) public onlyAdmin returns (bool) {
require(readOnlyMode == false);
bytes memory key = computeKeyIpv4(enodeHigh, enodeLow, enodeIpv4, enodePort);
if (!enodeExists(whitelistIpv4[key])) {
bytes memory key = computeKey(enodeHigh, enodeLow, enodeIp, enodePort);
if (!enodeExists(whitelist[key])) {
return false;
}
EnodeIpv4 memory e = whitelistIpv4[key];
Enode memory e = whitelist[key];
// TODO only if removing the head, reset the head to head.next
headIpv4 = e.next;
whitelistIpv4[e.prev].next = e.next;
whitelistIpv4[e.next].prev = e.prev;
countIpv4 = countIpv4 - 1;
delete whitelistIpv4[key];
headWhitelist = e.next;
whitelist[e.prev].next = e.next;
whitelist[e.next].prev = e.prev;
countWhitelist = countWhitelist - 1;
delete whitelist[key];
return true;
}
// RULES - LINKED LIST
function getHeadEnodeIpv4() public view returns (bytes memory, bytes memory, bytes32, bytes32, bytes4, uint16) {
require(countIpv4 > 0);
return getEnodeIpv4(headIpv4);
function getHeadEnode() public view returns (bytes memory, bytes memory, bytes32, bytes32, bytes16, uint16) {
require(countWhitelist > 0);
return getEnode(headWhitelist);
}
function getEnodeIpv4(bytes memory key) public view returns (bytes memory, bytes memory, bytes32 , bytes32 , bytes4 , uint16) {
EnodeIpv4 memory e = whitelistIpv4[key];
function getEnode(bytes memory key) public view returns (bytes memory, bytes memory, bytes32 , bytes32 , bytes16 , uint16) {
Enode memory e = whitelist[key];
return (e.next, e.prev, e.enodeHigh, e.enodeLow, e.enodeHost, e.enodePort);
}
// RULES - UTILS
function enodeExists(EnodeIpv4 memory enode) private pure returns (bool) {
function enodeExists(Enode memory enode) private pure returns (bool) {
// TODO do we need to check all fields?
return enode.enodeHost > 0 && enode.enodeHigh > 0 && enode.enodeLow > 0;
}
function enodeExists(EnodeIpv6 memory enode) private pure returns (bool) {
return enode.enodeHost > 0 && enode.enodeHigh > 0 && enode.enodeLow > 0;
}
function computeKeyIpv6(bytes32 enodeHigh, bytes32 enodeLow, bytes16 enodeHostIpv6, uint16 enodePort) public pure returns (bytes memory) {
return abi.encode(enodeHigh, enodeLow, enodeHostIpv6, enodePort);
}
function computeKeyIpv4(bytes32 enodeHigh, bytes32 enodeLow, bytes4 enodeHostIpv4, uint16 enodePort) public pure returns (bytes memory) {
return abi.encode(enodeHigh, enodeLow, enodeHostIpv4, enodePort);
}
function getKeyCountIpv4() public view returns (uint) {
return keysIpv4.length;
function computeKey(bytes32 enodeHigh, bytes32 enodeLow, bytes16 enodeHostIp, uint16 enodePort) public pure returns (bytes memory) {
return abi.encode(enodeHigh, enodeLow, enodeHostIp, enodePort);
}
function getKeyCountIpv6() public view returns (uint) {
return keysIpv6.length;
function getKeyCount() public view returns (uint) {
return keysWhitelist.length;
}
}

@ -3,17 +3,17 @@ var proxy;
var node1High = "0x9bd359fdc3a2ed5df436c3d8914b1532740128929892092b7fcb320c1b62f375";
var node1Low = "0x2e1092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929";
var node1Host = "0x9bd359fd";
var node1Host = "0x0000000000000000000011119bd359fd";
var node1Port = 1;
var node2High = "0x892092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929";
var node2Low = "0xcb320c1b62f37892092b7f59bd359fdc3a2ed5df436c3d8914b1532740128929";
var node2Host = "0x9bd359fd";
var node2Host = "0x0000000000000000000011119bd359fd";
var node2Port = 2;
var node3High = "0x765092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929";
var node3Low = "0x920982b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929";
var node3Host = "0x7fc359fd";
var node3Host = "0x0000000000000000000011117fc359fd";
var node3Port = 3;
var nodes = [[0,0,0,0],
@ -28,10 +28,10 @@ contract('Permissioning WITH AUTHORITY ', () => {
it('Should NOT permit any node when none have been added', async () => {
proxy = await TestPermissioning.new();
try {
let permitted = await proxy.enodeAllowedIpv4(node1High, node1Low, node1Host, node1Port);
let permitted = await proxy.enodeAllowed(node1High, node1Low, node1Host, node1Port);
assert.equal(permitted, false, 'expected node NOT permitted');
// get head when no nodes in list should fail
await proxy.getHeadEnodeIpv4();
await proxy.getHeadEnode();
} catch (err) {
assert(true, err.toString().includes('revert'), 'expected revert in message');
return;
@ -41,9 +41,9 @@ contract('Permissioning WITH AUTHORITY ', () => {
it('Should add a node to the whitelist and then permit that node', async () => {
// add node1
await proxy.addEnodeIpv4(node1High, node1Low, node1Host, node1Port);
await proxy.addEnode(node1High, node1Low, node1Host, node1Port);
let result = await proxy.getHeadEnodeIpv4();
let result = await proxy.getHeadEnode();
assert.equal(result[2], node1High, 'expected high node1');
assert.equal(result[3], node1Low, 'expected low node1');
@ -52,11 +52,11 @@ contract('Permissioning WITH AUTHORITY ', () => {
assert.equal(result[0], result[1], 'for node1 expected next == prev when only one node added');
// add node2
await proxy.addEnodeIpv4(node2High, node2Low, node2Host, node2Port);
await proxy.addEnode(node2High, node2Low, node2Host, node2Port);
// add node3
await proxy.addEnodeIpv4(node3High, node3Low, node3Host, node3Port);
await proxy.addEnode(node3High, node3Low, node3Host, node3Port);
result = await proxy.getHeadEnodeIpv4();
result = await proxy.getHeadEnode();
let key = result[0];
let foundNode1, foundNode2, foundNode3 = false;
@ -64,7 +64,7 @@ contract('Permissioning WITH AUTHORITY ', () => {
let i = 0;
let originalKey = key;
while (i<9 ) {
result = await proxy.getEnodeIpv4(key);
result = await proxy.getEnode(key);
// assert the values match the nodes array
assert.equal(result[2], nodes[result[5]][0], 'expected high node' + result[5]);
@ -93,13 +93,13 @@ contract('Permissioning WITH AUTHORITY ', () => {
});
it('Should remove a node from the whitelist and then NOT find it in the list', async () => {
result = await proxy.getHeadEnodeIpv4();
result = await proxy.getHeadEnode();
let key = result[0];
// remove node3
result = await proxy.removeEnodeIpv4(node1High, node1Low, node1Host, node1Port);
result = await proxy.removeEnode(node1High, node1Low, node1Host, node1Port);
result = await proxy.getHeadEnodeIpv4();
result = await proxy.getHeadEnode();
key = result[0];
let foundNode1 = false;
let foundNode2 = false;
@ -108,7 +108,7 @@ contract('Permissioning WITH AUTHORITY ', () => {
let i = 0;
let originalKey = key;
while (i<9) {
result = await proxy.getEnodeIpv4(key);
result = await proxy.getEnode(key);
// assert the values match the nodes array
assert.equal(result[2], nodes[result[5]][0], 'expected high node' + result[5]);

@ -3,7 +3,7 @@ var proxy;
var node1High = "0x9bd359fdc3a2ed5df436c3d8914b1532740128929892092b7fcb320c1b62f375";
var node1Low = "0x892092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929";
var node1Host = "0x9bd359fd";
var node1Host = "0x0000000000000000000011119bd359fd";
var node1Port = 30303;
var originalAdmin = "627306090abaB3A6e1400e9345bC60c78a8BEf57".toLowerCase();
@ -52,7 +52,7 @@ contract('Authority ', () => {
// add node should fail in read only mode
try {
await proxy.addEnodeIpv4(node1High, node1Low, node1Host, node1Port);
await proxy.addEnode(node1High, node1Low, node1Host, node1Port);
} catch (err) {
assert(true, err.toString().includes('revert'), 'expected revert in message');
await proxy.exitReadOnly();

@ -3,17 +3,17 @@ var proxy;
var node1High = "0x9bd359fdc3a2ed5df436c3d8914b1532740128929892092b7fcb320c1b62f375";
var node1Low = "0x2e1092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929";
var node1Host = "0x9bd359fd";
var node1Host = "0x0000000000000000000011119bd359fd";
var node1Port = 30303;
var node2High = "0x892092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929";
var node2Low = "0xcb320c1b62f37892092b7f59bd359fdc3a2ed5df436c3d8914b1532740128929";
var node2Host = "0x9bd359fd";
var node2Host = "0x0000000000000000000011119bd359fd";
var node2Port = 30304;
var node3High = "0x765092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929";
var node3Low = "0x920982b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929";
var node3Host = "0x7fc359fd";
var node3Host = "0x0000000000000000000011117fc359fd";
var node3Port = 30305;
var newAdmin = "f17f52151EbEF6C7334FAD080c5704D77216b732";
@ -22,62 +22,62 @@ contract('Permissioning WITH AUTHORITY ', () => {
describe('Function: Permissioning + Authority', () => {
it('Should NOT permit any node when none have been added', async () => {
proxy = await TestPermissioning.new();
let permitted = await proxy.enodeAllowedIpv4(node1High, node1Low, node1Host, node1Port);
let permitted = await proxy.enodeAllowed(node1High, node1Low, node1Host, node1Port);
assert.equal(permitted, false, 'expected node NOT permitted');
});
it('Should compute key', async () => {
let key1 = await proxy.computeKeyIpv4(node1High, node1Low, node1Host, node1Port);
let key2 = await proxy.computeKeyIpv4(node1High, node1Low, node1Host, node1Port);
let key1 = await proxy.computeKey(node1High, node1Low, node1Host, node1Port);
let key2 = await proxy.computeKey(node1High, node1Low, node1Host, node1Port);
assert.equal(key1, key2, "computed keys should be the same");
let key3 = await proxy.computeKeyIpv4(node1High, node1Low, node1Host, node2Port);
let key3 = await proxy.computeKey(node1High, node1Low, node1Host, node2Port);
assert(key3 != key2, "keys for different ports should be different");
});
it('Should add a node to the whitelist and then permit that node', async () => {
// add node1
await proxy.addEnodeIpv4(node1High, node1Low, node1Host, node1Port);
let permitted = await proxy.enodeAllowedIpv4(node1High, node1Low, node1Host, node1Port);
await proxy.addEnode(node1High, node1Low, node1Host, node1Port);
let permitted = await proxy.enodeAllowed(node1High, node1Low, node1Host, node1Port);
assert.equal(permitted, true, 'expected node added to be permitted');
// add node2
await proxy.addEnodeIpv4(node2High, node2Low, node2Host, node2Port);
permitted = await proxy.enodeAllowedIpv4(node2High, node2Low, node2Host, node2Port);
await proxy.addEnode(node2High, node2Low, node2Host, node2Port);
permitted = await proxy.enodeAllowed(node2High, node2Low, node2Host, node2Port);
assert.equal(permitted, true, 'expected node 2 added to be permitted');
// first one still permitted
permitted = await proxy.enodeAllowedIpv4(node1High, node1Low, node1Host, node1Port);
permitted = await proxy.enodeAllowed(node1High, node1Low, node1Host, node1Port);
assert.equal(permitted, true, 'expected node 1 added to be permitted');
// add node3
await proxy.addEnodeIpv4(node3High, node3Low, node3Host, node3Port);
permitted = await proxy.enodeAllowedIpv4(node3High, node3Low, node3Host, node3Port);
await proxy.addEnode(node3High, node3Low, node3Host, node3Port);
permitted = await proxy.enodeAllowed(node3High, node3Low, node3Host, node3Port);
assert.equal(permitted, true, 'expected node 3 added to be permitted');
// node1 still permitted
permitted = await proxy.enodeAllowedIpv4(node1High, node1Low, node1Host, node1Port);
permitted = await proxy.enodeAllowed(node1High, node1Low, node1Host, node1Port);
assert.equal(permitted, true, 'expected node 1 added to be permitted');
// node2 still permitted
permitted = await proxy.enodeAllowedIpv4(node2High, node2Low, node2Host, node2Port);
permitted = await proxy.enodeAllowed(node2High, node2Low, node2Host, node2Port);
assert.equal(permitted, true, 'expected node 2 added to be permitted');
});
it('Should allow a connection between 2 added nodes', async () => {
let permitted = await proxy.connectionAllowedIpv4(node1High, node1Low, node1Host, node1Port, node2High, node2Low, node2Host, node2Port);
let permitted = await proxy.connectionAllowed(node1High, node1Low, node1Host, node1Port, node2High, node2Low, node2Host, node2Port);
assert.equal(permitted, true, 'expected permitted node1 <> node2');
permitted = await proxy.connectionAllowedIpv4(node1High, node1Low, node1Host, node1Port, node3High, node3Low, node3Host, node3Port);
permitted = await proxy.connectionAllowed(node1High, node1Low, node1Host, node1Port, node3High, node3Low, node3Host, node3Port);
assert.equal(permitted, true, 'expected permitted node1 <> node3');
permitted = await proxy.connectionAllowedIpv4(node2High, node2Low, node2Host, node2Port, node3High, node3Low, node3Host, node3Port);
permitted = await proxy.connectionAllowed(node2High, node2Low, node2Host, node2Port, node3High, node3Low, node3Host, node3Port);
assert.equal(permitted, true, 'expected permitted node2 <> node3');
});
it('Should remove a node from the whitelist and then NOT permit that node', async () => {
await proxy.removeEnodeIpv4(node1High, node1Low, node1Host, node1Port);
let permitted = await proxy.enodeAllowedIpv4(node1High, node1Low, node1Host, node1Port);
await proxy.removeEnode(node1High, node1Low, node1Host, node1Port);
let permitted = await proxy.enodeAllowed(node1High, node1Low, node1Host, node1Port);
assert.equal(permitted, false, 'expected removed node NOT permitted');
permitted = await proxy.connectionAllowedIpv4(node1High, node1Low, node1Host, node1Port, node2High, node2Low, node2Host, node2Port);
permitted = await proxy.connectionAllowed(node1High, node1Low, node1Host, node1Port, node2High, node2Low, node2Host, node2Port);
assert.equal(permitted, false, 'expected source disallowed since it was removed');
});
});

Loading…
Cancel
Save