diff --git a/.gitignore b/.gitignore index 9755d48c..1364d069 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ yarn-debug.log* yarn-error.log* lerna-debug.log* +# Idea +.idea + # Directories used by tools like mocha & istanbul coverage shippable diff --git a/.soliumrc.json b/.soliumrc.json index 9d7fba8e..a8ac728e 100644 --- a/.soliumrc.json +++ b/.soliumrc.json @@ -18,6 +18,9 @@ ], "blank-lines": "error", "no-trailing-whitespace": "error", - "arg-overflow": "error" + "arg-overflow": [ + "error", + 4 + ] } } \ No newline at end of file diff --git a/contracts/AdminList.sol b/contracts/AdminList.sol index 5c0aead0..48a8f691 100644 --- a/contracts/AdminList.sol +++ b/contracts/AdminList.sol @@ -17,7 +17,7 @@ contract AdminList { } function add(address _address) internal returns (bool) { - return list.push(uint(_address), true); + return list.push(uint(_address), false); } function remove(address _address) internal returns (bool) { @@ -43,13 +43,13 @@ contract AdminList { break; } else { counter++; - pointer = prev; + pointer = next; } } else { break; } //Getting rid of unused variable warning - next; + prev; } if (hasFound) { @@ -78,16 +78,16 @@ contract AdminList { allAddresses[counter++] = address(pointer); } - if (prev != 0) { - pointer = prev; + if (next != 0) { + pointer = next; } else { hasNext = false; } } //Getting rid of unused variable warning - next; + prev; } return allAddresses; } -} \ No newline at end of file +} diff --git a/contracts/ExposedRulesList.sol b/contracts/ExposedRulesList.sol new file mode 100644 index 00000000..ecee2eca --- /dev/null +++ b/contracts/ExposedRulesList.sol @@ -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); + } +} \ No newline at end of file diff --git a/contracts/Rules.sol b/contracts/Rules.sol index cdfa07d2..d0041aa5 100644 --- a/contracts/Rules.sol +++ b/contracts/Rules.sol @@ -1,33 +1,18 @@ pragma solidity >=0.4.22 <0.6.0; import "./RulesProxy.sol"; +import "./RulesList.sol"; import "./Ingress.sol"; import "./Admin.sol"; -contract Rules is RulesProxy { +contract Rules is RulesProxy, RulesList { // on read-only mode rules can't be added/removed bool readOnlyMode = false; // version of this contract: semver like 1.2.14 represented like 001002014 uint version = 1000000; - struct Enode { - bytes next; - bytes prev; - bytes32 enodeHigh; - bytes32 enodeLow; - bytes16 enodeHost; - uint16 enodePort; - } - mapping(bytes => Enode) private whitelist; // should there be a size for the whitelists? - - // keys - uint countWhitelist; - bytes[] keysWhitelist; - // head of linked list - bytes headWhitelist; - address private ingressContractAddress; modifier onlyOnEditMode() { @@ -70,7 +55,6 @@ contract Rules is RulesProxy { return true; } - // RULES - IS CONNECTION ALLOWED function connectionAllowed( bytes32 sourceEnodeHigh, bytes32 sourceEnodeLow, @@ -82,12 +66,12 @@ contract Rules is RulesProxy { uint16 destinationEnodePort ) public view returns (bytes32) { if ( - enodeAllowed( + enodeInWhitelist ( sourceEnodeHigh, sourceEnodeLow, sourceEnodeIp, sourceEnodePort - ) && enodeAllowed( + ) && enodeInWhitelist( destinationEnodeHigh, destinationEnodeLow, destinationEnodeIp, @@ -100,162 +84,54 @@ contract Rules is RulesProxy { } } - // RULES - IS ENODE ALLOWED - function enodeAllowed( - bytes32 sourceEnodeHigh, - bytes32 sourceEnodeLow, - bytes16 sourceEnodeIp, - uint16 sourceEnodePort - ) public view returns (bool){ - bytes memory key = computeKey( - sourceEnodeHigh, - sourceEnodeLow, - sourceEnodeIp, - sourceEnodePort - ); - Enode storage whitelistSource = whitelist[key]; - if (enodeExists(whitelistSource)) { - return true; - } + function enodeInWhitelist( + bytes32 enodeHigh, + bytes32 enodeLow, + bytes16 ip, + uint16 port + ) public view returns (bool) { + return exists(enodeHigh, enodeLow, ip, port); } - // RULES MODIFIERS - ADD function addEnode( bytes32 enodeHigh, bytes32 enodeLow, - bytes16 enodeIp, - uint16 enodePort + bytes16 ip, + uint16 port ) public onlyAdmin onlyOnEditMode returns (bool) { - bytes memory key = computeKey( - enodeHigh, - enodeLow, - enodeIp, - enodePort - ); - // return false if already in the list - if (enodeExists(whitelist[key])) { - return false; - } - bytes memory next; - bytes memory prev; - if (countWhitelist == 0) { - next = key; - prev = key; - headWhitelist = key; - } else { - 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; + bool added = add(enodeHigh, enodeLow, ip, port); - triggerRulesChangeEvent(false); + if (added) { + triggerRulesChangeEvent(false); + } - return true; + return added; } - // RULES MODIFIERS - REMOVE function removeEnode( bytes32 enodeHigh, bytes32 enodeLow, - bytes16 enodeIp, - uint16 enodePort + bytes16 ip, + uint16 port ) public onlyAdmin onlyOnEditMode returns (bool) { - bytes memory key = computeKey( - enodeHigh, - enodeLow, - enodeIp, - enodePort - ); - if (!enodeExists(whitelist[key])) { - return false; - } - Enode memory e = whitelist[key]; + bool removed = remove(enodeHigh, enodeLow, ip, port); - // update keys - for (uint i = 0; i < keysWhitelist.length; i++) { - if (bytesEqual(keysWhitelist[i], key)) { - keysWhitelist[i] = keysWhitelist[keysWhitelist.length - 1]; - delete keysWhitelist[keysWhitelist.length - 1]; - keysWhitelist.length--; - } + if (removed) { + triggerRulesChangeEvent(true); } - // update linked list - headWhitelist = e.next; - whitelist[e.prev].next = e.next; - whitelist[e.next].prev = e.prev; - countWhitelist = countWhitelist - 1; - delete whitelist[key]; - - triggerRulesChangeEvent(true); - - return true; + return removed; } - function bytesEqual(bytes memory a, bytes memory b) public pure returns(bool) { - - if (a.length != b.length) { - return false; - } else { - // check each byte - for (uint j = 0; j < b.length; j++) { - if (a[j] != b[j]) { - return false; - } - } - } - return true; + function getSize() public view returns (uint) { + return size(); } - // RULES - LINKED LIST - function getHeadEnode() public view returns (bytes memory, bytes memory, bytes32, bytes32, bytes16, uint16) { - require(countWhitelist > 0, "Whitelist is empty"); - return getEnode(headWhitelist); - } - - 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 getWhitelistKey(uint index) public view returns(bytes memory) { - return keysWhitelist[index]; - } - - 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 computeKey( - bytes32 enodeHigh, - bytes32 enodeLow, - bytes16 enodeHostIp, - uint16 enodePort - ) public pure returns (bytes memory) { - return abi.encode( - enodeHigh, - enodeLow, - enodeHostIp, - enodePort - ); - } - - function getKeyCount() public view returns (uint) { - return keysWhitelist.length; + function getByIndex(uint index) public view returns (bytes32 enodeHigh, bytes32 enodeLow, bytes16 ip, uint16 port) { + (bool _exists, bytes32 _enodeHigh, bytes32 _enodeLow, bytes16 _ip, uint16 _port) = get(index); + if (_exists) { + return (_enodeHigh, _enodeLow, _ip, _port); + } } function triggerRulesChangeEvent(bool addsRestrictions) public { diff --git a/contracts/RulesList.sol b/contracts/RulesList.sol new file mode 100644 index 00000000..63385581 --- /dev/null +++ b/contracts/RulesList.sol @@ -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)); + } + } +} diff --git a/genesis.json b/genesis.json index c0782bb6..68a2097e 100644 --- a/genesis.json +++ b/genesis.json @@ -34,7 +34,7 @@ "0x0000000000000000000000000000000000009999": { "comment": "Ingress smart contract", "balance": "0", - "code": "608060405234801561001057600080fd5b506004361061009e5760003560e01c80634dc3fefc116100665780634dc3fefc146101b45780638aa10435146101d5578063a43e04d8146101dd578063e001f8411461020e578063fe9fbb801461023a5761009e565b80630d2020dd146100a357806310d9042e146100dc57806311601306146101345780631e7c27cb1461014e5780633620b1df14610156575b600080fd5b6100c0600480360360208110156100b957600080fd5b5035610260565b604080516001600160a01b039092168252519081900360200190f35b6100e46102d9565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610120578181015183820152602001610108565b505050509050019250505060405180910390f35b61013c610332565b60408051918252519081900360200190f35b61013c610338565b61013c600480360361010081101561016d57600080fd5b508035906020810135906001600160801b0319604082013581169161ffff606082013581169260808301359260a08101359260c08201359092169160e0909101351661033e565b6101d3600480360360208110156101ca57600080fd5b5035151561044b565b005b61013c6104e0565b6101fa600480360360208110156101f357600080fd5b50356104e6565b604080519115158252519081900360200190f35b6101fa6004803603604081101561022457600080fd5b50803590602001356001600160a01b03166106f7565b6101fa6004803603602081101561025057600080fd5b50356001600160a01b03166108cb565b6000816102b75760408051600160e51b62461bcd02815260206004820181905260248201527f436f6e7472616374206e616d65206d757374206e6f7420626520656d7074792e604482015290519081900360640190fd5b506000818152600460205260409020600101546001600160a01b03165b919050565b6060600380548060200260200160405190810160405280929190818152602001828054801561032757602002820191906000526020600020905b815481526020019060010190808311610313575b505050505090505b90565b60015481565b60025481565b6000806001600160a01b0316610355600154610260565b6001600160a01b0316141561037257506001600160ff1b0361043f565b60018054600090815260046020818152604092839020909301548251600160e01b633620b1df0281529182018d9052602482018c90526001600160801b0319808c16604484015261ffff808c166064850152608484018b905260a484018a905290881660c4840152861660e483015291516001600160a01b0390921692633620b1df9261010480840193829003018186803b15801561041057600080fd5b505afa158015610424573d6000803e3d6000fd5b505050506040513d602081101561043a57600080fd5b505190505b98975050505050505050565b60018054600090815260046020526040902001546001600160a01b031633146104a857604051600160e51b62461bcd0281526004018080602001828103825260338152602001806109eb6033913960400191505060405180910390fd5b60408051821515815290517f66120f934b66d52127e448f8e94c2460ea62821335e0dd18e89ed38a4a09b4139181900360200190a150565b60005490565b60008161053d5760408051600160e51b62461bcd02815260206004820181905260248201527f436f6e7472616374206e616d65206d757374206e6f7420626520656d7074792e604482015290519081900360640190fd5b60035461057e57604051600160e51b62461bcd028152600401808060200182810382526047815260200180610a496047913960600191505060405180910390fd5b610587336108cb565b6105c557604051600160e51b62461bcd02815260040180806020018281038252602b815260200180610a1e602b913960400191505060405180910390fd5b60005b6003548110156106ee5782600382815481106105e057fe5b906000526020600020015414156106e657600460006003838154811061060257fe5b60009182526020808320909101548352820192909252604001902080546001600160a01b0319908116825560019091018054909116905560038054600019810190811061064b57fe5b90600052602060002001546003828154811061066357fe5b60009182526020909120015560038054600019810190811061068157fe5b6000918252602082200155600380549061069f90600019830161098c565b5060408051600081526020810185905281517fe3d908a1f6d2467f8e7c8198f30125843211345eedb763beb4cdfb7fe728a5af929181900390910190a160019150506102d4565b6001016105c8565b50600092915050565b60008261074e5760408051600160e51b62461bcd02815260206004820181905260248201527f436f6e7472616374206e616d65206d757374206e6f7420626520656d7074792e604482015290519081900360640190fd5b610757336108cb565b61079557604051600160e51b62461bcd02815260040180806020018281038252602b815260200180610a1e602b913960400191505060405180910390fd5b61079d6109b5565b50600083815260046020908152604091829020825180840190935280546001600160a01b0390811684526001909101541690820181905261082f5750604080518082019091523381526001600160a01b0383166020820152600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0184905561083f565b6001600160a01b03831660208201525b600084815260046020908152604091829020835181546001600160a01b03199081166001600160a01b039283161783558584015160019093018054909116928216929092179091558251908616815290810186905281517fe3d908a1f6d2467f8e7c8198f30125843211345eedb763beb4cdfb7fe728a5af929181900390910190a15060019392505050565b6000806001600160a01b03166108e2600254610260565b6001600160a01b031614156108f9575060016102d4565b600254600090815260046020818152604092839020600101548351600160e71b6301fd3f770281526001600160a01b0387811694820194909452935192169263fe9fbb809260248083019392829003018186803b15801561095957600080fd5b505afa15801561096d573d6000803e3d6000fd5b505050506040513d602081101561098357600080fd5b505190506102d4565b8154818355818111156109b0576000838152602090206109b09181019083016109cc565b505050565b604080518082019091526000808252602082015290565b61032f91905b808211156109e657600081556001016109d2565b509056fe4f6e6c792052756c657320636f6e74726163742063616e20747269676765722052756c6573206368616e6765206576656e74734e6f7420617574686f72697a656420746f2075706461746520636f6e74726163742072656769737472792e4d7573742068617665206174206c65617374206f6e65207265676973746572656420636f6e747261637420746f20657865637574652064656c657465206f7065726174696f6e2ea165627a7a7230582073f4ef6d66965e70d97731c1ed4cee49d49ddfd40986a754167a282d3bfd050f0029", + "code": "0x608060405234801561001057600080fd5b50600436106100bb576000357c0100000000000000000000000000000000000000000000000000000000900480634dc3fefc116100835780634dc3fefc146102805780638aa10435146102b0578063a43e04d8146102ce578063e001f84114610314578063fe9fbb801461037a576100bb565b80630d2020dd146100c057806310d9042e1461012e578063116013061461018d5780631e7c27cb146101ab5780633620b1df146101c9575b600080fd5b6100ec600480360360208110156100d657600080fd5b81019080803590602001909291905050506103d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61013661048e565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561017957808201518184015260208101905061015e565b505050509050019250505060405180910390f35b6101956104e6565b6040518082815260200191505060405180910390f35b6101b36104ec565b6040518082815260200191505060405180910390f35b61026a60048036036101008110156101e057600080fd5b81019080803590602001909291908035906020019092919080356fffffffffffffffffffffffffffffffff19169060200190929190803561ffff169060200190929190803590602001909291908035906020019092919080356fffffffffffffffffffffffffffffffff19169060200190929190803561ffff1690602001909291905050506104f2565b6040518082815260200191505060405180910390f35b6102ae6004803603602081101561029657600080fd5b810190808035151590602001909291905050506106e0565b005b6102b86107da565b6040518082815260200191505060405180910390f35b6102fa600480360360208110156102e457600080fd5b81019080803590602001909291905050506107e3565b604051808215151515815260200191505060405180910390f35b6103606004803603604081101561032a57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ac8565b604051808215151515815260200191505060405180910390f35b6103bc6004803603602081101561039057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e75565b604051808215151515815260200191505060405180910390f35b6000806001028211610450576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f436f6e7472616374206e616d65206d757374206e6f7420626520656d7074792e81525060200191505060405180910390fd5b6004600083815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b606060038054806020026020016040519081016040528092919081815260200182805480156104dc57602002820191906000526020600020905b8154815260200190600101908083116104c8575b5050505050905090565b60015481565b60025481565b60008073ffffffffffffffffffffffffffffffffffffffff166105166001546103d6565b73ffffffffffffffffffffffffffffffffffffffff16141561055d577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60010290506106d4565b60046000600154815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633620b1df8a8a8a8a8a8a8a8a6040518963ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180898152602001888152602001876fffffffffffffffffffffffffffffffff19166fffffffffffffffffffffffffffffffff191681526020018661ffff1661ffff168152602001858152602001848152602001836fffffffffffffffffffffffffffffffff19166fffffffffffffffffffffffffffffffff191681526020018261ffff1661ffff1681526020019850505050505050505060206040518083038186803b15801561069657600080fd5b505afa1580156106aa573d6000803e3d6000fd5b505050506040513d60208110156106c057600080fd5b810190808051906020019092919050505090505b98975050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff1660046000600154815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461079c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603381526020018061106a6033913960400191505060405180910390fd5b7f66120f934b66d52127e448f8e94c2460ea62821335e0dd18e89ed38a4a09b41381604051808215151515815260200191505060405180910390a150565b60008054905090565b600080600102821161085d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f436f6e7472616374206e616d65206d757374206e6f7420626520656d7074792e81525060200191505060405180910390fd5b6000600380549050116108bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260478152602001806110c86047913960600191505060405180910390fd5b6108c433610e75565b610919576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b81526020018061109d602b913960400191505060405180910390fd5b60008090505b600380549050811015610abd57826003828154811061093a57fe5b90600052602060002001541415610ab057600460006003838154811061095c57fe5b90600052602060002001548152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550506003600160038054905003815481106109db57fe5b9060005260206000200154600382815481106109f357fe5b9060005260206000200181905550600360016003805490500381548110610a1657fe5b90600052602060002001600090556003805480919060019003610a399190610fd2565b507fe3d908a1f6d2467f8e7c8198f30125843211345eedb763beb4cdfb7fe728a5af600084604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a16001915050610ac3565b808060010191505061091f565b50600090505b919050565b6000806001028311610b42576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f436f6e7472616374206e616d65206d757374206e6f7420626520656d7074792e81525060200191505060405180910390fd5b610b4b33610e75565b610ba0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b81526020018061109d602b913960400191505060405180910390fd5b610ba8610ffe565b600460008581526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff161415610d215760405180604001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681525090506003849080600181540180825580915050906001820390600052602060002001600090919290919091505550610d5a565b82816020019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b806004600086815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050507fe3d908a1f6d2467f8e7c8198f30125843211345eedb763beb4cdfb7fe728a5af8385604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1600191505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff16610e996002546103d6565b73ffffffffffffffffffffffffffffffffffffffff161415610ebe5760019050610fcd565b60046000600254815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fe9fbb80836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610f8f57600080fd5b505afa158015610fa3573d6000803e3d6000fd5b505050506040513d6020811015610fb957600080fd5b810190808051906020019092919050505090505b919050565b815481835581811115610ff957818360005260206000209182019101610ff89190611044565b5b505050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b61106691905b8082111561106257600081600090555060010161104a565b5090565b9056fe4f6e6c792052756c657320636f6e74726163742063616e20747269676765722052756c6573206368616e6765206576656e74734e6f7420617574686f72697a656420746f2075706461746520636f6e74726163742072656769737472792e4d7573742068617665206174206c65617374206f6e65207265676973746572656420636f6e747261637420746f20657865637574652064656c657465206f7065726174696f6e2ea165627a7a723058204f6dae7867fd92626859171e36427fd13977e560e948075f7dd326404654e9d90029", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0x00000000000000000000000000000000000000000000000000000000000f4240", "0x0000000000000000000000000000000000000000000000000000000000000001": "0x72756c6573000000000000000000000000000000000000000000000000000000", diff --git a/test/test-get-all-enodes.js b/test/test-get-all-enodes.js deleted file mode 100644 index c48497b6..00000000 --- a/test/test-get-all-enodes.js +++ /dev/null @@ -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'); - }); -}); diff --git a/test/test-rules-proxy.js b/test/test-ingress-proxy.js similarity index 100% rename from test/test-rules-proxy.js rename to test/test-ingress-proxy.js diff --git a/test/test-rules-list.js b/test/test-rules-list.js new file mode 100644 index 00000000..dcd8f959 --- /dev/null +++ b/test/test-rules-list.js @@ -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); + }); +}); \ No newline at end of file diff --git a/test/test-rules-permissioning.js b/test/test-rules-permissioning.js new file mode 100644 index 00000000..b9a363b0 --- /dev/null +++ b/test/test-rules-permissioning.js @@ -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'); + }); +}); diff --git a/test/test-rules.js b/test/test-rules.js deleted file mode 100644 index d1e5a471..00000000 --- a/test/test-rules.js +++ /dev/null @@ -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"); - }); -});