Skip to content
This repository has been archived by the owner on Jan 16, 2023. It is now read-only.

Commit

Permalink
PIE-1515: Rules contract with linked list library (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucassaldanha committed Apr 18, 2019
1 parent 643f4bb commit 672dbb1
Show file tree
Hide file tree
Showing 12 changed files with 475 additions and 490 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Idea
.idea

# Directories used by tools like mocha & istanbul
coverage
shippable
Expand Down
5 changes: 4 additions & 1 deletion .soliumrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
],
"blank-lines": "error",
"no-trailing-whitespace": "error",
"arg-overflow": "error"
"arg-overflow": [
"error",
4
]
}
}
14 changes: 7 additions & 7 deletions contracts/AdminList.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
}
}
}
31 changes: 31 additions & 0 deletions contracts/ExposedRulesList.sol
Original file line number Diff line number Diff line change
@@ -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);
}
}
186 changes: 31 additions & 155 deletions contracts/Rules.sol
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down Expand Up @@ -70,7 +55,6 @@ contract Rules is RulesProxy {
return true;
}

// RULES - IS CONNECTION ALLOWED
function connectionAllowed(
bytes32 sourceEnodeHigh,
bytes32 sourceEnodeLow,
Expand All @@ -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,
Expand All @@ -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 {
Expand Down
Loading

0 comments on commit 672dbb1

Please sign in to comment.