diff --git a/.mockery.yaml b/.mockery.yaml index 0b66e272..9b00d38a 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -1,5 +1,4 @@ with-expecter: True -testonly: True dir: pkg/mocks mockname: "Mock{{.InterfaceName}}" outpkg: mocks diff --git a/contracts/src/Nodes.sol b/contracts/src/Nodes.sol index 485ff3e2..5998831c 100644 --- a/contracts/src/Nodes.sol +++ b/contracts/src/Nodes.sol @@ -1,91 +1,162 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.13; +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; -contract Nodes is Ownable { - constructor() Ownable(msg.sender) {} +/** +A NFT contract for XMTP Node Operators. +The deployer of this contract is responsible for minting NFTs and assinging them to node operators. + +All nodes on the network periodically check this contract to determine which nodes they should connect to. + */ +contract Nodes is ERC721, Ownable { + constructor() ERC721("XMTP Node Operator", "XMTP") Ownable(msg.sender) {} + + // uint16 counter so that we cannot create more than 65k IDs + // The ERC721 standard expects the tokenID to be uint256 for standard methods unfortunately + uint16 private _nodeIdCounter; + + // A node, as stored in the internal mapping struct Node { + bytes signingKeyPub; string httpAddress; - uint256 originatorId; bool isHealthy; - // Maybe we want a TLS cert separate from the public key for MTLS authenticated connections? } - event NodeUpdate( - bytes publicKey, - string httpAddress, - uint256 originatorId, - bool isHealthy - ); + struct NodeWithId { + uint16 nodeId; + Node node; + } - // List of public keys - bytes[] publicKeys; + event NodeUpdated(uint256 nodeId, Node node); - // Mapping of publicKey to node - mapping(bytes => Node) public nodes; + // Mapping of token ID to Node + mapping(uint256 => Node) private _nodes; /** - Add a node to the network + Mint a new node NFT and store the metadata in the smart contract */ function addNode( - bytes calldata publicKey, + address to, + bytes calldata signingKeyPub, + string calldata httpAddress + ) public onlyOwner returns (uint16) { + uint16 nodeId = _nodeIdCounter; + _mint(to, nodeId); + _nodes[nodeId] = Node(signingKeyPub, httpAddress, true); + _emitNodeUpdate(nodeId); + _nodeIdCounter++; + + return nodeId; + } + + /** + Override the built in transferFrom function to block NFT owners from transferring + node ownership. + + NFT owners are only allowed to update their HTTP address and MTLS cert. + */ + function transferFrom( + address from, + address to, + uint256 tokenId + ) public override { + require( + _msgSender() == owner(), + "Only the contract owner can transfer Node ownership" + ); + super.transferFrom(from, to, tokenId); + } + + /** + Allow a NFT holder to update the HTTP address of their node + */ + function updateHttpAddress( + uint256 tokenId, string calldata httpAddress - ) public onlyOwner { + ) public { require( - bytes(nodes[publicKey].httpAddress).length == 0, - "Node already exists" + _msgSender() == ownerOf(tokenId), + "Only the owner of the Node NFT can update its http address" ); + _nodes[tokenId].httpAddress = httpAddress; + _emitNodeUpdate(tokenId); + } - require(bytes(httpAddress).length != 0, "HTTP address is required"); + /** + The contract owner may update the health status of the node. - nodes[publicKey] = Node({ - httpAddress: httpAddress, - originatorId: publicKeys.length + 1, - isHealthy: true - }); + No one else is allowed to call this function. + */ + function updateHealth(uint256 tokenId, bool isHealthy) public onlyOwner { + // Make sure that the token exists + _requireOwned(tokenId); + _nodes[tokenId].isHealthy = isHealthy; + _emitNodeUpdate(tokenId); + } - publicKeys.push(publicKey); + /** + Get a list of healthy nodes with their ID and metadata + */ + function healthyNodes() public view returns (NodeWithId[] memory) { + uint16 totalNodeCount = _nodeIdCounter; + uint256 healthyCount = 0; - emit NodeUpdate(publicKey, httpAddress, publicKeys.length, true); + // First, count the number of healthy nodes + for (uint256 i = 0; i < totalNodeCount; i++) { + if (_nodeExists(i) && _nodes[i].isHealthy) { + healthyCount++; + } + } + + // Create an array to store healthy nodes + NodeWithId[] memory healthyNodesList = new NodeWithId[](healthyCount); + uint256 currentIndex = 0; + + // Populate the array with healthy nodes + for (uint16 i = 0; i < totalNodeCount; i++) { + if (_nodeExists(i) && _nodes[i].isHealthy) { + healthyNodesList[currentIndex] = NodeWithId({ + nodeId: i, + node: _nodes[i] + }); + currentIndex++; + } + } + + return healthyNodesList; } /** - The contract owner can use this function to mark a node as unhealthy - triggering all other nodes to stop replicating to/from this node + Get all nodes regardless of their health status */ - function markNodeUnhealthy(bytes calldata publicKey) public onlyOwner { - require( - bytes(nodes[publicKey].httpAddress).length != 0, - "Node does not exist" - ); - nodes[publicKey].isHealthy = false; + function allNodes() public view returns (NodeWithId[] memory) { + uint16 totalNodeCount = _nodeIdCounter; + NodeWithId[] memory allNodesList = new NodeWithId[](totalNodeCount); - emit NodeUpdate( - publicKey, - nodes[publicKey].httpAddress, - nodes[publicKey].originatorId, - false - ); + for (uint16 i = 0; i < totalNodeCount; i++) { + allNodesList[i] = NodeWithId({nodeId: i, node: _nodes[i]}); + } + + return allNodesList; } /** - The contract owner can use this function to mark a node as healthy - triggering all other nodes to + Get a node's metadata by ID */ - function markNodeHealthy(bytes calldata publicKey) public onlyOwner { - require( - bytes(nodes[publicKey].httpAddress).length != 0, - "Node does not exist" - ); - nodes[publicKey].isHealthy = true; + function getNode(uint256 tokenId) public view returns (Node memory) { + _requireOwned(tokenId); + return _nodes[tokenId]; + } - emit NodeUpdate( - publicKey, - nodes[publicKey].httpAddress, - nodes[publicKey].originatorId, - true - ); + function _emitNodeUpdate(uint256 tokenId) private { + emit NodeUpdated(tokenId, _nodes[tokenId]); + } + + function _nodeExists(uint256 tokenId) private view returns (bool) { + address owner = _ownerOf(tokenId); + return owner != address(0); } } diff --git a/contracts/test/GroupMessage.t.sol b/contracts/test/GroupMessage.t.sol index d61c364d..64d7c122 100644 --- a/contracts/test/GroupMessage.t.sol +++ b/contracts/test/GroupMessage.t.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.13; import {Test, console} from "forge-std/Test.sol"; import {GroupMessages} from "../src/GroupMessages.sol"; -contract CounterTest is Test { +contract GroupMessagesTest is Test { GroupMessages public groupMessages; function setUp() public { diff --git a/contracts/test/Nodes.sol b/contracts/test/Nodes.sol new file mode 100644 index 00000000..d7d742bf --- /dev/null +++ b/contracts/test/Nodes.sol @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Test, console} from "forge-std/Test.sol"; +import {Nodes} from "../src/Nodes.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; + +contract NodesTest is Test { + Nodes public nodes; + + function setUp() public { + nodes = new Nodes(); + } + + function _genBytes(uint32 length) internal pure returns (bytes memory) { + bytes memory message = new bytes(length); + for (uint256 i = 0; i < length; i++) { + message[i] = bytes1(uint8(i % 256)); + } + + return message; + } + + function _genString(uint32 length) internal pure returns (string memory) { + return string(_genBytes(length)); + } + + function _randomNode( + bool isHealthy + ) internal pure returns (Nodes.Node memory) { + return + Nodes.Node({ + signingKeyPub: _genBytes(32), + httpAddress: _genString(32), + isHealthy: isHealthy + }); + } + + function test_canAddNode() public { + Nodes.Node memory node = _randomNode(true); + + address operatorAddress = vm.randomAddress(); + + uint16 nodeId = nodes.addNode( + operatorAddress, + node.signingKeyPub, + node.httpAddress + ); + + vm.assertEq(nodes.ownerOf(nodeId), operatorAddress); + vm.assertEq(nodes.getNode(nodeId).signingKeyPub, node.signingKeyPub); + vm.assertEq(nodes.getNode(nodeId).httpAddress, node.httpAddress); + vm.assertEq(nodes.getNode(nodeId).isHealthy, true); + } + + function test_canAddMultiple() public { + Nodes.Node memory node1 = _randomNode(true); + Nodes.Node memory node2 = _randomNode(true); + Nodes.Node memory node3 = _randomNode(true); + + address operator1 = vm.randomAddress(); + address operator2 = vm.randomAddress(); + address operator3 = vm.randomAddress(); + + uint16 node1Id = nodes.addNode( + operator1, + node1.signingKeyPub, + node1.httpAddress + ); + nodes.addNode(operator2, node2.signingKeyPub, node2.httpAddress); + nodes.addNode(operator3, node3.signingKeyPub, node3.httpAddress); + + Nodes.NodeWithId[] memory healthyNodes = nodes.healthyNodes(); + vm.assertTrue(healthyNodes.length == 3); + + nodes.updateHealth(node1Id, false); + healthyNodes = nodes.healthyNodes(); + vm.assertTrue(healthyNodes.length == 2); + } + + function test_canMarkUnhealthy() public { + Nodes.Node memory node = _randomNode(true); + address operator = vm.randomAddress(); + + uint16 nodeId = nodes.addNode( + operator, + node.signingKeyPub, + node.httpAddress + ); + + nodes.updateHealth(nodeId, false); + + vm.assertEq(nodes.getNode(nodeId).isHealthy, false); + vm.assertEq(nodes.healthyNodes().length, 0); + } + + function testFail_ownerCannotUpdateHealth() public { + vm.expectRevert(Ownable.OwnableUnauthorizedAccount.selector); + Nodes.Node memory node = _randomNode(true); + address operator = vm.randomAddress(); + + uint16 nodeId = nodes.addNode( + operator, + node.signingKeyPub, + node.httpAddress + ); + + vm.prank(operator); + nodes.updateHealth(nodeId, false); + } + + function testFail_ownerCannotTransfer() public { + Nodes.Node memory node = _randomNode(true); + address operator = vm.randomAddress(); + + uint16 nodeId = nodes.addNode( + operator, + node.signingKeyPub, + node.httpAddress + ); + + vm.prank(operator); + nodes.safeTransferFrom(operator, vm.randomAddress(), uint256(nodeId)); + } + + function test_canChangeHttpAddress() public { + Nodes.Node memory node = _randomNode(true); + address operator = vm.randomAddress(); + + uint16 nodeId = nodes.addNode( + operator, + node.signingKeyPub, + node.httpAddress + ); + + vm.prank(operator); + nodes.updateHttpAddress(nodeId, "new-http-address"); + + vm.assertEq(nodes.getNode(nodeId).httpAddress, "new-http-address"); + } + + function testFail_cannotChangeOtherHttpAddress() public { + vm.expectRevert( + "Only the owner of the Node NFT can update its http address" + ); + + Nodes.Node memory node = _randomNode(true); + address operator = vm.randomAddress(); + + uint16 nodeId = nodes.addNode( + operator, + node.signingKeyPub, + node.httpAddress + ); + + vm.prank(vm.randomAddress()); + nodes.updateHttpAddress(nodeId, "new-http-address"); + } +} diff --git a/pkg/abis/nodes.go b/pkg/abis/nodes.go index 1f91c859..e5f3b4a2 100644 --- a/pkg/abis/nodes.go +++ b/pkg/abis/nodes.go @@ -29,9 +29,22 @@ var ( _ = abi.ConvertType ) +// NodesNode is an auto generated low-level Go binding around an user-defined struct. +type NodesNode struct { + SigningKeyPub []byte + HttpAddress string + IsHealthy bool +} + +// NodesNodeWithId is an auto generated low-level Go binding around an user-defined struct. +type NodesNodeWithId struct { + NodeId uint16 + Node NodesNode +} + // NodesMetaData contains all meta data concerning the Nodes contract. var NodesMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addNode\",\"inputs\":[{\"name\":\"publicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"httpAddress\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"markNodeHealthy\",\"inputs\":[{\"name\":\"publicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"markNodeUnhealthy\",\"inputs\":[{\"name\":\"publicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"nodes\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"httpAddress\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"originatorId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"isHealthy\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"NodeUpdate\",\"inputs\":[{\"name\":\"publicKey\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"httpAddress\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"},{\"name\":\"originatorId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"isHealthy\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"OwnableInvalidOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableUnauthorizedAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addNode\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"signingKeyPub\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"httpAddress\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"allNodes\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple[]\",\"internalType\":\"structNodes.NodeWithId[]\",\"components\":[{\"name\":\"nodeId\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"node\",\"type\":\"tuple\",\"internalType\":\"structNodes.Node\",\"components\":[{\"name\":\"signingKeyPub\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"httpAddress\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"isHealthy\",\"type\":\"bool\",\"internalType\":\"bool\"}]}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"approve\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"balanceOf\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApproved\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getNode\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structNodes.Node\",\"components\":[{\"name\":\"signingKeyPub\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"httpAddress\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"isHealthy\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"healthyNodes\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple[]\",\"internalType\":\"structNodes.NodeWithId[]\",\"components\":[{\"name\":\"nodeId\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"node\",\"type\":\"tuple\",\"internalType\":\"structNodes.Node\",\"components\":[{\"name\":\"signingKeyPub\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"httpAddress\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"isHealthy\",\"type\":\"bool\",\"internalType\":\"bool\"}]}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isApprovedForAll\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"name\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ownerOf\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTransferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTransferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setApprovalForAll\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"symbol\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"tokenURI\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateHealth\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"isHealthy\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateHttpAddress\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"httpAddress\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Approval\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ApprovalForAll\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NodeUpdated\",\"inputs\":[{\"name\":\"nodeId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"node\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structNodes.Node\",\"components\":[{\"name\":\"signingKeyPub\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"httpAddress\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"isHealthy\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Transfer\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"ERC721IncorrectOwner\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC721InsufficientApproval\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ERC721InvalidApprover\",\"inputs\":[{\"name\":\"approver\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC721InvalidOperator\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC721InvalidOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC721InvalidReceiver\",\"inputs\":[{\"name\":\"receiver\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC721InvalidSender\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC721NonexistentToken\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"OwnableInvalidOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableUnauthorizedAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]}]", } // NodesABI is the input ABI used to generate the binding from. @@ -180,54 +193,221 @@ func (_Nodes *NodesTransactorRaw) Transact(opts *bind.TransactOpts, method strin return _Nodes.Contract.contract.Transact(opts, method, params...) } -// Nodes is a free data retrieval call binding the contract method 0x404608bd. +// AllNodes is a free data retrieval call binding the contract method 0x02f6f1ba. +// +// Solidity: function allNodes() view returns((uint16,(bytes,string,bool))[]) +func (_Nodes *NodesCaller) AllNodes(opts *bind.CallOpts) ([]NodesNodeWithId, error) { + var out []interface{} + err := _Nodes.contract.Call(opts, &out, "allNodes") + + if err != nil { + return *new([]NodesNodeWithId), err + } + + out0 := *abi.ConvertType(out[0], new([]NodesNodeWithId)).(*[]NodesNodeWithId) + + return out0, err + +} + +// AllNodes is a free data retrieval call binding the contract method 0x02f6f1ba. +// +// Solidity: function allNodes() view returns((uint16,(bytes,string,bool))[]) +func (_Nodes *NodesSession) AllNodes() ([]NodesNodeWithId, error) { + return _Nodes.Contract.AllNodes(&_Nodes.CallOpts) +} + +// AllNodes is a free data retrieval call binding the contract method 0x02f6f1ba. +// +// Solidity: function allNodes() view returns((uint16,(bytes,string,bool))[]) +func (_Nodes *NodesCallerSession) AllNodes() ([]NodesNodeWithId, error) { + return _Nodes.Contract.AllNodes(&_Nodes.CallOpts) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address owner) view returns(uint256) +func (_Nodes *NodesCaller) BalanceOf(opts *bind.CallOpts, owner common.Address) (*big.Int, error) { + var out []interface{} + err := _Nodes.contract.Call(opts, &out, "balanceOf", owner) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address owner) view returns(uint256) +func (_Nodes *NodesSession) BalanceOf(owner common.Address) (*big.Int, error) { + return _Nodes.Contract.BalanceOf(&_Nodes.CallOpts, owner) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address owner) view returns(uint256) +func (_Nodes *NodesCallerSession) BalanceOf(owner common.Address) (*big.Int, error) { + return _Nodes.Contract.BalanceOf(&_Nodes.CallOpts, owner) +} + +// GetApproved is a free data retrieval call binding the contract method 0x081812fc. +// +// Solidity: function getApproved(uint256 tokenId) view returns(address) +func (_Nodes *NodesCaller) GetApproved(opts *bind.CallOpts, tokenId *big.Int) (common.Address, error) { + var out []interface{} + err := _Nodes.contract.Call(opts, &out, "getApproved", tokenId) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetApproved is a free data retrieval call binding the contract method 0x081812fc. +// +// Solidity: function getApproved(uint256 tokenId) view returns(address) +func (_Nodes *NodesSession) GetApproved(tokenId *big.Int) (common.Address, error) { + return _Nodes.Contract.GetApproved(&_Nodes.CallOpts, tokenId) +} + +// GetApproved is a free data retrieval call binding the contract method 0x081812fc. +// +// Solidity: function getApproved(uint256 tokenId) view returns(address) +func (_Nodes *NodesCallerSession) GetApproved(tokenId *big.Int) (common.Address, error) { + return _Nodes.Contract.GetApproved(&_Nodes.CallOpts, tokenId) +} + +// GetNode is a free data retrieval call binding the contract method 0x4f0f4aa9. +// +// Solidity: function getNode(uint256 tokenId) view returns((bytes,string,bool)) +func (_Nodes *NodesCaller) GetNode(opts *bind.CallOpts, tokenId *big.Int) (NodesNode, error) { + var out []interface{} + err := _Nodes.contract.Call(opts, &out, "getNode", tokenId) + + if err != nil { + return *new(NodesNode), err + } + + out0 := *abi.ConvertType(out[0], new(NodesNode)).(*NodesNode) + + return out0, err + +} + +// GetNode is a free data retrieval call binding the contract method 0x4f0f4aa9. +// +// Solidity: function getNode(uint256 tokenId) view returns((bytes,string,bool)) +func (_Nodes *NodesSession) GetNode(tokenId *big.Int) (NodesNode, error) { + return _Nodes.Contract.GetNode(&_Nodes.CallOpts, tokenId) +} + +// GetNode is a free data retrieval call binding the contract method 0x4f0f4aa9. +// +// Solidity: function getNode(uint256 tokenId) view returns((bytes,string,bool)) +func (_Nodes *NodesCallerSession) GetNode(tokenId *big.Int) (NodesNode, error) { + return _Nodes.Contract.GetNode(&_Nodes.CallOpts, tokenId) +} + +// HealthyNodes is a free data retrieval call binding the contract method 0x17b5b840. +// +// Solidity: function healthyNodes() view returns((uint16,(bytes,string,bool))[]) +func (_Nodes *NodesCaller) HealthyNodes(opts *bind.CallOpts) ([]NodesNodeWithId, error) { + var out []interface{} + err := _Nodes.contract.Call(opts, &out, "healthyNodes") + + if err != nil { + return *new([]NodesNodeWithId), err + } + + out0 := *abi.ConvertType(out[0], new([]NodesNodeWithId)).(*[]NodesNodeWithId) + + return out0, err + +} + +// HealthyNodes is a free data retrieval call binding the contract method 0x17b5b840. +// +// Solidity: function healthyNodes() view returns((uint16,(bytes,string,bool))[]) +func (_Nodes *NodesSession) HealthyNodes() ([]NodesNodeWithId, error) { + return _Nodes.Contract.HealthyNodes(&_Nodes.CallOpts) +} + +// HealthyNodes is a free data retrieval call binding the contract method 0x17b5b840. +// +// Solidity: function healthyNodes() view returns((uint16,(bytes,string,bool))[]) +func (_Nodes *NodesCallerSession) HealthyNodes() ([]NodesNodeWithId, error) { + return _Nodes.Contract.HealthyNodes(&_Nodes.CallOpts) +} + +// IsApprovedForAll is a free data retrieval call binding the contract method 0xe985e9c5. +// +// Solidity: function isApprovedForAll(address owner, address operator) view returns(bool) +func (_Nodes *NodesCaller) IsApprovedForAll(opts *bind.CallOpts, owner common.Address, operator common.Address) (bool, error) { + var out []interface{} + err := _Nodes.contract.Call(opts, &out, "isApprovedForAll", owner, operator) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsApprovedForAll is a free data retrieval call binding the contract method 0xe985e9c5. +// +// Solidity: function isApprovedForAll(address owner, address operator) view returns(bool) +func (_Nodes *NodesSession) IsApprovedForAll(owner common.Address, operator common.Address) (bool, error) { + return _Nodes.Contract.IsApprovedForAll(&_Nodes.CallOpts, owner, operator) +} + +// IsApprovedForAll is a free data retrieval call binding the contract method 0xe985e9c5. +// +// Solidity: function isApprovedForAll(address owner, address operator) view returns(bool) +func (_Nodes *NodesCallerSession) IsApprovedForAll(owner common.Address, operator common.Address) (bool, error) { + return _Nodes.Contract.IsApprovedForAll(&_Nodes.CallOpts, owner, operator) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. // -// Solidity: function nodes(bytes ) view returns(string httpAddress, uint256 originatorId, bool isHealthy) -func (_Nodes *NodesCaller) Nodes(opts *bind.CallOpts, arg0 []byte) (struct { - HttpAddress string - OriginatorId *big.Int - IsHealthy bool -}, error) { +// Solidity: function name() view returns(string) +func (_Nodes *NodesCaller) Name(opts *bind.CallOpts) (string, error) { var out []interface{} - err := _Nodes.contract.Call(opts, &out, "nodes", arg0) + err := _Nodes.contract.Call(opts, &out, "name") - outstruct := new(struct { - HttpAddress string - OriginatorId *big.Int - IsHealthy bool - }) if err != nil { - return *outstruct, err + return *new(string), err } - outstruct.HttpAddress = *abi.ConvertType(out[0], new(string)).(*string) - outstruct.OriginatorId = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.IsHealthy = *abi.ConvertType(out[2], new(bool)).(*bool) + out0 := *abi.ConvertType(out[0], new(string)).(*string) - return *outstruct, err + return out0, err } -// Nodes is a free data retrieval call binding the contract method 0x404608bd. +// Name is a free data retrieval call binding the contract method 0x06fdde03. // -// Solidity: function nodes(bytes ) view returns(string httpAddress, uint256 originatorId, bool isHealthy) -func (_Nodes *NodesSession) Nodes(arg0 []byte) (struct { - HttpAddress string - OriginatorId *big.Int - IsHealthy bool -}, error) { - return _Nodes.Contract.Nodes(&_Nodes.CallOpts, arg0) +// Solidity: function name() view returns(string) +func (_Nodes *NodesSession) Name() (string, error) { + return _Nodes.Contract.Name(&_Nodes.CallOpts) } -// Nodes is a free data retrieval call binding the contract method 0x404608bd. +// Name is a free data retrieval call binding the contract method 0x06fdde03. // -// Solidity: function nodes(bytes ) view returns(string httpAddress, uint256 originatorId, bool isHealthy) -func (_Nodes *NodesCallerSession) Nodes(arg0 []byte) (struct { - HttpAddress string - OriginatorId *big.Int - IsHealthy bool -}, error) { - return _Nodes.Contract.Nodes(&_Nodes.CallOpts, arg0) +// Solidity: function name() view returns(string) +func (_Nodes *NodesCallerSession) Name() (string, error) { + return _Nodes.Contract.Name(&_Nodes.CallOpts) } // Owner is a free data retrieval call binding the contract method 0x8da5cb5b. @@ -261,67 +441,170 @@ func (_Nodes *NodesCallerSession) Owner() (common.Address, error) { return _Nodes.Contract.Owner(&_Nodes.CallOpts) } -// AddNode is a paid mutator transaction binding the contract method 0x5a48bd1d. +// OwnerOf is a free data retrieval call binding the contract method 0x6352211e. +// +// Solidity: function ownerOf(uint256 tokenId) view returns(address) +func (_Nodes *NodesCaller) OwnerOf(opts *bind.CallOpts, tokenId *big.Int) (common.Address, error) { + var out []interface{} + err := _Nodes.contract.Call(opts, &out, "ownerOf", tokenId) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// OwnerOf is a free data retrieval call binding the contract method 0x6352211e. +// +// Solidity: function ownerOf(uint256 tokenId) view returns(address) +func (_Nodes *NodesSession) OwnerOf(tokenId *big.Int) (common.Address, error) { + return _Nodes.Contract.OwnerOf(&_Nodes.CallOpts, tokenId) +} + +// OwnerOf is a free data retrieval call binding the contract method 0x6352211e. +// +// Solidity: function ownerOf(uint256 tokenId) view returns(address) +func (_Nodes *NodesCallerSession) OwnerOf(tokenId *big.Int) (common.Address, error) { + return _Nodes.Contract.OwnerOf(&_Nodes.CallOpts, tokenId) +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. // -// Solidity: function addNode(bytes publicKey, string httpAddress) returns() -func (_Nodes *NodesTransactor) AddNode(opts *bind.TransactOpts, publicKey []byte, httpAddress string) (*types.Transaction, error) { - return _Nodes.contract.Transact(opts, "addNode", publicKey, httpAddress) +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_Nodes *NodesCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _Nodes.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_Nodes *NodesSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _Nodes.Contract.SupportsInterface(&_Nodes.CallOpts, interfaceId) +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_Nodes *NodesCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _Nodes.Contract.SupportsInterface(&_Nodes.CallOpts, interfaceId) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_Nodes *NodesCaller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _Nodes.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_Nodes *NodesSession) Symbol() (string, error) { + return _Nodes.Contract.Symbol(&_Nodes.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_Nodes *NodesCallerSession) Symbol() (string, error) { + return _Nodes.Contract.Symbol(&_Nodes.CallOpts) +} + +// TokenURI is a free data retrieval call binding the contract method 0xc87b56dd. +// +// Solidity: function tokenURI(uint256 tokenId) view returns(string) +func (_Nodes *NodesCaller) TokenURI(opts *bind.CallOpts, tokenId *big.Int) (string, error) { + var out []interface{} + err := _Nodes.contract.Call(opts, &out, "tokenURI", tokenId) + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + } -// AddNode is a paid mutator transaction binding the contract method 0x5a48bd1d. +// TokenURI is a free data retrieval call binding the contract method 0xc87b56dd. // -// Solidity: function addNode(bytes publicKey, string httpAddress) returns() -func (_Nodes *NodesSession) AddNode(publicKey []byte, httpAddress string) (*types.Transaction, error) { - return _Nodes.Contract.AddNode(&_Nodes.TransactOpts, publicKey, httpAddress) +// Solidity: function tokenURI(uint256 tokenId) view returns(string) +func (_Nodes *NodesSession) TokenURI(tokenId *big.Int) (string, error) { + return _Nodes.Contract.TokenURI(&_Nodes.CallOpts, tokenId) } -// AddNode is a paid mutator transaction binding the contract method 0x5a48bd1d. +// TokenURI is a free data retrieval call binding the contract method 0xc87b56dd. // -// Solidity: function addNode(bytes publicKey, string httpAddress) returns() -func (_Nodes *NodesTransactorSession) AddNode(publicKey []byte, httpAddress string) (*types.Transaction, error) { - return _Nodes.Contract.AddNode(&_Nodes.TransactOpts, publicKey, httpAddress) +// Solidity: function tokenURI(uint256 tokenId) view returns(string) +func (_Nodes *NodesCallerSession) TokenURI(tokenId *big.Int) (string, error) { + return _Nodes.Contract.TokenURI(&_Nodes.CallOpts, tokenId) } -// MarkNodeHealthy is a paid mutator transaction binding the contract method 0x97d6305a. +// AddNode is a paid mutator transaction binding the contract method 0xa0eae81d. // -// Solidity: function markNodeHealthy(bytes publicKey) returns() -func (_Nodes *NodesTransactor) MarkNodeHealthy(opts *bind.TransactOpts, publicKey []byte) (*types.Transaction, error) { - return _Nodes.contract.Transact(opts, "markNodeHealthy", publicKey) +// Solidity: function addNode(address to, bytes signingKeyPub, string httpAddress) returns(uint16) +func (_Nodes *NodesTransactor) AddNode(opts *bind.TransactOpts, to common.Address, signingKeyPub []byte, httpAddress string) (*types.Transaction, error) { + return _Nodes.contract.Transact(opts, "addNode", to, signingKeyPub, httpAddress) } -// MarkNodeHealthy is a paid mutator transaction binding the contract method 0x97d6305a. +// AddNode is a paid mutator transaction binding the contract method 0xa0eae81d. // -// Solidity: function markNodeHealthy(bytes publicKey) returns() -func (_Nodes *NodesSession) MarkNodeHealthy(publicKey []byte) (*types.Transaction, error) { - return _Nodes.Contract.MarkNodeHealthy(&_Nodes.TransactOpts, publicKey) +// Solidity: function addNode(address to, bytes signingKeyPub, string httpAddress) returns(uint16) +func (_Nodes *NodesSession) AddNode(to common.Address, signingKeyPub []byte, httpAddress string) (*types.Transaction, error) { + return _Nodes.Contract.AddNode(&_Nodes.TransactOpts, to, signingKeyPub, httpAddress) } -// MarkNodeHealthy is a paid mutator transaction binding the contract method 0x97d6305a. +// AddNode is a paid mutator transaction binding the contract method 0xa0eae81d. // -// Solidity: function markNodeHealthy(bytes publicKey) returns() -func (_Nodes *NodesTransactorSession) MarkNodeHealthy(publicKey []byte) (*types.Transaction, error) { - return _Nodes.Contract.MarkNodeHealthy(&_Nodes.TransactOpts, publicKey) +// Solidity: function addNode(address to, bytes signingKeyPub, string httpAddress) returns(uint16) +func (_Nodes *NodesTransactorSession) AddNode(to common.Address, signingKeyPub []byte, httpAddress string) (*types.Transaction, error) { + return _Nodes.Contract.AddNode(&_Nodes.TransactOpts, to, signingKeyPub, httpAddress) } -// MarkNodeUnhealthy is a paid mutator transaction binding the contract method 0xf0da65bc. +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. // -// Solidity: function markNodeUnhealthy(bytes publicKey) returns() -func (_Nodes *NodesTransactor) MarkNodeUnhealthy(opts *bind.TransactOpts, publicKey []byte) (*types.Transaction, error) { - return _Nodes.contract.Transact(opts, "markNodeUnhealthy", publicKey) +// Solidity: function approve(address to, uint256 tokenId) returns() +func (_Nodes *NodesTransactor) Approve(opts *bind.TransactOpts, to common.Address, tokenId *big.Int) (*types.Transaction, error) { + return _Nodes.contract.Transact(opts, "approve", to, tokenId) } -// MarkNodeUnhealthy is a paid mutator transaction binding the contract method 0xf0da65bc. +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. // -// Solidity: function markNodeUnhealthy(bytes publicKey) returns() -func (_Nodes *NodesSession) MarkNodeUnhealthy(publicKey []byte) (*types.Transaction, error) { - return _Nodes.Contract.MarkNodeUnhealthy(&_Nodes.TransactOpts, publicKey) +// Solidity: function approve(address to, uint256 tokenId) returns() +func (_Nodes *NodesSession) Approve(to common.Address, tokenId *big.Int) (*types.Transaction, error) { + return _Nodes.Contract.Approve(&_Nodes.TransactOpts, to, tokenId) } -// MarkNodeUnhealthy is a paid mutator transaction binding the contract method 0xf0da65bc. +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. // -// Solidity: function markNodeUnhealthy(bytes publicKey) returns() -func (_Nodes *NodesTransactorSession) MarkNodeUnhealthy(publicKey []byte) (*types.Transaction, error) { - return _Nodes.Contract.MarkNodeUnhealthy(&_Nodes.TransactOpts, publicKey) +// Solidity: function approve(address to, uint256 tokenId) returns() +func (_Nodes *NodesTransactorSession) Approve(to common.Address, tokenId *big.Int) (*types.Transaction, error) { + return _Nodes.Contract.Approve(&_Nodes.TransactOpts, to, tokenId) } // RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. @@ -345,6 +628,90 @@ func (_Nodes *NodesTransactorSession) RenounceOwnership() (*types.Transaction, e return _Nodes.Contract.RenounceOwnership(&_Nodes.TransactOpts) } +// SafeTransferFrom is a paid mutator transaction binding the contract method 0x42842e0e. +// +// Solidity: function safeTransferFrom(address from, address to, uint256 tokenId) returns() +func (_Nodes *NodesTransactor) SafeTransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, tokenId *big.Int) (*types.Transaction, error) { + return _Nodes.contract.Transact(opts, "safeTransferFrom", from, to, tokenId) +} + +// SafeTransferFrom is a paid mutator transaction binding the contract method 0x42842e0e. +// +// Solidity: function safeTransferFrom(address from, address to, uint256 tokenId) returns() +func (_Nodes *NodesSession) SafeTransferFrom(from common.Address, to common.Address, tokenId *big.Int) (*types.Transaction, error) { + return _Nodes.Contract.SafeTransferFrom(&_Nodes.TransactOpts, from, to, tokenId) +} + +// SafeTransferFrom is a paid mutator transaction binding the contract method 0x42842e0e. +// +// Solidity: function safeTransferFrom(address from, address to, uint256 tokenId) returns() +func (_Nodes *NodesTransactorSession) SafeTransferFrom(from common.Address, to common.Address, tokenId *big.Int) (*types.Transaction, error) { + return _Nodes.Contract.SafeTransferFrom(&_Nodes.TransactOpts, from, to, tokenId) +} + +// SafeTransferFrom0 is a paid mutator transaction binding the contract method 0xb88d4fde. +// +// Solidity: function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) returns() +func (_Nodes *NodesTransactor) SafeTransferFrom0(opts *bind.TransactOpts, from common.Address, to common.Address, tokenId *big.Int, data []byte) (*types.Transaction, error) { + return _Nodes.contract.Transact(opts, "safeTransferFrom0", from, to, tokenId, data) +} + +// SafeTransferFrom0 is a paid mutator transaction binding the contract method 0xb88d4fde. +// +// Solidity: function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) returns() +func (_Nodes *NodesSession) SafeTransferFrom0(from common.Address, to common.Address, tokenId *big.Int, data []byte) (*types.Transaction, error) { + return _Nodes.Contract.SafeTransferFrom0(&_Nodes.TransactOpts, from, to, tokenId, data) +} + +// SafeTransferFrom0 is a paid mutator transaction binding the contract method 0xb88d4fde. +// +// Solidity: function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) returns() +func (_Nodes *NodesTransactorSession) SafeTransferFrom0(from common.Address, to common.Address, tokenId *big.Int, data []byte) (*types.Transaction, error) { + return _Nodes.Contract.SafeTransferFrom0(&_Nodes.TransactOpts, from, to, tokenId, data) +} + +// SetApprovalForAll is a paid mutator transaction binding the contract method 0xa22cb465. +// +// Solidity: function setApprovalForAll(address operator, bool approved) returns() +func (_Nodes *NodesTransactor) SetApprovalForAll(opts *bind.TransactOpts, operator common.Address, approved bool) (*types.Transaction, error) { + return _Nodes.contract.Transact(opts, "setApprovalForAll", operator, approved) +} + +// SetApprovalForAll is a paid mutator transaction binding the contract method 0xa22cb465. +// +// Solidity: function setApprovalForAll(address operator, bool approved) returns() +func (_Nodes *NodesSession) SetApprovalForAll(operator common.Address, approved bool) (*types.Transaction, error) { + return _Nodes.Contract.SetApprovalForAll(&_Nodes.TransactOpts, operator, approved) +} + +// SetApprovalForAll is a paid mutator transaction binding the contract method 0xa22cb465. +// +// Solidity: function setApprovalForAll(address operator, bool approved) returns() +func (_Nodes *NodesTransactorSession) SetApprovalForAll(operator common.Address, approved bool) (*types.Transaction, error) { + return _Nodes.Contract.SetApprovalForAll(&_Nodes.TransactOpts, operator, approved) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 tokenId) returns() +func (_Nodes *NodesTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, tokenId *big.Int) (*types.Transaction, error) { + return _Nodes.contract.Transact(opts, "transferFrom", from, to, tokenId) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 tokenId) returns() +func (_Nodes *NodesSession) TransferFrom(from common.Address, to common.Address, tokenId *big.Int) (*types.Transaction, error) { + return _Nodes.Contract.TransferFrom(&_Nodes.TransactOpts, from, to, tokenId) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 tokenId) returns() +func (_Nodes *NodesTransactorSession) TransferFrom(from common.Address, to common.Address, tokenId *big.Int) (*types.Transaction, error) { + return _Nodes.Contract.TransferFrom(&_Nodes.TransactOpts, from, to, tokenId) +} + // TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // // Solidity: function transferOwnership(address newOwner) returns() @@ -366,9 +733,51 @@ func (_Nodes *NodesTransactorSession) TransferOwnership(newOwner common.Address) return _Nodes.Contract.TransferOwnership(&_Nodes.TransactOpts, newOwner) } -// NodesNodeUpdateIterator is returned from FilterNodeUpdate and is used to iterate over the raw logs and unpacked data for NodeUpdate events raised by the Nodes contract. -type NodesNodeUpdateIterator struct { - Event *NodesNodeUpdate // Event containing the contract specifics and raw log +// UpdateHealth is a paid mutator transaction binding the contract method 0x8354196f. +// +// Solidity: function updateHealth(uint256 tokenId, bool isHealthy) returns() +func (_Nodes *NodesTransactor) UpdateHealth(opts *bind.TransactOpts, tokenId *big.Int, isHealthy bool) (*types.Transaction, error) { + return _Nodes.contract.Transact(opts, "updateHealth", tokenId, isHealthy) +} + +// UpdateHealth is a paid mutator transaction binding the contract method 0x8354196f. +// +// Solidity: function updateHealth(uint256 tokenId, bool isHealthy) returns() +func (_Nodes *NodesSession) UpdateHealth(tokenId *big.Int, isHealthy bool) (*types.Transaction, error) { + return _Nodes.Contract.UpdateHealth(&_Nodes.TransactOpts, tokenId, isHealthy) +} + +// UpdateHealth is a paid mutator transaction binding the contract method 0x8354196f. +// +// Solidity: function updateHealth(uint256 tokenId, bool isHealthy) returns() +func (_Nodes *NodesTransactorSession) UpdateHealth(tokenId *big.Int, isHealthy bool) (*types.Transaction, error) { + return _Nodes.Contract.UpdateHealth(&_Nodes.TransactOpts, tokenId, isHealthy) +} + +// UpdateHttpAddress is a paid mutator transaction binding the contract method 0x50d80993. +// +// Solidity: function updateHttpAddress(uint256 tokenId, string httpAddress) returns() +func (_Nodes *NodesTransactor) UpdateHttpAddress(opts *bind.TransactOpts, tokenId *big.Int, httpAddress string) (*types.Transaction, error) { + return _Nodes.contract.Transact(opts, "updateHttpAddress", tokenId, httpAddress) +} + +// UpdateHttpAddress is a paid mutator transaction binding the contract method 0x50d80993. +// +// Solidity: function updateHttpAddress(uint256 tokenId, string httpAddress) returns() +func (_Nodes *NodesSession) UpdateHttpAddress(tokenId *big.Int, httpAddress string) (*types.Transaction, error) { + return _Nodes.Contract.UpdateHttpAddress(&_Nodes.TransactOpts, tokenId, httpAddress) +} + +// UpdateHttpAddress is a paid mutator transaction binding the contract method 0x50d80993. +// +// Solidity: function updateHttpAddress(uint256 tokenId, string httpAddress) returns() +func (_Nodes *NodesTransactorSession) UpdateHttpAddress(tokenId *big.Int, httpAddress string) (*types.Transaction, error) { + return _Nodes.Contract.UpdateHttpAddress(&_Nodes.TransactOpts, tokenId, httpAddress) +} + +// NodesApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the Nodes contract. +type NodesApprovalIterator struct { + Event *NodesApproval // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -382,7 +791,7 @@ type NodesNodeUpdateIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *NodesNodeUpdateIterator) Next() bool { +func (it *NodesApprovalIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -391,7 +800,7 @@ func (it *NodesNodeUpdateIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(NodesNodeUpdate) + it.Event = new(NodesApproval) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -406,7 +815,7 @@ func (it *NodesNodeUpdateIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(NodesNodeUpdate) + it.Event = new(NodesApproval) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -422,44 +831,69 @@ func (it *NodesNodeUpdateIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *NodesNodeUpdateIterator) Error() error { +func (it *NodesApprovalIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *NodesNodeUpdateIterator) Close() error { +func (it *NodesApprovalIterator) Close() error { it.sub.Unsubscribe() return nil } -// NodesNodeUpdate represents a NodeUpdate event raised by the Nodes contract. -type NodesNodeUpdate struct { - PublicKey []byte - HttpAddress string - OriginatorId *big.Int - IsHealthy bool - Raw types.Log // Blockchain specific contextual infos +// NodesApproval represents a Approval event raised by the Nodes contract. +type NodesApproval struct { + Owner common.Address + Approved common.Address + TokenId *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterNodeUpdate is a free log retrieval operation binding the contract event 0x94b61d0a2ca1645b5632d2a8d7037021433f9d678f3d9bfc4b69089acb64eead. +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. // -// Solidity: event NodeUpdate(bytes publicKey, string httpAddress, uint256 originatorId, bool isHealthy) -func (_Nodes *NodesFilterer) FilterNodeUpdate(opts *bind.FilterOpts) (*NodesNodeUpdateIterator, error) { +// Solidity: event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId) +func (_Nodes *NodesFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, approved []common.Address, tokenId []*big.Int) (*NodesApprovalIterator, error) { - logs, sub, err := _Nodes.contract.FilterLogs(opts, "NodeUpdate") + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var approvedRule []interface{} + for _, approvedItem := range approved { + approvedRule = append(approvedRule, approvedItem) + } + var tokenIdRule []interface{} + for _, tokenIdItem := range tokenId { + tokenIdRule = append(tokenIdRule, tokenIdItem) + } + + logs, sub, err := _Nodes.contract.FilterLogs(opts, "Approval", ownerRule, approvedRule, tokenIdRule) if err != nil { return nil, err } - return &NodesNodeUpdateIterator{contract: _Nodes.contract, event: "NodeUpdate", logs: logs, sub: sub}, nil + return &NodesApprovalIterator{contract: _Nodes.contract, event: "Approval", logs: logs, sub: sub}, nil } -// WatchNodeUpdate is a free log subscription operation binding the contract event 0x94b61d0a2ca1645b5632d2a8d7037021433f9d678f3d9bfc4b69089acb64eead. +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. // -// Solidity: event NodeUpdate(bytes publicKey, string httpAddress, uint256 originatorId, bool isHealthy) -func (_Nodes *NodesFilterer) WatchNodeUpdate(opts *bind.WatchOpts, sink chan<- *NodesNodeUpdate) (event.Subscription, error) { +// Solidity: event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId) +func (_Nodes *NodesFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *NodesApproval, owner []common.Address, approved []common.Address, tokenId []*big.Int) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var approvedRule []interface{} + for _, approvedItem := range approved { + approvedRule = append(approvedRule, approvedItem) + } + var tokenIdRule []interface{} + for _, tokenIdItem := range tokenId { + tokenIdRule = append(tokenIdRule, tokenIdItem) + } - logs, sub, err := _Nodes.contract.WatchLogs(opts, "NodeUpdate") + logs, sub, err := _Nodes.contract.WatchLogs(opts, "Approval", ownerRule, approvedRule, tokenIdRule) if err != nil { return nil, err } @@ -469,8 +903,8 @@ func (_Nodes *NodesFilterer) WatchNodeUpdate(opts *bind.WatchOpts, sink chan<- * select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(NodesNodeUpdate) - if err := _Nodes.contract.UnpackLog(event, "NodeUpdate", log); err != nil { + event := new(NodesApproval) + if err := _Nodes.contract.UnpackLog(event, "Approval", log); err != nil { return err } event.Raw = log @@ -491,21 +925,21 @@ func (_Nodes *NodesFilterer) WatchNodeUpdate(opts *bind.WatchOpts, sink chan<- * }), nil } -// ParseNodeUpdate is a log parse operation binding the contract event 0x94b61d0a2ca1645b5632d2a8d7037021433f9d678f3d9bfc4b69089acb64eead. +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. // -// Solidity: event NodeUpdate(bytes publicKey, string httpAddress, uint256 originatorId, bool isHealthy) -func (_Nodes *NodesFilterer) ParseNodeUpdate(log types.Log) (*NodesNodeUpdate, error) { - event := new(NodesNodeUpdate) - if err := _Nodes.contract.UnpackLog(event, "NodeUpdate", log); err != nil { +// Solidity: event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId) +func (_Nodes *NodesFilterer) ParseApproval(log types.Log) (*NodesApproval, error) { + event := new(NodesApproval) + if err := _Nodes.contract.UnpackLog(event, "Approval", log); err != nil { return nil, err } event.Raw = log return event, nil } -// NodesOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Nodes contract. -type NodesOwnershipTransferredIterator struct { - Event *NodesOwnershipTransferred // Event containing the contract specifics and raw log +// NodesApprovalForAllIterator is returned from FilterApprovalForAll and is used to iterate over the raw logs and unpacked data for ApprovalForAll events raised by the Nodes contract. +type NodesApprovalForAllIterator struct { + Event *NodesApprovalForAll // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -519,7 +953,7 @@ type NodesOwnershipTransferredIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *NodesOwnershipTransferredIterator) Next() bool { +func (it *NodesApprovalForAllIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -528,7 +962,7 @@ func (it *NodesOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(NodesOwnershipTransferred) + it.Event = new(NodesApprovalForAll) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -543,7 +977,7 @@ func (it *NodesOwnershipTransferredIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(NodesOwnershipTransferred) + it.Event = new(NodesApprovalForAll) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -559,43 +993,332 @@ func (it *NodesOwnershipTransferredIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *NodesOwnershipTransferredIterator) Error() error { +func (it *NodesApprovalForAllIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *NodesOwnershipTransferredIterator) Close() error { +func (it *NodesApprovalForAllIterator) Close() error { it.sub.Unsubscribe() return nil } -// NodesOwnershipTransferred represents a OwnershipTransferred event raised by the Nodes contract. -type NodesOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// NodesApprovalForAll represents a ApprovalForAll event raised by the Nodes contract. +type NodesApprovalForAll struct { + Owner common.Address + Operator common.Address + Approved bool + Raw types.Log // Blockchain specific contextual infos } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// FilterApprovalForAll is a free log retrieval operation binding the contract event 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Nodes *NodesFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*NodesOwnershipTransferredIterator, error) { +// Solidity: event ApprovalForAll(address indexed owner, address indexed operator, bool approved) +func (_Nodes *NodesFilterer) FilterApprovalForAll(opts *bind.FilterOpts, owner []common.Address, operator []common.Address) (*NodesApprovalForAllIterator, error) { - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) + var operatorRule []interface{} + for _, operatorItem := range operator { + operatorRule = append(operatorRule, operatorItem) } - logs, sub, err := _Nodes.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + logs, sub, err := _Nodes.contract.FilterLogs(opts, "ApprovalForAll", ownerRule, operatorRule) if err != nil { return nil, err } - return &NodesOwnershipTransferredIterator{contract: _Nodes.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &NodesApprovalForAllIterator{contract: _Nodes.contract, event: "ApprovalForAll", logs: logs, sub: sub}, nil +} + +// WatchApprovalForAll is a free log subscription operation binding the contract event 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31. +// +// Solidity: event ApprovalForAll(address indexed owner, address indexed operator, bool approved) +func (_Nodes *NodesFilterer) WatchApprovalForAll(opts *bind.WatchOpts, sink chan<- *NodesApprovalForAll, owner []common.Address, operator []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var operatorRule []interface{} + for _, operatorItem := range operator { + operatorRule = append(operatorRule, operatorItem) + } + + logs, sub, err := _Nodes.contract.WatchLogs(opts, "ApprovalForAll", ownerRule, operatorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NodesApprovalForAll) + if err := _Nodes.contract.UnpackLog(event, "ApprovalForAll", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApprovalForAll is a log parse operation binding the contract event 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31. +// +// Solidity: event ApprovalForAll(address indexed owner, address indexed operator, bool approved) +func (_Nodes *NodesFilterer) ParseApprovalForAll(log types.Log) (*NodesApprovalForAll, error) { + event := new(NodesApprovalForAll) + if err := _Nodes.contract.UnpackLog(event, "ApprovalForAll", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NodesNodeUpdatedIterator is returned from FilterNodeUpdated and is used to iterate over the raw logs and unpacked data for NodeUpdated events raised by the Nodes contract. +type NodesNodeUpdatedIterator struct { + Event *NodesNodeUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NodesNodeUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NodesNodeUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NodesNodeUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NodesNodeUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NodesNodeUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NodesNodeUpdated represents a NodeUpdated event raised by the Nodes contract. +type NodesNodeUpdated struct { + NodeId *big.Int + Node NodesNode + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNodeUpdated is a free log retrieval operation binding the contract event 0x925a803604a97550dcfaba2eb298fb6e6f828340bdf9d467d2a34c50cfbba96a. +// +// Solidity: event NodeUpdated(uint256 nodeId, (bytes,string,bool) node) +func (_Nodes *NodesFilterer) FilterNodeUpdated(opts *bind.FilterOpts) (*NodesNodeUpdatedIterator, error) { + + logs, sub, err := _Nodes.contract.FilterLogs(opts, "NodeUpdated") + if err != nil { + return nil, err + } + return &NodesNodeUpdatedIterator{contract: _Nodes.contract, event: "NodeUpdated", logs: logs, sub: sub}, nil +} + +// WatchNodeUpdated is a free log subscription operation binding the contract event 0x925a803604a97550dcfaba2eb298fb6e6f828340bdf9d467d2a34c50cfbba96a. +// +// Solidity: event NodeUpdated(uint256 nodeId, (bytes,string,bool) node) +func (_Nodes *NodesFilterer) WatchNodeUpdated(opts *bind.WatchOpts, sink chan<- *NodesNodeUpdated) (event.Subscription, error) { + + logs, sub, err := _Nodes.contract.WatchLogs(opts, "NodeUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NodesNodeUpdated) + if err := _Nodes.contract.UnpackLog(event, "NodeUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseNodeUpdated is a log parse operation binding the contract event 0x925a803604a97550dcfaba2eb298fb6e6f828340bdf9d467d2a34c50cfbba96a. +// +// Solidity: event NodeUpdated(uint256 nodeId, (bytes,string,bool) node) +func (_Nodes *NodesFilterer) ParseNodeUpdated(log types.Log) (*NodesNodeUpdated, error) { + event := new(NodesNodeUpdated) + if err := _Nodes.contract.UnpackLog(event, "NodeUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NodesOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Nodes contract. +type NodesOwnershipTransferredIterator struct { + Event *NodesOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NodesOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NodesOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NodesOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NodesOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NodesOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NodesOwnershipTransferred represents a OwnershipTransferred event raised by the Nodes contract. +type NodesOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Nodes *NodesFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*NodesOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _Nodes.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &NodesOwnershipTransferredIterator{contract: _Nodes.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } // WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. @@ -655,3 +1378,165 @@ func (_Nodes *NodesFilterer) ParseOwnershipTransferred(log types.Log) (*NodesOwn event.Raw = log return event, nil } + +// NodesTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the Nodes contract. +type NodesTransferIterator struct { + Event *NodesTransfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NodesTransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NodesTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NodesTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NodesTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NodesTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NodesTransfer represents a Transfer event raised by the Nodes contract. +type NodesTransfer struct { + From common.Address + To common.Address + TokenId *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 indexed tokenId) +func (_Nodes *NodesFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address, tokenId []*big.Int) (*NodesTransferIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + var tokenIdRule []interface{} + for _, tokenIdItem := range tokenId { + tokenIdRule = append(tokenIdRule, tokenIdItem) + } + + logs, sub, err := _Nodes.contract.FilterLogs(opts, "Transfer", fromRule, toRule, tokenIdRule) + if err != nil { + return nil, err + } + return &NodesTransferIterator{contract: _Nodes.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 indexed tokenId) +func (_Nodes *NodesFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *NodesTransfer, from []common.Address, to []common.Address, tokenId []*big.Int) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + var tokenIdRule []interface{} + for _, tokenIdItem := range tokenId { + tokenIdRule = append(tokenIdRule, tokenIdItem) + } + + logs, sub, err := _Nodes.contract.WatchLogs(opts, "Transfer", fromRule, toRule, tokenIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NodesTransfer) + if err := _Nodes.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 indexed tokenId) +func (_Nodes *NodesFilterer) ParseTransfer(log types.Log) (*NodesTransfer, error) { + event := new(NodesTransfer) + if err := _Nodes.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/pkg/registry/registry.go b/pkg/registry/registry.go index 56a33cbc..ddd83221 100644 --- a/pkg/registry/registry.go +++ b/pkg/registry/registry.go @@ -1,11 +1,10 @@ package registry type Node struct { - Index int - PublicKey []byte - GrpcAddress string - DisabledBlock *uint64 - // Maybe add mTLS cert here + NodeId int + SigningKey []byte + HttpAddress string + MtlsCert []byte } type NodeRegistry interface {