-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnode_space.sol
123 lines (97 loc) · 4.51 KB
/
node_space.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
pragma solidity 0.5.4;
import "./ownable.sol";
import "./node.sol";
import "./base_space_interfaces.sol";
/**
* NodeSpace
* Seperated from content_space to avoid circular dependencies.
*/
/* -- Revision history --
NodeSpace20190528170100ML: First versioned released
*/
contract NodeSpace is Ownable, INodeSpace {
bytes32 public version ="NodeSpace20190528170100ML"; //class name (max 16), date YYYYMMDD, time HHMMSS and Developer initials XX
address[] public activeNodeAddresses;
bytes[] public activeNodeLocators;
address[] public pendingNodeAddresses;
bytes[] public pendingNodeLocators;
function checkRedundantEntry(address[] memory _addrs, bytes[] memory _locators, address _nodeAddr, bytes memory _nodeLocator) pure internal returns (bool) {
require(_addrs.length == _locators.length);
for (uint i = 0; i < _addrs.length; i++) {
// right now we assume that neither the address or the locator can be used redundantly
if (keccak256(_locators[i]) == keccak256(_nodeLocator) || _addrs[i] == _nodeAddr) {
return true;
}
}
return false;
}
event NodeSubmitted(address addr, bytes locator);
function numActiveNodes() public view returns (uint) {
return activeNodeLocators.length;
}
function numPendingNodes() public view returns (uint) {
return pendingNodeLocators.length;
}
// we assume that this call is made from the submitted node - that is, from their address
function submitNode(bytes memory _locator) public {
require(!checkRedundantEntry(pendingNodeAddresses, pendingNodeLocators, msg.sender, _locator));
require(!checkRedundantEntry(activeNodeAddresses, activeNodeLocators, msg.sender, _locator));
require(pendingNodeAddresses.length < 100); // don't allow *too* much abuse - TODO: what value?
pendingNodeLocators.push(_locator);
pendingNodeAddresses.push(msg.sender);
emit NodeSubmitted(msg.sender, _locator);
}
event NodeApproved(address addr, bytes locator);
function removeNodeInternal(uint nodeOrd, address[] storage _nodeAddresses, bytes[] storage _nodeLocators) internal {
require(nodeOrd < _nodeAddresses.length && nodeOrd < _nodeLocators.length);
if (nodeOrd != _nodeAddresses.length - 1) {
_nodeLocators[nodeOrd] = _nodeLocators[_nodeLocators.length - 1];
_nodeAddresses[nodeOrd] = _nodeAddresses[_nodeAddresses.length - 1];
}
delete _nodeLocators[_nodeLocators.length - 1];
_nodeLocators.length--;
delete _nodeAddresses[_nodeAddresses.length - 1];
_nodeAddresses.length--;
}
function approveNode(address _nodeAddr) public onlyOwner {
bool found = false;
for (uint i = 0; i < pendingNodeAddresses.length; i++) {
if (pendingNodeAddresses[i] == _nodeAddr) {
activeNodeAddresses.push(pendingNodeAddresses[i]);
activeNodeLocators.push(pendingNodeLocators[i]);
emit NodeApproved(pendingNodeAddresses[i], pendingNodeLocators[i]);
removeNodeInternal(i, pendingNodeAddresses, pendingNodeLocators);
found = true;
break;
}
}
require(found);
}
event AddNode(address ownerAddr, address nodeAddr);
// direct method for owner to add node(s)
function addNode(address _nodeAddr, bytes memory _locator) public onlyOwner {
require(!checkRedundantEntry(activeNodeAddresses, activeNodeLocators, _nodeAddr, _locator));
activeNodeAddresses.push(_nodeAddr);
activeNodeLocators.push(_locator);
emit AddNode(msg.sender, _nodeAddr);
}
event RemoveNode (address ownerAddr, address nodeAddr);
// direct method for owner to remove node(s)
function removeNode(address _nodeAddr) public onlyOwner {
for (uint i = 0; i < activeNodeAddresses.length; i++) {
if (activeNodeAddresses[i] == _nodeAddr) {
removeNodeInternal(i, activeNodeAddresses, activeNodeLocators);
emit RemoveNode(msg.sender, _nodeAddr);
}
}
}
// check whether an address - which should represent a content fabric node - can confirm (publish?) a content object
function canNodePublish(address candidate) external view returns (bool) {
for (uint i = 0; i < activeNodeAddresses.length; i++) {
if (activeNodeAddresses[i] == candidate) {
return true;
}
}
return false;
}
}