mirror of https://github.com/poanetwork/quorum.git
permissions: Code clean up.
This commit is contained in:
parent
94f898787f
commit
6b66f7e27d
|
@ -33,7 +33,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
"github.com/ethereum/go-ethereum/console"
|
"github.com/ethereum/go-ethereum/console"
|
||||||
"github.com/ethereum/go-ethereum/controls/permission"
|
|
||||||
"github.com/ethereum/go-ethereum/core/quorum"
|
"github.com/ethereum/go-ethereum/core/quorum"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
|
@ -41,6 +40,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
"github.com/ethereum/go-ethereum/node"
|
"github.com/ethereum/go-ethereum/node"
|
||||||
|
"github.com/ethereum/go-ethereum/permission"
|
||||||
"gopkg.in/urfave/cli.v1"
|
"gopkg.in/urfave/cli.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,407 +0,0 @@
|
||||||
pragma solidity ^0.5.3;
|
|
||||||
|
|
||||||
contract Clusterkeys {
|
|
||||||
// Struct for managing the org details
|
|
||||||
enum Operation {None, Add, Delete}
|
|
||||||
struct OrgKeyDetails {
|
|
||||||
string tmKey;
|
|
||||||
bool active;
|
|
||||||
}
|
|
||||||
struct OrgDetails {
|
|
||||||
string orgId;
|
|
||||||
string morgId;
|
|
||||||
string pendingKey;
|
|
||||||
Operation pendingOp;
|
|
||||||
uint keyCount;
|
|
||||||
OrgKeyDetails []orgKeys;
|
|
||||||
mapping (bytes32 => uint) orgKeyIndex;
|
|
||||||
}
|
|
||||||
OrgDetails [] private orgList;
|
|
||||||
mapping(bytes32 => uint) private OrgIndex;
|
|
||||||
|
|
||||||
// Struct for managing the voter accounst for the org
|
|
||||||
// voter struct which will be part of Master org
|
|
||||||
struct VoterDetails {
|
|
||||||
address vAccount;
|
|
||||||
bool active;
|
|
||||||
}
|
|
||||||
struct MasterOrgDetails {
|
|
||||||
string orgId;
|
|
||||||
uint voterCount;
|
|
||||||
uint validVoterCount;
|
|
||||||
VoterDetails []voterList;
|
|
||||||
mapping (address => uint) voterIndex;
|
|
||||||
}
|
|
||||||
MasterOrgDetails [] private masterOrgList;
|
|
||||||
mapping(bytes32 => uint) private MasterOrgIndex;
|
|
||||||
|
|
||||||
// Struct to monitor the key usage
|
|
||||||
struct KeyUsageDetails {
|
|
||||||
string tmKey;
|
|
||||||
string morgId;
|
|
||||||
uint count;
|
|
||||||
bool pending;
|
|
||||||
}
|
|
||||||
KeyUsageDetails [] private keyUsage;
|
|
||||||
mapping (bytes32 => uint) KeyIndex;
|
|
||||||
|
|
||||||
// mapping to monitor the voting status for each acount and
|
|
||||||
// overall voting count
|
|
||||||
mapping (uint => mapping (address => bool)) private voteStatus;
|
|
||||||
mapping (uint => uint) private voteCount;
|
|
||||||
|
|
||||||
uint private orgNum = 0;
|
|
||||||
uint private morgNum = 0;
|
|
||||||
uint private keyNum = 0;
|
|
||||||
|
|
||||||
// events related to Master Org add
|
|
||||||
event MasterOrgAdded(string _orgId);
|
|
||||||
event SubOrgAdded(string _orgId);
|
|
||||||
|
|
||||||
// events related to Org level key management
|
|
||||||
event OrgKeyAdded(string _orgId, string _tmKey);
|
|
||||||
event OrgKeyDeleted(string _orgId, string _tmKey);
|
|
||||||
|
|
||||||
// events related to org level approval process
|
|
||||||
event ItemForApproval(string _orgId, Operation _pendingOp, string _tmKey);
|
|
||||||
|
|
||||||
// events related to managing voting accounts for the org
|
|
||||||
event VoterAdded(string _orgId, address _address);
|
|
||||||
event VoterDeleted(string _orgId, address _address);
|
|
||||||
|
|
||||||
|
|
||||||
/* public and external functions */
|
|
||||||
// view functions
|
|
||||||
|
|
||||||
// dummy function called from geth interface to check of the contract is deployed
|
|
||||||
function checkOrgContractExists() external pure returns (bool){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns voter count for a given org
|
|
||||||
function getOrgVoteCount(string calldata _orgId) external view returns (uint) {
|
|
||||||
return voteCount[getOrgIndex(_orgId)];
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns pending operation details
|
|
||||||
function getPendingOp(string calldata _orgId) external view returns (string memory, Operation) {
|
|
||||||
uint i = getOrgIndex(_orgId);
|
|
||||||
return (orgList[i].pendingKey, orgList[i].pendingOp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// All internal functions
|
|
||||||
|
|
||||||
// returns the voter index
|
|
||||||
function getVoterIndex(string memory _morgId, address _vAccount) internal view returns (uint)
|
|
||||||
{
|
|
||||||
uint morgIndex = getMasterOrgIndex(_morgId);
|
|
||||||
return masterOrgList[morgIndex].voterIndex[_vAccount] - 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the org index for the org list
|
|
||||||
function getOrgIndex(string memory _orgId) internal view returns (uint)
|
|
||||||
{
|
|
||||||
return OrgIndex[keccak256(abi.encodePacked(_orgId))] - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the master org index for the org from voter list
|
|
||||||
function getMasterOrgIndex(string memory _orgId) internal view returns (uint)
|
|
||||||
{
|
|
||||||
return MasterOrgIndex[keccak256(abi.encodePacked(_orgId))] - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the key index from org key list
|
|
||||||
function getOrgKeyIndex(uint _orgIndex, string memory _tmKey) internal view returns (uint)
|
|
||||||
{
|
|
||||||
return orgList[_orgIndex].orgKeyIndex[keccak256(abi.encodePacked(_tmKey))] - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the key index for the key usage list
|
|
||||||
function getKeyIndex(string memory _tmKey) internal view returns (uint)
|
|
||||||
{
|
|
||||||
return KeyIndex[keccak256(abi.encodePacked(_tmKey))] - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize the voter account votes to false. This will be called
|
|
||||||
// when a new item is initiated for approval
|
|
||||||
function voterInit(string memory _orgId) internal {
|
|
||||||
uint orgIndex = getOrgIndex(_orgId);
|
|
||||||
uint morgIndex = getMasterOrgIndex(orgList[orgIndex].morgId);
|
|
||||||
for (uint i = 0; i < masterOrgList[morgIndex].voterList.length; i++){
|
|
||||||
if (masterOrgList[morgIndex].voterList[i].active){
|
|
||||||
voteStatus[orgIndex][masterOrgList[morgIndex].voterList[i].vAccount] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
voteCount[orgIndex] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// processes the vote from the voter account.
|
|
||||||
function processVote (string memory _orgId) internal {
|
|
||||||
uint orgIndex = getOrgIndex(_orgId);
|
|
||||||
if (voteStatus[orgIndex][msg.sender] == false ){
|
|
||||||
voteStatus[orgIndex][msg.sender] = true;
|
|
||||||
voteCount[orgIndex]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// checks if enough votes have been cast for the pending operation.
|
|
||||||
// If yes returns true
|
|
||||||
function checkEnoughVotes (string memory _orgId, string memory _morgId) internal view returns (bool) {
|
|
||||||
uint orgIndex = getOrgIndex(_orgId);
|
|
||||||
uint morgIndex = getMasterOrgIndex(_morgId);
|
|
||||||
|
|
||||||
return (voteCount[orgIndex] > masterOrgList[morgIndex].validVoterCount / 2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// function to update key usage details at master org level for a key
|
|
||||||
function updateKeyUsage(string memory _tmKey, string memory _morgId, Operation op) internal {
|
|
||||||
uint keyIndex = getKeyIndex(_tmKey);
|
|
||||||
keyUsage[keyIndex].pending = false;
|
|
||||||
if (op == Operation.Add){
|
|
||||||
keyUsage[keyIndex].count++;
|
|
||||||
keyUsage[keyIndex].morgId = _morgId;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
keyUsage[keyIndex].count--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// function to process the approavl for add or delete
|
|
||||||
function processApproval(uint _orgIndex) internal {
|
|
||||||
if(checkEnoughVotes(orgList[_orgIndex].orgId, orgList[_orgIndex].morgId)){
|
|
||||||
string storage locKey = orgList[_orgIndex].pendingKey;
|
|
||||||
if (orgList[_orgIndex].pendingOp == Operation.Add){
|
|
||||||
if (checkIfKeyExists(orgList[_orgIndex].orgId, locKey)){
|
|
||||||
uint keyIndex = getOrgKeyIndex(_orgIndex, locKey);
|
|
||||||
orgList[_orgIndex].orgKeys[keyIndex].active = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
orgList[_orgIndex].keyCount++;
|
|
||||||
orgList[_orgIndex].orgKeyIndex[keccak256(abi.encodePacked(locKey))] = orgList[_orgIndex].keyCount;
|
|
||||||
orgList[_orgIndex].orgKeys.push(OrgKeyDetails(locKey, true));
|
|
||||||
updateKeyUsage(orgList[_orgIndex].pendingKey, orgList[_orgIndex].morgId, orgList[_orgIndex].pendingOp);
|
|
||||||
}
|
|
||||||
emit OrgKeyAdded(orgList[_orgIndex].orgId, locKey);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (checkIfKeyExists (orgList[_orgIndex].orgId, locKey)){
|
|
||||||
uint keyIndex = getOrgKeyIndex(_orgIndex, locKey);
|
|
||||||
orgList[_orgIndex].orgKeys[keyIndex].active = false;
|
|
||||||
emit OrgKeyDeleted(orgList[_orgIndex].orgId, locKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
orgList[_orgIndex].pendingOp = Operation.None;
|
|
||||||
orgList[_orgIndex].pendingKey = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// All public functions
|
|
||||||
|
|
||||||
// checks if the org has any voter accounts set up or not
|
|
||||||
function checkIfVoterExists(string memory _morgId, address _address) public view returns (bool){
|
|
||||||
uint morgIndex = getMasterOrgIndex(_morgId);
|
|
||||||
if (masterOrgList[morgIndex].voterIndex[_address] == 0){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
uint voterIndex = getVoterIndex(_morgId, _address);
|
|
||||||
return masterOrgList[morgIndex].voterList[voterIndex].active;
|
|
||||||
}
|
|
||||||
|
|
||||||
// checks if there the key is already in the list of private keys for the org
|
|
||||||
function checkIfKeyExists(string memory _orgId, string memory _tmKey) public view returns (bool){
|
|
||||||
uint orgIndex = getOrgIndex(_orgId);
|
|
||||||
if (orgList[orgIndex].orgKeyIndex[keccak256(abi.encodePacked(_tmKey))] == 0){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
uint keyIndex = getOrgKeyIndex(orgIndex, _tmKey);
|
|
||||||
return orgList[orgIndex].orgKeys[keyIndex].active;
|
|
||||||
}
|
|
||||||
// All extenal view functions
|
|
||||||
|
|
||||||
// Get number of voters
|
|
||||||
function getNumberOfVoters(string calldata _morgId) external view returns (uint)
|
|
||||||
{
|
|
||||||
return masterOrgList[getMasterOrgIndex(_morgId)].voterCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get voter details
|
|
||||||
function getVoter(string calldata _morgId, uint i) external view returns (address _addr, bool _active)
|
|
||||||
{
|
|
||||||
uint morgIndex = getMasterOrgIndex(_morgId);
|
|
||||||
return (masterOrgList[morgIndex].voterList[i].vAccount, masterOrgList[morgIndex].voterList[i].active);
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the number of orgs
|
|
||||||
function getNumberOfOrgs() external view returns (uint){
|
|
||||||
return orgNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the total number of keys for a given org
|
|
||||||
function getOrgKeyCount(string calldata _orgId) external view returns (uint){
|
|
||||||
return orgList[getOrgIndex(_orgId)].orgKeys.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns org key details based on org id and key index
|
|
||||||
function getOrgKey(string calldata _orgId, uint _keyIndex) external view returns (string memory, bool){
|
|
||||||
uint orgIndex = getOrgIndex(_orgId);
|
|
||||||
return (orgList[orgIndex].orgKeys[_keyIndex].tmKey,orgList[orgIndex].orgKeys[_keyIndex].active);
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns org and master org details based on org index
|
|
||||||
function getOrgInfo(uint _orgIndex) external view returns (string memory, string memory){
|
|
||||||
return (orgList[_orgIndex].orgId, orgList[_orgIndex].morgId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// checks if the sender is one of the registered voter account for the org
|
|
||||||
function isVoter (string calldata _orgId, address account) external view returns (bool){
|
|
||||||
uint orgIndex = getOrgIndex(_orgId);
|
|
||||||
uint morgIndex = getMasterOrgIndex(orgList[orgIndex].morgId);
|
|
||||||
return (!(masterOrgList[morgIndex].voterIndex[account] == 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// checks if the voting accounts exists for the org
|
|
||||||
function checkVotingAccountExists(string calldata _orgId) external view returns (bool)
|
|
||||||
{
|
|
||||||
uint orgIndex = getOrgIndex(_orgId);
|
|
||||||
uint morgIndex = getMasterOrgIndex(orgList[orgIndex].morgId);
|
|
||||||
return (masterOrgList[morgIndex].validVoterCount > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// function to check if morg exists
|
|
||||||
function checkMasterOrgExists (string calldata _morgId) external view returns (bool) {
|
|
||||||
return (!(MasterOrgIndex[keccak256(abi.encodePacked(_morgId))] == 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// function to check if morg exists
|
|
||||||
function checkOrgExists (string calldata _orgId) external view returns (bool) {
|
|
||||||
return(!(OrgIndex[keccak256(abi.encodePacked(_orgId))] == 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// function for checking if org exists and if there are any pending ops
|
|
||||||
function checkOrgPendingOp (string calldata _orgId) external view returns (bool) {
|
|
||||||
uint orgIndex = getOrgIndex(_orgId);
|
|
||||||
return (orgList[orgIndex].pendingOp != Operation.None);
|
|
||||||
}
|
|
||||||
|
|
||||||
// function for checking if org exists and if there are any pending ops
|
|
||||||
function getOrgPendingOp (string calldata _orgId) external view returns (string memory, Operation) {
|
|
||||||
uint orgIndex = getOrgIndex(_orgId);
|
|
||||||
return (orgList[orgIndex].pendingKey, orgList[orgIndex].pendingOp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this function checks of the key proposed is in use in another master org
|
|
||||||
function checkKeyClash (string calldata _orgId, string calldata _key) external view returns (bool) {
|
|
||||||
uint orgIndex = getOrgIndex(_orgId);
|
|
||||||
|
|
||||||
uint keyIndex = getKeyIndex(_key);
|
|
||||||
if ((KeyIndex[keccak256(abi.encodePacked(_key))] != 0) &&
|
|
||||||
(keccak256(abi.encodePacked (keyUsage[keyIndex].morgId)) != keccak256(abi.encodePacked(orgList[orgIndex].morgId)))){
|
|
||||||
// check the count if count is greather than zero, key already in use
|
|
||||||
if ((keyUsage[keyIndex].count > 0) || (keyUsage[keyIndex].pending)){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// All extenal update functions
|
|
||||||
|
|
||||||
// function for adding a new master org
|
|
||||||
function addMasterOrg(string calldata _morgId) external
|
|
||||||
{
|
|
||||||
morgNum++;
|
|
||||||
MasterOrgIndex[keccak256(abi.encodePacked(_morgId))] = morgNum;
|
|
||||||
|
|
||||||
uint id = masterOrgList.length++;
|
|
||||||
masterOrgList[id].orgId = _morgId;
|
|
||||||
masterOrgList[id].voterCount = 0;
|
|
||||||
masterOrgList[id].validVoterCount = 0;
|
|
||||||
emit MasterOrgAdded(_morgId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// function for adding a new master org
|
|
||||||
function addSubOrg(string calldata _orgId, string calldata _morgId) external
|
|
||||||
{
|
|
||||||
orgNum++;
|
|
||||||
OrgIndex[keccak256(abi.encodePacked(_orgId))] = orgNum;
|
|
||||||
uint id = orgList.length++;
|
|
||||||
orgList[id].orgId = _orgId;
|
|
||||||
orgList[id].morgId = _morgId;
|
|
||||||
orgList[id].keyCount = 0;
|
|
||||||
orgList[id].pendingKey = "";
|
|
||||||
orgList[id].pendingOp = Operation.None;
|
|
||||||
emit SubOrgAdded(_morgId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// function for adding a voter account to a master org
|
|
||||||
function addVoter(string calldata _morgId, address _address) external
|
|
||||||
{
|
|
||||||
uint morgIndex = getMasterOrgIndex(_morgId);
|
|
||||||
masterOrgList[morgIndex].voterCount++;
|
|
||||||
masterOrgList[morgIndex].validVoterCount++;
|
|
||||||
masterOrgList[morgIndex].voterIndex[_address] = masterOrgList[morgIndex].voterCount;
|
|
||||||
masterOrgList[morgIndex].voterList.push(VoterDetails(_address, true));
|
|
||||||
emit VoterAdded(_morgId, _address);
|
|
||||||
}
|
|
||||||
|
|
||||||
// function for deleting a voter account to a master org
|
|
||||||
function deleteVoter(string calldata _morgId, address _address) external
|
|
||||||
{
|
|
||||||
uint morgIndex = getMasterOrgIndex(_morgId);
|
|
||||||
if(checkIfVoterExists(_morgId, _address)){
|
|
||||||
uint vIndex = getVoterIndex(_morgId, _address);
|
|
||||||
masterOrgList[morgIndex].validVoterCount --;
|
|
||||||
masterOrgList[morgIndex].voterList[vIndex].active = false;
|
|
||||||
emit VoterDeleted(_morgId, _address);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// function for adding a private key for the org. Thsi will be added once
|
|
||||||
// approval process is complete
|
|
||||||
function addOrgKey(string calldata _orgId, string calldata _tmKey) external
|
|
||||||
{
|
|
||||||
uint orgIndex = getOrgIndex(_orgId);
|
|
||||||
if (!checkIfKeyExists (_orgId, _tmKey)){
|
|
||||||
orgList[orgIndex].pendingKey = _tmKey;
|
|
||||||
orgList[orgIndex].pendingOp = Operation.Add;
|
|
||||||
voterInit(_orgId);
|
|
||||||
// add key to key usage list for tracking
|
|
||||||
uint keyIndex = getKeyIndex(_tmKey);
|
|
||||||
if (KeyIndex[keccak256(abi.encodePacked(_tmKey))] == 0){
|
|
||||||
keyNum ++;
|
|
||||||
KeyIndex[keccak256(abi.encodePacked(_tmKey))] = keyNum;
|
|
||||||
keyUsage.push(KeyUsageDetails(_tmKey, orgList[orgIndex].morgId, 0, true));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
keyUsage[keyIndex].pending = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit ItemForApproval(_orgId,Operation.Add, _tmKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// function for deleting a private key for the org. Thsi will be deleted once
|
|
||||||
// approval process is complete
|
|
||||||
function deleteOrgKey(string calldata _orgId, string calldata _tmKey) external
|
|
||||||
{
|
|
||||||
uint orgIndex = getOrgIndex(_orgId);
|
|
||||||
if (checkIfKeyExists(_orgId, _tmKey)) {
|
|
||||||
orgList[orgIndex].pendingKey = _tmKey;
|
|
||||||
orgList[orgIndex].pendingOp = Operation.Delete;
|
|
||||||
voterInit(_orgId);
|
|
||||||
uint keyIndex = getKeyIndex(_tmKey);
|
|
||||||
keyUsage[keyIndex].pending = true;
|
|
||||||
emit ItemForApproval(_orgId, Operation.Delete, _tmKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// function for approving key add or delete operations
|
|
||||||
function approvePendingOp(string calldata _orgId) external
|
|
||||||
{
|
|
||||||
uint orgIndex = getOrgIndex(_orgId);
|
|
||||||
processVote(_orgId);
|
|
||||||
processApproval(orgIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,188 +0,0 @@
|
||||||
package cluster
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
|
||||||
"github.com/ethereum/go-ethereum/controls"
|
|
||||||
pbind "github.com/ethereum/go-ethereum/controls/bind/cluster"
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
|
||||||
"github.com/ethereum/go-ethereum/node"
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
|
||||||
)
|
|
||||||
|
|
||||||
type OrgKeyCtrl struct {
|
|
||||||
ethClient *ethclient.Client
|
|
||||||
key *ecdsa.PrivateKey
|
|
||||||
km *pbind.Cluster
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates the controls structure for org key management
|
|
||||||
func NewOrgKeyCtrl(node *node.Node) (*OrgKeyCtrl, error) {
|
|
||||||
stateReader, _, err := controls.CreateEthClient(node)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Unable to create ethereum client for cluster check", "err", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// check if permissioning contract is there at address. If not return from here
|
|
||||||
km, err := pbind.NewCluster(params.QuorumPrivateKeyManagementContract, stateReader)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Permissions not enabled for the network", "err", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &OrgKeyCtrl{stateReader, node.GetNodeKey(), km}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// starts the org key management services
|
|
||||||
func (k *OrgKeyCtrl) Start() error {
|
|
||||||
|
|
||||||
_, err := pbind.NewClusterFilterer(params.QuorumPrivateKeyManagementContract, k.ethClient)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Cluster not enabled for the network", "err", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if permissioning contract is there at address. If not return from here
|
|
||||||
err = k.checkIfContractExists()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// start the service
|
|
||||||
k.manageClusterKeys()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// checks if the contract is deployed for org key management
|
|
||||||
func (k *OrgKeyCtrl) checkIfContractExists() error {
|
|
||||||
auth := bind.NewKeyedTransactor(k.key)
|
|
||||||
clusterSession := &pbind.ClusterSession{
|
|
||||||
Contract: k.km,
|
|
||||||
CallOpts: bind.CallOpts{
|
|
||||||
Pending: true,
|
|
||||||
},
|
|
||||||
TransactOpts: bind.TransactOpts{
|
|
||||||
From: auth.From,
|
|
||||||
Signer: auth.Signer,
|
|
||||||
GasLimit: 4700000,
|
|
||||||
GasPrice: big.NewInt(0),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// dummy call to contrat to check if the contract is deployed
|
|
||||||
_, err := clusterSession.CheckOrgContractExists()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// in case of geth restart firts checks for historical key update events and
|
|
||||||
// populates the cache, then starts the key change monitoring service
|
|
||||||
func (k *OrgKeyCtrl) manageClusterKeys() {
|
|
||||||
//call populate nodes to populate the nodes into contract
|
|
||||||
if err := k.populatePrivateKeys(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//monitor for nodes deletiin via smart contract
|
|
||||||
k.monitorKeyChanges()
|
|
||||||
}
|
|
||||||
|
|
||||||
// populates cache based on the historical key change events.
|
|
||||||
func (k *OrgKeyCtrl) populatePrivateKeys() error {
|
|
||||||
cluster, err := pbind.NewClusterFilterer(params.QuorumPrivateKeyManagementContract, k.ethClient)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Failed to monitor node delete", "err", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := &bind.FilterOpts{}
|
|
||||||
pastAddEvents, err := cluster.FilterOrgKeyAdded(opts)
|
|
||||||
|
|
||||||
if err != nil && err.Error() == "no contract code at given address" {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
recExists := true
|
|
||||||
for recExists {
|
|
||||||
recExists = pastAddEvents.Next()
|
|
||||||
if recExists {
|
|
||||||
types.AddOrgKey(pastAddEvents.Event.OrgId, pastAddEvents.Event.TmKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
opts = &bind.FilterOpts{}
|
|
||||||
pastDeleteEvents, _ := cluster.FilterOrgKeyDeleted(opts)
|
|
||||||
|
|
||||||
recExists = true
|
|
||||||
for recExists {
|
|
||||||
recExists = pastDeleteEvents.Next()
|
|
||||||
if recExists {
|
|
||||||
types.DeleteOrgKey(pastDeleteEvents.Event.OrgId, pastDeleteEvents.Event.TmKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// service to monitor key change events
|
|
||||||
func (k *OrgKeyCtrl) monitorKeyChanges() {
|
|
||||||
go k.monitorKeyAdd()
|
|
||||||
|
|
||||||
go k.monitorKeyDelete()
|
|
||||||
}
|
|
||||||
|
|
||||||
// monitors for new key added event and updates caches based on the same
|
|
||||||
func (k *OrgKeyCtrl) monitorKeyAdd() {
|
|
||||||
cluster, err := pbind.NewClusterFilterer(params.QuorumPrivateKeyManagementContract, k.ethClient)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Failed to monitor key action", "err", err)
|
|
||||||
}
|
|
||||||
ch := make(chan *pbind.ClusterOrgKeyAdded)
|
|
||||||
|
|
||||||
opts := &bind.WatchOpts{}
|
|
||||||
var blockNumber uint64 = 1
|
|
||||||
opts.Start = &blockNumber
|
|
||||||
var newEvent *pbind.ClusterOrgKeyAdded
|
|
||||||
|
|
||||||
_, err = cluster.WatchOrgKeyAdded(opts, ch)
|
|
||||||
if err != nil {
|
|
||||||
log.Info("Failed WatchOrgKeyDeleted: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case newEvent = <-ch:
|
|
||||||
types.AddOrgKey(newEvent.OrgId, newEvent.TmKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// monitors for new key delete event and updates caches based on the same
|
|
||||||
func (k *OrgKeyCtrl) monitorKeyDelete() {
|
|
||||||
cluster, err := pbind.NewClusterFilterer(params.QuorumPrivateKeyManagementContract, k.ethClient)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Failed to monitor key action", "err", err)
|
|
||||||
}
|
|
||||||
ch := make(chan *pbind.ClusterOrgKeyDeleted)
|
|
||||||
|
|
||||||
opts := &bind.WatchOpts{}
|
|
||||||
var blockNumber uint64 = 1
|
|
||||||
opts.Start = &blockNumber
|
|
||||||
var newEvent *pbind.ClusterOrgKeyDeleted
|
|
||||||
|
|
||||||
_, err = cluster.WatchOrgKeyDeleted(opts, ch)
|
|
||||||
if err != nil {
|
|
||||||
log.Info("Failed WatchOrgKeyDeleted: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case newEvent = <-ch:
|
|
||||||
types.DeleteOrgKey(newEvent.OrgId, newEvent.TmKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,14 +7,13 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
obind "github.com/ethereum/go-ethereum/controls/bind/cluster"
|
|
||||||
pbind "github.com/ethereum/go-ethereum/controls/bind/permission"
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
|
pbind "github.com/ethereum/go-ethereum/permission/bind/permission"
|
||||||
"math/big"
|
"math/big"
|
||||||
"regexp"
|
"regexp"
|
||||||
)
|
)
|
||||||
|
@ -74,10 +73,8 @@ type QuorumControlsAPI struct {
|
||||||
ethClnt *ethclient.Client
|
ethClnt *ethclient.Client
|
||||||
acntMgr *accounts.Manager
|
acntMgr *accounts.Manager
|
||||||
txOpt *bind.TransactOpts
|
txOpt *bind.TransactOpts
|
||||||
clustContr *obind.Cluster
|
|
||||||
key *ecdsa.PrivateKey
|
key *ecdsa.PrivateKey
|
||||||
permEnabled bool
|
permEnabled bool
|
||||||
orgEnabled bool
|
|
||||||
permConfig *types.PermissionConfig
|
permConfig *types.PermissionConfig
|
||||||
permInterf *pbind.PermInterface
|
permInterf *pbind.PermInterface
|
||||||
}
|
}
|
||||||
|
@ -148,7 +145,7 @@ var (
|
||||||
|
|
||||||
// NewQuorumControlsAPI creates a new QuorumControlsAPI to access quorum services
|
// NewQuorumControlsAPI creates a new QuorumControlsAPI to access quorum services
|
||||||
func NewQuorumControlsAPI(tp *core.TxPool, am *accounts.Manager) *QuorumControlsAPI {
|
func NewQuorumControlsAPI(tp *core.TxPool, am *accounts.Manager) *QuorumControlsAPI {
|
||||||
return &QuorumControlsAPI{tp, nil, am, nil, nil, nil, false, false, nil, nil}
|
return &QuorumControlsAPI{tp, nil, am, nil, nil, false, nil, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Init initializes QuorumControlsAPI with eth client, permission contract and org key management control
|
//Init initializes QuorumControlsAPI with eth client, permission contract and org key management control
|
||||||
|
|
|
@ -175,19 +175,15 @@ var DefaultAccess = FullAccess
|
||||||
var networkAdminRole string
|
var networkAdminRole string
|
||||||
var orgAdminRole string
|
var orgAdminRole string
|
||||||
|
|
||||||
const orgKeyMapLimit = 100
|
|
||||||
|
|
||||||
const defaultMapLimit = 100
|
const defaultMapLimit = 100
|
||||||
|
|
||||||
var OrgKeyMap, _ = lru.New(orgKeyMapLimit)
|
//var OrgKeyMap, _ = lru.New(orgKeyMapLimit)
|
||||||
|
|
||||||
var OrgInfoMap = NewOrgCache()
|
var OrgInfoMap = NewOrgCache()
|
||||||
var NodeInfoMap = NewNodeCache()
|
var NodeInfoMap = NewNodeCache()
|
||||||
var RoleInfoMap = NewRoleCache()
|
var RoleInfoMap = NewRoleCache()
|
||||||
var AcctInfoMap = NewAcctCache()
|
var AcctInfoMap = NewAcctCache()
|
||||||
|
|
||||||
var orgKeyLock sync.Mutex
|
|
||||||
|
|
||||||
func (pc *PermissionConfig) IsEmpty() bool {
|
func (pc *PermissionConfig) IsEmpty() bool {
|
||||||
return pc.InterfAddress == common.HexToAddress("0x0") || pc.NodeAddress == common.HexToAddress("0x0") || pc.AccountAddress == common.HexToAddress("0x0")
|
return pc.InterfAddress == common.HexToAddress("0x0") || pc.NodeAddress == common.HexToAddress("0x0") || pc.AccountAddress == common.HexToAddress("0x0")
|
||||||
}
|
}
|
||||||
|
@ -407,49 +403,3 @@ func ValidateNodeForTxn(enodeId string, from common.Address) bool {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds org key details to cache
|
|
||||||
func AddOrgKey(orgId string, key string) {
|
|
||||||
if OrgKeyMap.Len() != 0 {
|
|
||||||
if val, ok := OrgKeyMap.Get(orgId); ok {
|
|
||||||
orgKeyLock.Lock()
|
|
||||||
defer orgKeyLock.Unlock()
|
|
||||||
// Org record exists. Append the key only
|
|
||||||
vo := val.(*OrgStruct)
|
|
||||||
vo.Keys = append(vo.Keys, key)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OrgKeyMap.Add(orgId, &OrgStruct{OrgId: orgId, Keys: []string{key}})
|
|
||||||
}
|
|
||||||
|
|
||||||
// deletes org key details from cache
|
|
||||||
func DeleteOrgKey(orgId string, key string) {
|
|
||||||
if val, ok := OrgKeyMap.Get(orgId); ok {
|
|
||||||
orgKeyLock.Lock()
|
|
||||||
defer orgKeyLock.Unlock()
|
|
||||||
vo := val.(*OrgStruct)
|
|
||||||
for i, keyVal := range vo.Keys {
|
|
||||||
if keyVal == key {
|
|
||||||
vo.Keys = append(vo.Keys[:i], vo.Keys[i+1:]...)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Givens a orgid returns the linked keys for the org
|
|
||||||
func ResolvePrivateForKeys(orgId string) []string {
|
|
||||||
var keys []string
|
|
||||||
if val, ok := OrgKeyMap.Get(orgId); ok {
|
|
||||||
vo := val.(*OrgStruct)
|
|
||||||
if len(vo.Keys) > 0 {
|
|
||||||
keys = vo.Keys
|
|
||||||
} else {
|
|
||||||
keys = append(keys, orgId)
|
|
||||||
}
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
keys = append(keys, orgId)
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
|
@ -397,12 +397,11 @@ func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs
|
||||||
if isPrivate {
|
if isPrivate {
|
||||||
// Resolve the PrivateFrom - if its a org which is linked multiple constellation keys,
|
// Resolve the PrivateFrom - if its a org which is linked multiple constellation keys,
|
||||||
// this will fetch the linked constellation ids
|
// this will fetch the linked constellation ids
|
||||||
privateFor := resolvePrivateFor(args.PrivateFor)
|
|
||||||
data := []byte(*args.Data)
|
data := []byte(*args.Data)
|
||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
log.Info("sending private tx", "data", fmt.Sprintf("%x", data), "privatefrom", args.PrivateFrom, "privatefor", privateFor)
|
log.Info("sending private tx", "data", fmt.Sprintf("%x", data), "privatefrom", args.PrivateFrom, "privatefor", args.PrivateFor)
|
||||||
data, err := private.P.Send(data, args.PrivateFrom, args.PrivateFor)
|
data, err := private.P.Send(data, args.PrivateFrom, args.PrivateFor)
|
||||||
log.Info("sent private tx", "data", fmt.Sprintf("%x", data), "privatefrom", args.PrivateFrom, "privatefor", privateFor)
|
log.Info("sent private tx", "data", fmt.Sprintf("%x", data), "privatefrom", args.PrivateFrom, "privatefor", args.PrivateFor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
@ -1383,12 +1382,11 @@ func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args Sen
|
||||||
|
|
||||||
// Resolve the PrivateFrom - if its a org which is linked multiple constellation keys,
|
// Resolve the PrivateFrom - if its a org which is linked multiple constellation keys,
|
||||||
// this will fetch the linked constellation ids
|
// this will fetch the linked constellation ids
|
||||||
privateFor := resolvePrivateFor(args.PrivateFor)
|
|
||||||
//Send private transaction to local Constellation node
|
//Send private transaction to local Constellation node
|
||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
log.Info("sending private tx", "data", fmt.Sprintf("%x", data), "privatefrom", args.PrivateFrom, "privatefor", privateFor)
|
log.Info("sending private tx", "data", fmt.Sprintf("%x", data), "privatefrom", args.PrivateFrom, "privatefor", args.PrivateFor)
|
||||||
data, err = private.P.Send(data, args.PrivateFrom, privateFor)
|
data, err = private.P.Send(data, args.PrivateFrom, args.PrivateFor)
|
||||||
log.Info("sent private tx", "data", fmt.Sprintf("%x", data), "privatefrom", args.PrivateFrom, "privatefor", privateFor)
|
log.Info("sent private tx", "data", fmt.Sprintf("%x", data), "privatefrom", args.PrivateFrom, "privatefor", args.PrivateFor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
@ -1832,13 +1830,3 @@ func (s *PublicBlockChainAPI) GetQuorumPayload(digestHex string) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
//End-Quorum
|
//End-Quorum
|
||||||
|
|
||||||
func resolvePrivateFor(privateFor []string) []string {
|
|
||||||
var newPrivateFor []string
|
|
||||||
|
|
||||||
for _, value := range privateFor {
|
|
||||||
keys := types.ResolvePrivateForKeys(value)
|
|
||||||
newPrivateFor = append(newPrivateFor, keys...)
|
|
||||||
}
|
|
||||||
return newPrivateFor
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package controls
|
package permission
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
|
@ -1,4 +1,5 @@
|
||||||
pragma solidity ^0.5.3;
|
pragma solidity ^0.5.3;
|
||||||
|
|
||||||
import "./PermissionsUpgradable.sol";
|
import "./PermissionsUpgradable.sol";
|
||||||
|
|
||||||
contract AccountManager {
|
contract AccountManager {
|
|
@ -1,4 +1,5 @@
|
||||||
pragma solidity ^0.5.3;
|
pragma solidity ^0.5.3;
|
||||||
|
|
||||||
import "./PermissionsUpgradable.sol";
|
import "./PermissionsUpgradable.sol";
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +8,7 @@ contract NodeManager {
|
||||||
// enum and struct declaration
|
// enum and struct declaration
|
||||||
// changing node status to integer (0-NotInList, 1- PendingApproval, 2-Approved, 3-Deactivated, 4-Blacklisted)
|
// changing node status to integer (0-NotInList, 1- PendingApproval, 2-Approved, 3-Deactivated, 4-Blacklisted)
|
||||||
// PendingDeactivation, Deactivated, PendingActivation, PendingBlacklisting, Blacklisted)
|
// PendingDeactivation, Deactivated, PendingActivation, PendingBlacklisting, Blacklisted)
|
||||||
// enum NodeStatus {NotInList, PendingApproval, Approved, PendingDeactivation, Deactivated, PendingActivation, PendingBlacklisting, Blacklisted}
|
// enum NodeStatus {NotInList, PendingApproval, Approved, PendingDeactivation, Deactivated, PendingActivation, PendingBlacklisting, Blacklisted}
|
||||||
struct NodeDetails {
|
struct NodeDetails {
|
||||||
string enodeId; //e.g. 127.0.0.1:20005
|
string enodeId; //e.g. 127.0.0.1:20005
|
||||||
string orgId;
|
string orgId;
|
||||||
|
@ -79,7 +80,7 @@ contract NodeManager {
|
||||||
// Get node status by enode id
|
// Get node status by enode id
|
||||||
function getNodeStatus(string memory _enodeId) public view returns (uint)
|
function getNodeStatus(string memory _enodeId) public view returns (uint)
|
||||||
{
|
{
|
||||||
if (nodeIdToIndex[keccak256(abi.encodePacked(_enodeId))] == 0){
|
if (nodeIdToIndex[keccak256(abi.encodePacked(_enodeId))] == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return nodeList[getNodeIndex(_enodeId)].status;
|
return nodeList[getNodeIndex(_enodeId)].status;
|
||||||
|
@ -100,7 +101,7 @@ contract NodeManager {
|
||||||
{
|
{
|
||||||
numberOfNodes++;
|
numberOfNodes++;
|
||||||
nodeIdToIndex[keccak256(abi.encodePacked(_enodeId))] = numberOfNodes;
|
nodeIdToIndex[keccak256(abi.encodePacked(_enodeId))] = numberOfNodes;
|
||||||
nodeList.push(NodeDetails(_enodeId, _orgId, 1));
|
nodeList.push(NodeDetails(_enodeId, _orgId, 1));
|
||||||
emit NodeProposed(_enodeId, _orgId);
|
emit NodeProposed(_enodeId, _orgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +111,7 @@ contract NodeManager {
|
||||||
{
|
{
|
||||||
numberOfNodes++;
|
numberOfNodes++;
|
||||||
nodeIdToIndex[keccak256(abi.encodePacked(_enodeId))] = numberOfNodes;
|
nodeIdToIndex[keccak256(abi.encodePacked(_enodeId))] = numberOfNodes;
|
||||||
nodeList.push(NodeDetails(_enodeId, _orgId, 2));
|
nodeList.push(NodeDetails(_enodeId, _orgId, 2));
|
||||||
emit NodeApproved(_enodeId, _orgId);
|
emit NodeApproved(_enodeId, _orgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,12 +139,12 @@ contract NodeManager {
|
||||||
// operations that can be done 3-Deactivate Node, 4-ActivateNode, 5-Blacklist nodeList
|
// operations that can be done 3-Deactivate Node, 4-ActivateNode, 5-Blacklist nodeList
|
||||||
require((_status == 3 || _status == 4 || _status == 5), "invalid operation");
|
require((_status == 3 || _status == 4 || _status == 5), "invalid operation");
|
||||||
|
|
||||||
if (_status == 3){
|
if (_status == 3) {
|
||||||
require(getNodeStatus(_enodeId) == 2, "Op cannot be performed");
|
require(getNodeStatus(_enodeId) == 2, "Op cannot be performed");
|
||||||
nodeList[getNodeIndex(_enodeId)].status = 3;
|
nodeList[getNodeIndex(_enodeId)].status = 3;
|
||||||
emit NodeDeactivated(_enodeId, _orgId);
|
emit NodeDeactivated(_enodeId, _orgId);
|
||||||
}
|
}
|
||||||
else if (_status == 4){
|
else if (_status == 4) {
|
||||||
require(getNodeStatus(_enodeId) == 3, "Op cannot be performed");
|
require(getNodeStatus(_enodeId) == 3, "Op cannot be performed");
|
||||||
nodeList[getNodeIndex(_enodeId)].status = 2;
|
nodeList[getNodeIndex(_enodeId)].status = 2;
|
||||||
emit NodeActivated(_enodeId, _orgId);
|
emit NodeActivated(_enodeId, _orgId);
|
||||||
|
@ -162,7 +163,7 @@ contract NodeManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkOrg(string memory _enodeId, string memory _orgId) internal view
|
function checkOrg(string memory _enodeId, string memory _orgId) internal view
|
||||||
returns(bool)
|
returns (bool)
|
||||||
{
|
{
|
||||||
return (keccak256(abi.encodePacked(nodeList[getNodeIndex(_enodeId)].orgId)) == keccak256(abi.encodePacked(_orgId)));
|
return (keccak256(abi.encodePacked(nodeList[getNodeIndex(_enodeId)].orgId)) == keccak256(abi.encodePacked(_orgId)));
|
||||||
}
|
}
|
|
@ -257,6 +257,7 @@ contract OrgManager {
|
||||||
{
|
{
|
||||||
return orgList[_orgIndex].subOrgIndexList.length;
|
return orgList[_orgIndex].subOrgIndexList.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSubOrgIndexLength(uint _orgIndex, uint _subOrgIndex) external view returns (uint)
|
function getSubOrgIndexLength(uint _orgIndex, uint _subOrgIndex) external view returns (uint)
|
||||||
{
|
{
|
||||||
return orgList[_orgIndex].subOrgIndexList[_subOrgIndex];
|
return orgList[_orgIndex].subOrgIndexList[_subOrgIndex];
|
|
@ -24,7 +24,7 @@ contract PermissionsInterface {
|
||||||
permImplementation = PermissionsImplementation(_permImplementation);
|
permImplementation = PermissionsImplementation(_permImplementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPermissionsImpl() public view returns(address)
|
function getPermissionsImpl() public view returns (address)
|
||||||
{
|
{
|
||||||
return address(permImplementation);
|
return address(permImplementation);
|
||||||
}
|
}
|
|
@ -18,7 +18,7 @@ contract PermissionsUpgradable {
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
function init (address _permInterface, address _permImpl) external
|
function init(address _permInterface, address _permImpl) external
|
||||||
onlyCustodian
|
onlyCustodian
|
||||||
{
|
{
|
||||||
permImpl = _permImpl;
|
permImpl = _permImpl;
|
||||||
|
@ -35,17 +35,17 @@ contract PermissionsUpgradable {
|
||||||
setImpl(permImpl);
|
setImpl(permImpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCustodian() public view returns(address)
|
function getCustodian() public view returns (address)
|
||||||
{
|
{
|
||||||
return custodian;
|
return custodian;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPermImpl() public view returns(address)
|
function getPermImpl() public view returns (address)
|
||||||
{
|
{
|
||||||
return permImpl;
|
return permImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPermInterface() public view returns(address)
|
function getPermInterface() public view returns (address)
|
||||||
{
|
{
|
||||||
return permInterface;
|
return permInterface;
|
||||||
}
|
}
|
|
@ -1,9 +1,11 @@
|
||||||
pragma solidity ^0.5.3;
|
pragma solidity ^0.5.3;
|
||||||
|
|
||||||
import "./PermissionsUpgradable.sol";
|
import "./PermissionsUpgradable.sol";
|
||||||
|
|
||||||
// TODO: check code comments
|
// TODO: check code comments
|
||||||
contract RoleManager {
|
contract RoleManager {
|
||||||
PermissionsUpgradable private permUpgradable;
|
PermissionsUpgradable private permUpgradable;
|
||||||
|
|
||||||
struct RoleDetails {
|
struct RoleDetails {
|
||||||
string roleId;
|
string roleId;
|
||||||
string orgId;
|
string orgId;
|
||||||
|
@ -75,7 +77,7 @@ contract RoleManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeRole(string calldata _roleId, string calldata _orgId) external{
|
function removeRole(string calldata _roleId, string calldata _orgId) external {
|
||||||
if (roleIndex[keccak256(abi.encodePacked(_roleId, _orgId))] != 0) {
|
if (roleIndex[keccak256(abi.encodePacked(_roleId, _orgId))] != 0) {
|
||||||
uint rIndex = getRoleIndex(_roleId, _orgId);
|
uint rIndex = getRoleIndex(_roleId, _orgId);
|
||||||
roleList[rIndex].active = false;
|
roleList[rIndex].active = false;
|
|
@ -1,4 +1,5 @@
|
||||||
pragma solidity ^0.5.3;
|
pragma solidity ^0.5.3;
|
||||||
|
|
||||||
import "./PermissionsUpgradable.sol";
|
import "./PermissionsUpgradable.sol";
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,7 +156,7 @@ contract VoterManager {
|
||||||
orgVoterList[id].pendingOp.enodeId = _enodeId;
|
orgVoterList[id].pendingOp.enodeId = _enodeId;
|
||||||
orgVoterList[id].pendingOp.account = _account;
|
orgVoterList[id].pendingOp.account = _account;
|
||||||
orgVoterList[id].pendingOp.opType = _pendingOp;
|
orgVoterList[id].pendingOp.opType = _pendingOp;
|
||||||
// init vote status
|
// init vote status
|
||||||
for (uint i = 0; i < orgVoterList[id].voterList.length; i++) {
|
for (uint i = 0; i < orgVoterList[id].voterList.length; i++) {
|
||||||
if (orgVoterList[id].voterList[i].active) {
|
if (orgVoterList[id].voterList[i].active) {
|
||||||
orgVoterList[id].votingStatus[id][orgVoterList[id].voterList[i].vAccount] = false;
|
orgVoterList[id].votingStatus[id][orgVoterList[id].voterList[i].vAccount] = false;
|
|
@ -6,8 +6,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/controls"
|
|
||||||
pbind "github.com/ethereum/go-ethereum/controls/bind/permission"
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
|
@ -16,6 +14,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
pbind "github.com/ethereum/go-ethereum/permission/bind/permission"
|
||||||
"github.com/ethereum/go-ethereum/raft"
|
"github.com/ethereum/go-ethereum/raft"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
@ -146,7 +145,7 @@ func waitForSync(e *eth.Ethereum) {
|
||||||
// Creates the controls structure for permissions
|
// Creates the controls structure for permissions
|
||||||
func NewQuorumPermissionCtrl(stack *node.Node, permissionedMode, isRaft bool, pconfig *types.PermissionConfig) (*PermissionCtrl, error) {
|
func NewQuorumPermissionCtrl(stack *node.Node, permissionedMode, isRaft bool, pconfig *types.PermissionConfig) (*PermissionCtrl, error) {
|
||||||
// Create a new ethclient to for interfacing with the contract
|
// Create a new ethclient to for interfacing with the contract
|
||||||
stateReader, e, err := controls.CreateEthClient(stack)
|
stateReader, e, err := CreateEthClient(stack)
|
||||||
waitForSync(e)
|
waitForSync(e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to create ethereum client for permissions check", "err", err)
|
log.Error("Unable to create ethereum client for permissions check", "err", err)
|
Loading…
Reference in New Issue