PIE-1515: Rules contract with linked list library (#39)
parent
643f4bb2ee
commit
672dbb162c
@ -0,0 +1,31 @@ |
||||
pragma solidity >=0.4.22 <0.6.0; |
||||
|
||||
import "./RulesList.sol"; |
||||
|
||||
|
||||
contract ExposedRulesList is RulesList { |
||||
|
||||
function _calculateKey(bytes32 _enodeHigh, bytes32 _enodeLow, bytes16 _ip, uint16 _port) public pure returns(uint256) { |
||||
return calculateKey(_enodeHigh, _enodeLow, _ip, _port); |
||||
} |
||||
|
||||
function _size() public view returns (uint256) { |
||||
return size(); |
||||
} |
||||
|
||||
function _exists(bytes32 _enodeHigh, bytes32 _enodeLow, bytes16 _ip, uint16 _port) public view returns (bool) { |
||||
return exists(_enodeHigh, _enodeLow, _ip, _port); |
||||
} |
||||
|
||||
function _add(bytes32 _enodeHigh, bytes32 _enodeLow, bytes16 _ip, uint16 _port) public returns (bool) { |
||||
return add(_enodeHigh, _enodeLow, _ip, _port); |
||||
} |
||||
|
||||
function _remove(bytes32 _enodeHigh, bytes32 _enodeLow, bytes16 _ip, uint16 _port) public returns (bool) { |
||||
return remove(_enodeHigh, _enodeLow, _ip, _port); |
||||
} |
||||
|
||||
function _get(uint _index) public view returns (bool _found, bytes32 _enodeHigh, bytes32 _enodeLow, bytes16 _ip, uint16 _port) { |
||||
return get(_index); |
||||
} |
||||
} |
@ -0,0 +1,93 @@ |
||||
pragma solidity >=0.4.22 <0.6.0; |
||||
|
||||
import "solidity-linked-list/contracts/StructuredLinkedList.sol"; |
||||
|
||||
|
||||
contract RulesList { |
||||
using StructuredLinkedList for StructuredLinkedList.List; |
||||
|
||||
// struct size = 82 bytes |
||||
struct enode { |
||||
bytes32 enodeHigh; |
||||
bytes32 enodeLow; |
||||
bytes16 ip; |
||||
uint16 port; |
||||
} |
||||
|
||||
StructuredLinkedList.List private list; |
||||
mapping (uint256 => enode) private enodeMapping; |
||||
|
||||
function calculateKey(bytes32 _enodeHigh, bytes32 _enodeLow, bytes16 _ip, uint16 _port) internal pure returns(uint256) { |
||||
return uint256(keccak256(abi.encodePacked(_enodeHigh, _enodeLow, _ip, _port))); |
||||
} |
||||
|
||||
function size() internal view returns (uint256) { |
||||
return list.sizeOf(); |
||||
} |
||||
|
||||
function exists(bytes32 _enodeHigh, bytes32 _enodeLow, bytes16 _ip, uint16 _port) internal view returns (bool) { |
||||
return list.nodeExists(calculateKey(_enodeHigh, _enodeLow, _ip, _port)); |
||||
} |
||||
|
||||
function add(bytes32 _enodeHigh, bytes32 _enodeLow, bytes16 _ip, uint16 _port) internal returns (bool) { |
||||
uint key = calculateKey(_enodeHigh, _enodeLow, _ip, _port); |
||||
if (!list.nodeExists(key)) { |
||||
enode memory newEnode = enode( |
||||
_enodeHigh, |
||||
_enodeLow, |
||||
_ip, |
||||
_port |
||||
); |
||||
enodeMapping[key] = newEnode; |
||||
|
||||
return list.push(calculateKey(_enodeHigh, _enodeLow, _ip, _port), false); |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
function remove(bytes32 _enodeHigh, bytes32 _enodeLow, bytes16 _ip, uint16 _port) internal returns (bool) { |
||||
uint key = calculateKey(_enodeHigh, _enodeLow, _ip, _port); |
||||
if (list.nodeExists(key)) { |
||||
delete enodeMapping[key]; |
||||
return list.remove(key) != 0 ? true : false; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
function get(uint _index) internal view returns (bool _exists, bytes32 _enodeHigh, bytes32 _enodeLow, bytes16 _ip, uint16 _port) { |
||||
uint listSize = list.sizeOf(); |
||||
if (_index >= listSize) { |
||||
return (false, bytes32(0), bytes32(0), bytes16(0), uint16(0)); |
||||
} |
||||
|
||||
uint counter = 0; |
||||
uint pointer = 0; |
||||
bool hasFound = false; |
||||
|
||||
while(counter <= listSize) { |
||||
(bool nodeExists, uint256 prev, uint256 next) = list.getNode(pointer); |
||||
if (nodeExists) { |
||||
if (counter == _index + 1) { |
||||
hasFound = true; |
||||
break; |
||||
} else { |
||||
counter++; |
||||
pointer = next; |
||||
} |
||||
} else { |
||||
break; |
||||
} |
||||
//Getting rid of unused variable warning |
||||
prev; |
||||
} |
||||
|
||||
if (hasFound) { |
||||
enode memory e = enodeMapping[pointer]; |
||||
return (true, e.enodeHigh, e.enodeLow, e.ip, e.port); |
||||
} else { |
||||
return (false, bytes32(0), bytes32(0), bytes16(0), uint16(0)); |
||||
} |
||||
} |
||||
} |
File diff suppressed because one or more lines are too long
@ -1,171 +0,0 @@ |
||||
const Ingress = artifacts.require('Ingress.sol'); |
||||
const Rules = artifacts.require('Rules.sol'); |
||||
const Admin = artifacts.require('Admin.sol'); |
||||
|
||||
const ADMIN_NAME = "0x61646d696e697374726174696f6e000000000000000000000000000000000000"; |
||||
|
||||
var node1High = "0x9bd359fdc3a2ed5df436c3d8914b1532740128929892092b7fcb320c1b62f375"; |
||||
var node1HighCopy = "0x9bd359fdc3a2ed5df436c3d8914b1532740128929892092b7fcb320c1b62f375"; |
||||
var node1Low = "0x2e1092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
var node1Host = "0x0000000000000000000011119bd359fd"; |
||||
var node1Port = 1; |
||||
|
||||
var node2High = "0x892092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
var node2Low = "0xcb320c1b62f37892092b7f59bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
var node2Host = "0x0000000000000000000011119bd359fd"; |
||||
var node2Port = 2; |
||||
|
||||
var node3High = "0x765092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
var node3Low = "0x920982b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
var node3Host = "0x0000000000000000000011117fc359fd"; |
||||
var node3Port = 3; |
||||
|
||||
// use 1,2,3 as port numbers and index into this array
|
||||
var nodes = [[0,0,0,0], |
||||
[node1High, node1Low, node1Host, node1Port], |
||||
[node2High, node2Low, node2Host, node2Port], |
||||
[node3High, node3Low, node3Host, node3Port]]; |
||||
|
||||
var newAdmin = "f17f52151EbEF6C7334FAD080c5704D77216b732"; |
||||
|
||||
// Contract keys
|
||||
var RULES_CONTRACT = "0x72756c6573000000000000000000000000000000000000000000000000000000"; |
||||
|
||||
contract('Rules (node permissioning)', () => { |
||||
let ingressContract; |
||||
let rulesContract; |
||||
let adminContract; |
||||
|
||||
before(async () => { |
||||
ingressContract = await Ingress.new(); |
||||
adminContract = await Admin.new(); |
||||
result = await ingressContract.setContractAddress(ADMIN_NAME, adminContract.address); |
||||
rulesContract = await Rules.new(ingressContract.address); |
||||
}) |
||||
|
||||
it('Should NOT permit any node when none have been added', async () => { |
||||
try { |
||||
let permitted = await rulesContract.enodeAllowed(node1High, node1Low, node1Host, node1Port); |
||||
assert.equal(permitted, false, 'expected node NOT permitted'); |
||||
// get head when no nodes in list should fail
|
||||
await rulesContract.getHeadEnode(); |
||||
} catch (err) { |
||||
assert(true, err.toString().includes('revert'), 'expected revert in message'); |
||||
return; |
||||
} |
||||
assert(false, 'did not catch expected error from getHeadEnode() when no nodes in whitelist'); |
||||
}); |
||||
|
||||
it('Should add a node to the whitelist and then permit that node', async () => { |
||||
// Register the Rules contract to permit adding enodes
|
||||
await ingressContract.setContractAddress(RULES_CONTRACT, rulesContract.address); |
||||
|
||||
// add node1
|
||||
await rulesContract.addEnode(node1High, node1Low, node1Host, node1Port); |
||||
|
||||
let result = await rulesContract.getHeadEnode(); |
||||
|
||||
assert.equal(result[2], node1High, 'expected high node1'); |
||||
assert.equal(result[3], node1Low, 'expected low node1'); |
||||
assert.equal(result[4], node1Host, 'expected host node1'); |
||||
assert.equal(result[5], node1Port, 'expected port node1'); |
||||
assert.equal(result[0], result[1], 'for node1 expected next == prev when only one node added'); |
||||
|
||||
// add node2
|
||||
await rulesContract.addEnode(node2High, node2Low, node2Host, node2Port); |
||||
// add node3
|
||||
await rulesContract.addEnode(node3High, node3Low, node3Host, node3Port); |
||||
|
||||
result = await rulesContract.getHeadEnode(); |
||||
|
||||
let key = result[0]; |
||||
let foundNode1, foundNode2, foundNode3 = false; |
||||
|
||||
let i = 0; |
||||
let originalKey = key; |
||||
while (i<9 ) { |
||||
result = await rulesContract.getEnode(key); |
||||
|
||||
// assert the values match the nodes array
|
||||
assert.equal(result[2], nodes[result[5]][0], 'expected high node' + result[5]); |
||||
assert.equal(result[3], nodes[result[5]][1], 'expected low node' + result[5]); |
||||
assert.equal(result[4], nodes[result[5]][2], 'expected host node' + result[5]); |
||||
if (result[2] == node1High) { |
||||
foundNode1 = true; |
||||
} |
||||
if (result[2] == node2High) { |
||||
foundNode2 = true; |
||||
} |
||||
if (result[2] == node3High) { |
||||
foundNode3 = true; |
||||
} |
||||
|
||||
key = result[0]; |
||||
i++; |
||||
if (key == originalKey) { |
||||
break; |
||||
} |
||||
} |
||||
assert.equal(i, 3, 'expected 3 values'); |
||||
assert.equal(foundNode1, true, 'expected to find node1'); |
||||
assert.equal(foundNode2, true, 'expected to find node2'); |
||||
assert.equal(foundNode3, true, 'expected to find node3'); |
||||
// test keycount
|
||||
result = await rulesContract.getKeyCount(); |
||||
assert.equal(result, 3, 'expected count 3'); |
||||
}); |
||||
|
||||
it('Should remove a node from the whitelist and then NOT find it in the list', async () => { |
||||
result = await rulesContract.getHeadEnode(); |
||||
let key = result[0]; |
||||
|
||||
// remove node3
|
||||
result = await rulesContract.removeEnode(node1High, node1Low, node1Host, node1Port); |
||||
|
||||
result = await rulesContract.getHeadEnode(); |
||||
key = result[0]; |
||||
let foundNode1 = false; |
||||
let foundNode2 = false; |
||||
let foundNode3 = false; |
||||
|
||||
let i = 0; |
||||
let originalKey = key; |
||||
while (i<9) { |
||||
result = await rulesContract.getEnode(key); |
||||
|
||||
// assert the values match the nodes array
|
||||
assert.equal(result[2], nodes[result[5]][0], 'expected high node' + result[5]); |
||||
assert.equal(result[3], nodes[result[5]][1], 'expected low node' + result[5]); |
||||
assert.equal(result[4], nodes[result[5]][2], 'expected host node' + result[5]); |
||||
if (result[2] == node1High) { |
||||
foundNode1 = true; |
||||
} |
||||
if (result[2] == node2High) { |
||||
foundNode2 = true; |
||||
} |
||||
if (result[2] == node3High) { |
||||
foundNode3 = true; |
||||
} |
||||
|
||||
key = result[0]; |
||||
i++; |
||||
if (key == originalKey) { |
||||
break; |
||||
} |
||||
} |
||||
assert.equal(foundNode1, false, 'expected to NOT find node1'); |
||||
assert.equal(foundNode2, true, 'expected to find node2'); |
||||
assert.equal(foundNode3, true, 'expected to find node3'); |
||||
assert.equal(i, 2, 'expected 2 values'); |
||||
result = await rulesContract.getKeyCount(); |
||||
assert.equal(result, 2, 'expected count 2'); |
||||
}); |
||||
|
||||
it('Should compare bytes', async () => { |
||||
result = await rulesContract.bytesEqual(node1High, node1Low); |
||||
assert.equal(result, false, 'expected not equal'); |
||||
|
||||
result = await rulesContract.bytesEqual(node1High, node1HighCopy); |
||||
assert.equal(result, true, 'expected equal'); |
||||
}); |
||||
}); |
@ -0,0 +1,159 @@ |
||||
const BN = web3.utils.BN; |
||||
const RulesList = artifacts.require('ExposedRulesList.sol'); |
||||
|
||||
const node1High = "0x9bd359fdc3a2ed5df436c3d8914b1532740128929892092b7fcb320c1b62f375"; |
||||
const node1Low = "0x2e1092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
const node1Host = "0x0000000000000000000011119bd359fd"; |
||||
const node1Port = 30303; |
||||
const node2High = "0x892092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
const node2Low = "0xcb320c1b62f37892092b7f59bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
const node2Host = "0x0000000000000000000011119bd359fd"; |
||||
const node2Port = 30304; |
||||
const node3High = "0x765092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
const node3Low = "0x920982b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
const node3Host = "0x0000000000000000000011117fc359fd"; |
||||
const node3Port = 30305; |
||||
|
||||
contract("RulesList (list manipulation)", async () => { |
||||
|
||||
let rulesListContract; |
||||
|
||||
beforeEach(async () => { |
||||
rulesListContract = await RulesList.new(); |
||||
}); |
||||
|
||||
it("should calculate same key for same enode", async () => { |
||||
let key1 = new BN(await rulesListContract._calculateKey(node1High, node1Low, node1Host, node1Port)); |
||||
let key2 = new BN(await rulesListContract._calculateKey(node1High, node1Low, node1Host, node1Port)); |
||||
|
||||
assert.ok(key1.eq(key2)) |
||||
}); |
||||
|
||||
it("should calculate different key for different enode", async () => { |
||||
let key1 = new BN(await rulesListContract._calculateKey(node1High, node1Low, node1Host, node1Port)); |
||||
let key2 = new BN(await rulesListContract._calculateKey(node2High, node2Low, node2Host, node2Port)); |
||||
|
||||
assert.notOk(key1.eq(key2)) |
||||
}); |
||||
|
||||
it("should start with an empty list of rules", async () => { |
||||
let size = await rulesListContract._size(); |
||||
|
||||
assert.equal(size, 0); |
||||
}); |
||||
|
||||
it("size method reflect list size", async () => { |
||||
await rulesListContract._add(node1High, node1Low, node1Host, node1Port); |
||||
await rulesListContract._add(node2High, node2Low, node2Host, node2Port); |
||||
await rulesListContract._add(node3High, node3Low, node3Host, node3Port); |
||||
|
||||
let size = await rulesListContract._size(); |
||||
assert.equal(size, 3); |
||||
}); |
||||
|
||||
it("exists should return true for existing address", async () => { |
||||
await rulesListContract._add(node1High, node1Low, node1Host, node1Port); |
||||
|
||||
let exists = await rulesListContract._exists(node1High, node1Low, node1Host, node1Port); |
||||
|
||||
assert.ok(exists); |
||||
}); |
||||
|
||||
it("exists should return false for absent address", async () => { |
||||
// adding another address so list is not empty
|
||||
await rulesListContract._add(node1High, node1Low, node1Host, node1Port); |
||||
|
||||
let exists = await rulesListContract._exists(node2High, node2Low, node2Host, node2Port); |
||||
|
||||
assert.notOk(exists); |
||||
}); |
||||
|
||||
it("exists should return false when list is empty", async () => { |
||||
let exists = await rulesListContract._exists(node1High, node1Low, node1Host, node1Port); |
||||
|
||||
assert.notOk(exists); |
||||
}); |
||||
|
||||
it("add enode to list should add node to the list and increase list size", async () => { |
||||
let exists = await rulesListContract._exists(node1High, node1Low, node1Host, node1Port); |
||||
assert.notOk(exists); |
||||
let size = await rulesListContract._size(); |
||||
assert.equal(size, 0); |
||||
|
||||
await rulesListContract._add(node1High, node1Low, node1Host, node1Port); |
||||
|
||||
exists = await rulesListContract._exists(node1High, node1Low, node1Host, node1Port); |
||||
assert.ok(exists); |
||||
size = await rulesListContract._size(); |
||||
assert.equal(size, 1); |
||||
}); |
||||
|
||||
it("add existing enode should do nothing on second insert", async () => { |
||||
await rulesListContract._add(node1High, node1Low, node1Host, node1Port); |
||||
await rulesListContract._add(node1High, node1Low, node1Host, node1Port); |
||||
|
||||
let size = await rulesListContract._size(); |
||||
assert.equal(size, 1); |
||||
|
||||
let exists = await rulesListContract._exists(node1High, node1Low, node1Host, node1Port); |
||||
assert.ok(exists); |
||||
}); |
||||
|
||||
it("remove absent enode should not fail", async () => { |
||||
let txResult = await rulesListContract._remove(node1High, node1Low, node1Host, node1Port); |
||||
|
||||
assert.ok(txResult.receipt.status); |
||||
}); |
||||
|
||||
it("remove enode from list should remove enode from list and decrease list size", async () => { |
||||
await rulesListContract._add(node1High, node1Low, node1Host, node1Port); |
||||
let size = await rulesListContract._size(); |
||||
assert.equal(size, 1); |
||||
let exists = await rulesListContract._exists(node1High, node1Low, node1Host, node1Port); |
||||
assert.ok(exists); |
||||
|
||||
await rulesListContract._remove(node1High, node1Low, node1Host, node1Port); |
||||
|
||||
size = await rulesListContract._size(); |
||||
assert.equal(size, 0); |
||||
exists = await rulesListContract._exists(node1High, node1Low, node1Host, node1Port); |
||||
assert.notOk(exists); |
||||
}); |
||||
|
||||
it("remove address in the middle of list should maintain list order", async () => { |
||||
await rulesListContract._add(node1High, node1Low, node1Host, node1Port); |
||||
await rulesListContract._add(node2High, node2Low, node2Host, node2Port); |
||||
await rulesListContract._add(node3High, node3Low, node3Host, node3Port); |
||||
|
||||
node = await rulesListContract._get(1); |
||||
assert.ok(node._found); |
||||
assert.equal(node[1], node2High); |
||||
|
||||
await rulesListContract._remove(node2High, node2Low, node2Host, node2Port); |
||||
|
||||
node = await rulesListContract._get(1); |
||||
assert.ok(node._found); |
||||
assert.equal(node[1], node3High); |
||||
}); |
||||
|
||||
it("get by index on empty list should return false", async () => { |
||||
let node = await rulesListContract._get(0); |
||||
|
||||
assert.notOk(node._found); |
||||
}); |
||||
|
||||
it("get by index returns expected order", async () => { |
||||
await rulesListContract._add(node1High, node1Low, node1Host, node1Port); |
||||
await rulesListContract._add(node2High, node2Low, node2Host, node2Port); |
||||
await rulesListContract._add(node3High, node3Low, node3Host, node3Port); |
||||
|
||||
let enode = await rulesListContract._get(0); |
||||
assert.equal(enode._enodeHigh, node1High); |
||||
|
||||
enode = await rulesListContract._get(1); |
||||
assert.equal(enode._enodeHigh, node2High); |
||||
|
||||
enode = await rulesListContract._get(2); |
||||
assert.equal(enode._enodeHigh, node3High); |
||||
}); |
||||
}); |
@ -0,0 +1,146 @@ |
||||
const IngressContract = artifacts.require('Ingress.sol'); |
||||
const RulesContract = artifacts.require('Rules.sol'); |
||||
const AdminContract = artifacts.require('Admin.sol'); |
||||
|
||||
// Contract keys
|
||||
const RULES_NAME = "0x72756c6573000000000000000000000000000000000000000000000000000000"; |
||||
const ADMIN_NAME = "0x61646d696e697374726174696f6e000000000000000000000000000000000000"; |
||||
|
||||
// enodeAllowed reponses
|
||||
const PERMITTED = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; |
||||
const NOT_PERMITTED = "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; |
||||
|
||||
const node1High = "0x9bd359fdc3a2ed5df436c3d8914b1532740128929892092b7fcb320c1b62f375"; |
||||
const node1Low = "0x2e1092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
const node1Host = "0x0000000000000000000011119bd359fd"; |
||||
const node1Port = 30303; |
||||
|
||||
const node2High = "0x892092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
const node2Low = "0xcb320c1b62f37892092b7f59bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
const node2Host = "0x0000000000000000000011119bd359fd"; |
||||
const node2Port = 30304; |
||||
|
||||
const node3High = "0x765092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
const node3Low = "0x920982b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
const node3Host = "0x0000000000000000000011117fc359fd"; |
||||
const node3Port = 30305; |
||||
|
||||
const newAdmin = "f17f52151EbEF6C7334FAD080c5704D77216b732"; |
||||
|
||||
contract("Rules (Permissioning)", (accounts) => { |
||||
let ingressContract; |
||||
let rulesContract; |
||||
let adminContract; |
||||
|
||||
before(async () => { |
||||
ingressContract = await IngressContract.new(); |
||||
|
||||
adminContract = await AdminContract.new(); |
||||
await ingressContract.setContractAddress(ADMIN_NAME, adminContract.address); |
||||
|
||||
rulesContract = await RulesContract.new(ingressContract.address); |
||||
await ingressContract.setContractAddress(RULES_NAME, rulesContract.address); |
||||
}); |
||||
|
||||
it('should NOT permit node when whitelist is empty', async () => { |
||||
let size = await rulesContract.getSize(); |
||||
assert.equal(size, 0, "expected empty whitelist"); |
||||
|
||||
let permitted = await rulesContract.enodeInWhitelist(node1High, node1Low, node1Host, node1Port); |
||||
assert.notOk(permitted, 'expected node NOT permitted'); |
||||
}); |
||||
|
||||
it('Should NOT fail when removing enode from empty list', async () => { |
||||
let size = await rulesContract.getSize(); |
||||
assert.equal(size, 0, "expected empty whitelist"); |
||||
|
||||
let tx = await rulesContract.removeEnode(node1High, node1Low, node1Host, node1Port); |
||||
assert.ok(tx.receipt.status); |
||||
}); |
||||
|
||||
it('should add multiple nodes to whitelist', async () => { |
||||
await rulesContract.addEnode(node1High, node1Low, node1Host, node1Port); |
||||
await rulesContract.addEnode(node2High, node2Low, node2Host, node2Port); |
||||
await rulesContract.addEnode(node3High, node3Low, node3Host, node3Port); |
||||
|
||||
permitted = await rulesContract.enodeInWhitelist(node1High, node1Low, node1Host, node1Port); |
||||
assert.ok(permitted, 'expected node 1 added to be in whitelist'); |
||||
|
||||
permitted = await rulesContract.enodeInWhitelist(node2High, node2Low, node2Host, node2Port); |
||||
assert.ok(permitted, 'expected node 2 added to be in whitelist'); |
||||
|
||||
permitted = await rulesContract.enodeInWhitelist(node3High, node3Low, node3Host, node3Port); |
||||
assert.ok(permitted, 'expected node 3 added to be in whitelist'); |
||||
}); |
||||
|
||||
it('should allow a connection between nodes added to the whitelist', async () => { |
||||
let permitted = await rulesContract.connectionAllowed(node1High, node1Low, node1Host, node1Port, node2High, node2Low, node2Host, node2Port); |
||||
assert.equal(permitted, PERMITTED, 'expected permitted node1 <---> node2'); |
||||
|
||||
permitted = await rulesContract.connectionAllowed(node1High, node1Low, node1Host, node1Port, node3High, node3Low, node3Host, node3Port); |
||||
assert.equal(permitted, PERMITTED, 'expected permitted node1 <---> node3'); |
||||
|
||||
permitted = await rulesContract.connectionAllowed(node2High, node2Low, node2Host, node2Port, node3High, node3Low, node3Host, node3Port); |
||||
assert.equal(permitted, PERMITTED, 'expected permitted node2 <---> node3'); |
||||
}); |
||||
|
||||
it('should NOT allow connection with node removed from whitelist', async () => { |
||||
await rulesContract.removeEnode(node3High, node3Low, node3Host, node3Port); |
||||
let permitted = await rulesContract.enodeInWhitelist(node3High, node3Low, node3Host, node3Port); |
||||
assert.notOk(permitted, 'expected removed node NOT permitted'); |
||||
|
||||
permitted = await rulesContract.connectionAllowed(node3High, node3Low, node3Host, node3Port, node2High, node2Low, node2Host, node2Port); |
||||
assert.equal(permitted, NOT_PERMITTED, 'expected source disallowed since it was removed'); |
||||
|
||||
let result = await rulesContract.getSize(); |
||||
assert.equal(result, 2, "expected number of nodes"); |
||||
}); |
||||
|
||||
it('should permit a node added back to the whitelist', async () => { |
||||
let permitted = await rulesContract.enodeInWhitelist(node3High, node3Low, node3Host, node3Port); |
||||
assert.notOk(permitted, 'expected removed node NOT permitted'); |
||||
|
||||
await rulesContract.addEnode(node3High, node3Low, node3Host, node3Port); |
||||
permitted = await rulesContract.enodeInWhitelist(node3High, node3Low, node3Host, node3Port); |
||||
assert.ok(permitted, 'expected added node permitted'); |
||||
|
||||
permitted = await rulesContract.connectionAllowed(node3High, node3Low, node3Host, node3Port, node2High, node2Low, node2Host, node2Port); |
||||
assert.equal(permitted, PERMITTED, 'expected connection allowed since node was added back to whitelist'); |
||||
}); |
||||
|
||||
it('should not allow non-admin account to add node to whitelist', async () => { |
||||
try { |
||||
await rulesContract.addEnode(node1High, node1Low, node1Host, node1Port, { from: accounts[1] }); |
||||
expect.fail(null, null, "Modifier was not enforced") |
||||
} catch(err) { |
||||
expect(err.reason).to.contain('Sender not authorized'); |
||||
} |
||||
}); |
||||
|
||||
it('should not allow non-admin account to remove node to whitelist', async () => { |
||||
try { |
||||
await rulesContract.addEnode(node1High, node1Low, node1Host, node1Port, { from: accounts[1] }); |
||||
expect.fail(null, null, "Modifier was not enforced") |
||||
} catch(err) { |
||||
expect(err.reason).to.contain('Sender not authorized'); |
||||
} |
||||
}); |
||||
|
||||
it('should allow new admin account to remove node from whitelist', async () => { |
||||
await adminContract.addAdmin(accounts[1]); |
||||
|
||||
await rulesContract.removeEnode(node1High, node1Low, node1Host, node1Port, { from: accounts[1] }); |
||||
|
||||
let permitted = await rulesContract.enodeInWhitelist(node1High, node1Low, node1Host, node1Port); |
||||
assert.notOk(permitted, 'expected added node NOT permitted'); |
||||
}); |
||||
|
||||
it('should allow new admin account to add node to whitelist', async () => { |
||||
await adminContract.addAdmin(accounts[2]); |
||||
|
||||
await rulesContract.addEnode(node1High, node1Low, node1Host, node1Port, { from: accounts[2] }); |
||||
|
||||
let permitted = await rulesContract.enodeInWhitelist(node1High, node1Low, node1Host, node1Port); |
||||
assert.ok(permitted, 'expected added node permitted'); |
||||
}); |
||||
}); |
@ -1,155 +0,0 @@ |
||||
const IngressContract = artifacts.require('Ingress.sol'); |
||||
const RulesContract = artifacts.require('Rules.sol'); |
||||
const AdminContract = artifacts.require('Admin.sol'); |
||||
|
||||
// Contract keys
|
||||
const RULES_NAME = "0x72756c6573000000000000000000000000000000000000000000000000000000"; |
||||
const ADMIN_NAME = "0x61646d696e697374726174696f6e000000000000000000000000000000000000"; |
||||
|
||||
var node1High = "0x9bd359fdc3a2ed5df436c3d8914b1532740128929892092b7fcb320c1b62f375"; |
||||
var node1Low = "0x2e1092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
var node1Host = "0x0000000000000000000011119bd359fd"; |
||||
var node1Port = 30303; |
||||
|
||||
var node2High = "0x892092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
var node2Low = "0xcb320c1b62f37892092b7f59bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
var node2Host = "0x0000000000000000000011119bd359fd"; |
||||
var node2Port = 30304; |
||||
|
||||
var node3High = "0x765092b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
var node3Low = "0x920982b7fcb320c1b62f3759bd359fdc3a2ed5df436c3d8914b1532740128929"; |
||||
var node3Host = "0x0000000000000000000011117fc359fd"; |
||||
var node3Port = 30305; |
||||
|
||||
var newAdmin = "f17f52151EbEF6C7334FAD080c5704D77216b732"; |
||||
|
||||
contract("Rules", () => { |
||||
let ingressContract; |
||||
let rulesContract; |
||||
let adminContract; |
||||
|
||||
before(async () => { |
||||
ingressContract = await IngressContract.new(); |
||||
adminContract = await AdminContract.new(); |
||||
result = await ingressContract.setContractAddress(ADMIN_NAME, adminContract.address); |
||||
rulesContract = await RulesContract.new(ingressContract.address); |
||||
}); |
||||
|
||||
it('Should NOT permit any node when none have been added', async () => { |
||||
ingressContract = await IngressContract.new(); |
||||
result = await ingressContract.setContractAddress(ADMIN_NAME, adminContract.address); |
||||
rulesContract = await RulesContract.new(ingressContract.address); |
||||
|
||||
let permitted = await rulesContract.enodeAllowed(node1High, node1Low, node1Host, node1Port); |
||||
assert.equal(permitted, false, 'expected node NOT permitted'); |
||||
}); |
||||
|
||||
it('Should NOT be able to remove enode from empty list', async () => { |
||||
await rulesContract.removeEnode(node3High, node3Low, node3Host, node3Port); |
||||
let permitted = await rulesContract.enodeAllowed(node3High, node3Low, node3Host, node3Port); |
||||
assert.equal(permitted, false, 'expected removed node NOT permitted'); |
||||
}); |
||||
|
||||
it('Should compute key', async () => { |
||||
let key1 = await rulesContract.computeKey(node1High, node1Low, node1Host, node1Port); |
||||
let key2 = await rulesContract.computeKey(node1High, node1Low, node1Host, node1Port); |
||||
assert.equal(key1, key2, "computed keys should be the same"); |
||||
|
||||
let key3 = await rulesContract.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 () => { |
||||
// Register the Rules contract to permit adding enodes
|
||||
await ingressContract.setContractAddress(RULES_NAME, rulesContract.address); |
||||
|
||||
// add node1
|
||||
await rulesContract.addEnode(node1High, node1Low, node1Host, node1Port); |
||||
let permitted = await rulesContract.enodeAllowed(node1High, node1Low, node1Host, node1Port); |
||||
assert.equal(permitted, true, 'expected node added to be permitted'); |
||||
|
||||
// add node2
|
||||
await rulesContract.addEnode(node2High, node2Low, node2Host, node2Port); |
||||
permitted = await rulesContract.enodeAllowed(node2High, node2Low, node2Host, node2Port); |
||||
assert.equal(permitted, true, 'expected node 2 added to be permitted'); |
||||
|
||||
// first one still permitted
|
||||
permitted = await rulesContract.enodeAllowed(node1High, node1Low, node1Host, node1Port); |
||||
assert.equal(permitted, true, 'expected node 1 added to be permitted'); |
||||
|
||||
// add node3
|
||||
await rulesContract.addEnode(node3High, node3Low, node3Host, node3Port); |
||||
permitted = await rulesContract.enodeAllowed(node3High, node3Low, node3Host, node3Port); |
||||
assert.equal(permitted, true, 'expected node 3 added to be permitted'); |
||||
|
||||
// node1 still permitted
|
||||
permitted = await rulesContract.enodeAllowed(node1High, node1Low, node1Host, node1Port); |
||||
assert.equal(permitted, true, 'expected node 1 added to be permitted'); |
||||
// node2 still permitted
|
||||
permitted = await rulesContract.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 rulesContract.connectionAllowed(node1High, node1Low, node1Host, node1Port, node2High, node2Low, node2Host, node2Port); |
||||
assert.equal(permitted, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 'expected permitted node1 <> node2'); |
||||
permitted = await rulesContract.connectionAllowed(node1High, node1Low, node1Host, node1Port, node3High, node3Low, node3Host, node3Port); |
||||
assert.equal(permitted, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 'expected permitted node1 <> node3'); |
||||
permitted = await rulesContract.connectionAllowed(node2High, node2Low, node2Host, node2Port, node3High, node3Low, node3Host, node3Port); |
||||
assert.equal(permitted, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 'expected permitted node2 <> node3'); |
||||
}); |
||||
|
||||
it('Should remove END node from the whitelist and then NOT permit that node', async () => { |
||||
await rulesContract.removeEnode(node3High, node3Low, node3Host, node3Port); |
||||
let permitted = await rulesContract.enodeAllowed(node3High, node3Low, node3Host, node3Port); |
||||
assert.equal(permitted, false, 'expected removed node NOT permitted'); |
||||
|
||||
permitted = await rulesContract.connectionAllowed(node3High, node3Low, node3Host, node3Port, node2High, node2Low, node2Host, node2Port); |
||||
assert.equal(permitted, "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 'expected source disallowed since it was removed'); |
||||
|
||||
let result = await rulesContract.getKeyCount(); |
||||
assert.equal(result, 2, "expected number of nodes"); |
||||
}); |
||||
|
||||
it('Should remove a node from the whitelist and then NOT permit that node', async () => { |
||||
await rulesContract.removeEnode(node1High, node1Low, node1Host, node1Port); |
||||
let permitted = await rulesContract.enodeAllowed(node1High, node1Low, node1Host, node1Port); |
||||
assert.equal(permitted, false, 'expected removed node NOT permitted'); |
||||
|
||||
permitted = await rulesContract.connectionAllowed(node1High, node1Low, node1Host, node1Port, node2High, node2Low, node2Host, node2Port); |
||||
assert.equal(permitted, "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 'expected source disallowed since it was removed'); |
||||
|
||||
let result = await rulesContract.getKeyCount(); |
||||
assert.equal(result, 1, "expected number of nodes"); |
||||
}); |
||||
|
||||
it('Should remove FINAL node from the whitelist AND then NOT permit that node AND list now empty', async () => { |
||||
await rulesContract.removeEnode(node2High, node2Low, node2Host, node2Port); |
||||
let permitted = await rulesContract.enodeAllowed(node2High, node2Low, node2Host, node2Port); |
||||
assert.equal(permitted, false, 'expected removed node NOT permitted'); |
||||
|
||||
permitted = await rulesContract.connectionAllowed(node1High, node1Low, node1Host, node1Port, node2High, node2Low, node2Host, node2Port); |
||||
assert.equal(permitted, "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 'expected source disallowed since it was removed'); |
||||
|
||||
let result = await rulesContract.getKeyCount(); |
||||
assert.equal(result, 0, "expected number of nodes"); |
||||
}); |
||||
|
||||
it('Should add a node to the list after it has been emptied', async () => { |
||||
// no nodes in the list
|
||||
let permitted = await rulesContract.enodeAllowed(node2High, node2Low, node2Host, node2Port); |
||||
assert.equal(permitted, false, 'expected removed node NOT permitted'); |
||||
|
||||
permitted = await rulesContract.connectionAllowed(node1High, node1Low, node1Host, node1Port, node2High, node2Low, node2Host, node2Port); |
||||
assert.equal(permitted, "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 'expected source disallowed since it was removed'); |
||||
|
||||
// add node2
|
||||
await rulesContract.addEnode(node2High, node2Low, node2Host, node2Port); |
||||
permitted = await rulesContract.enodeAllowed(node2High, node2Low, node2Host, node2Port); |
||||
assert.equal(permitted, true, 'expected node 2 added to be permitted'); |
||||
|
||||
// should be one node
|
||||
let result = await rulesContract.getKeyCount(); |
||||
assert.equal(result, 1, "expected number of nodes"); |
||||
}); |
||||
}); |
Loading…
Reference in new issue