mirror of https://github.com/poanetwork/quorum.git
permission: update start and initialize service methods
code clean up - remove unused code related to org key
This commit is contained in:
parent
468478be78
commit
6e7f3959e3
|
@ -25,7 +25,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/permission"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"time"
|
||||
"unicode"
|
||||
|
@ -171,15 +170,9 @@ func makeFullNode(ctx *cli.Context) *node.Node {
|
|||
utils.RegisterDashboardService(stack, &cfg.Dashboard, gitCommit)
|
||||
}
|
||||
|
||||
if ctx.GlobalBool(utils.EnableNodePermissionFlag.Name) {
|
||||
fileName := "permission-config.json"
|
||||
fullPath := filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), fileName)
|
||||
if _, err := os.Stat(fullPath); err != nil {
|
||||
log.Warn("permission-config.json file is missing. permission service will be disabled", err)
|
||||
} else {
|
||||
if utils.IsPermissionEnabled(ctx) {
|
||||
RegisterPermissionService(ctx, stack)
|
||||
}
|
||||
}
|
||||
|
||||
// Whisper must be explicitly enabled by specifying at least 1 whisper flag or in dev mode
|
||||
shhEnabled := enableWhisper(ctx)
|
||||
|
@ -212,9 +205,9 @@ func RegisterPermissionService(ctx *cli.Context, stack *node.Node) {
|
|||
if permissionConfig, err = permission.ParsePermissionConifg(dataDir); err != nil {
|
||||
utils.Fatalf("loading of permission-config.json failed", "error", err)
|
||||
}
|
||||
|
||||
log.Info("AJ-permission ctrl new")
|
||||
// start the permissions management service
|
||||
pc, err := permission.NewQuorumPermissionCtrl(stack, ctx.GlobalBool(utils.EnableNodePermissionFlag.Name), ctx.GlobalBool(utils.RaftModeFlag.Name), &permissionConfig)
|
||||
pc, err := permission.NewQuorumPermissionCtrl(stack, ctx.GlobalBool(utils.RaftModeFlag.Name), &permissionConfig)
|
||||
if err != nil {
|
||||
utils.Fatalf("Failed to load the permission contracts as given in permissions-config.json %v", err)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/ethereum/go-ethereum/permission"
|
||||
"math"
|
||||
"os"
|
||||
godebug "runtime/debug"
|
||||
|
@ -343,6 +344,18 @@ func startNode(ctx *cli.Context, stack *node.Node) {
|
|||
}
|
||||
}()
|
||||
|
||||
//initialize permission as we can create eth client only after the node and RPC are started
|
||||
if utils.IsPermissionEnabled(ctx) {
|
||||
var permissionService *permission.PermissionCtrl
|
||||
stack.Service(&permissionService)
|
||||
if permissionService == nil {
|
||||
utils.Fatalf("permission service missing")
|
||||
}
|
||||
//initialize the service to create eth client and get ethereum service
|
||||
permissionService.InitializeService()
|
||||
permissionService.Start(stack.Server())
|
||||
}
|
||||
|
||||
// Start auxiliary services if enabled
|
||||
if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) {
|
||||
// Mining only makes sense if a full Ethereum node is running
|
||||
|
|
|
@ -20,9 +20,11 @@ package utils
|
|||
import (
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
@ -63,6 +65,19 @@ func Fatalf(format string, args ...interface{}) {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
func IsPermissionEnabled(ctx *cli.Context) bool {
|
||||
if ctx.GlobalBool(EnableNodePermissionFlag.Name) {
|
||||
fileName := "permission-config.json"
|
||||
fullPath := filepath.Join(ctx.GlobalString(DataDirFlag.Name), fileName)
|
||||
if _, err := os.Stat(fullPath); err != nil {
|
||||
log.Warn("permission-config.json file is missing. permission service will be disabled", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func StartNode(stack *node.Node) {
|
||||
log.Info("AJ-start node2")
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -3,19 +3,22 @@ package controls
|
|||
import (
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
)
|
||||
|
||||
// Create an RPC client for the contract interface
|
||||
func CreateEthClient(stack *node.Node) (*ethclient.Client, *eth.Ethereum, error) {
|
||||
var e *eth.Ethereum
|
||||
log.Info("AJ-CreateEthClient permission ethereum service..")
|
||||
if err := stack.Service(&e); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
log.Info("AJ-CreateEthClient permission stack attach..")
|
||||
rpcClient, err := stack.Attach()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
log.Info("AJ-permission CreateEthClient done")
|
||||
return ethclient.NewClient(rpcClient), e, nil
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -87,11 +87,6 @@ type OrgDetailInfo struct {
|
|||
SubOrgList []string `json:"subOrgList"`
|
||||
}
|
||||
|
||||
type OrgStruct struct {
|
||||
OrgId string
|
||||
Keys []string
|
||||
}
|
||||
|
||||
// permission config for bootstrapping
|
||||
type PermissionConfig struct {
|
||||
UpgrdAddress common.Address
|
||||
|
@ -407,49 +402,3 @@ func ValidateNodeForTxn(enodeId string, from common.Address) bool {
|
|||
}
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1805,10 +1805,8 @@ func (s *PublicBlockChainAPI) GetQuorumPayload(digestHex string) (string, error)
|
|||
|
||||
func resolvePrivateFor(privateFor []string) []string {
|
||||
var newPrivateFor []string
|
||||
|
||||
for _, value := range privateFor {
|
||||
keys := types.ResolvePrivateForKeys(value)
|
||||
newPrivateFor = append(newPrivateFor, keys...)
|
||||
newPrivateFor = append(newPrivateFor, value)
|
||||
}
|
||||
return newPrivateFor
|
||||
}
|
||||
|
|
|
@ -6,12 +6,11 @@ import (
|
|||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
pbind "github.com/ethereum/go-ethereum/controls/bind/permission"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
pbind "github.com/ethereum/go-ethereum/permission/bind"
|
||||
"math/big"
|
||||
"regexp"
|
||||
)
|
||||
|
@ -61,16 +60,9 @@ const (
|
|||
Inactive
|
||||
)
|
||||
|
||||
type PermissionContracts struct {
|
||||
PermInterf *pbind.PermInterface
|
||||
}
|
||||
|
||||
// QuorumControlsAPI provides an API to access Quorum's node permission and org key management related services
|
||||
type QuorumControlsAPI struct {
|
||||
txPool *core.TxPool
|
||||
acctMgr *accounts.Manager
|
||||
permConfig *types.PermissionConfig
|
||||
permInterf *pbind.PermInterface
|
||||
permCtrl *PermissionCtrl
|
||||
}
|
||||
|
||||
// txArgs holds arguments required for execute functions
|
||||
|
@ -138,26 +130,10 @@ var (
|
|||
)
|
||||
|
||||
// NewQuorumControlsAPI creates a new QuorumControlsAPI to access quorum services
|
||||
func NewQuorumControlsAPI(tp *core.TxPool, am *accounts.Manager, pcfg *types.PermissionConfig, pc *pbind.PermInterface) *QuorumControlsAPI {
|
||||
return &QuorumControlsAPI{tp, am, pcfg, pc}
|
||||
func NewQuorumControlsAPI(p *PermissionCtrl) *QuorumControlsAPI {
|
||||
return &QuorumControlsAPI{p}
|
||||
}
|
||||
|
||||
/*//Init initializes QuorumControlsAPI with eth client, permission contract and org key management control
|
||||
func (p *QuorumControlsAPI) Init(ethClnt *ethclient.Client, key *ecdsa.PrivateKey, pc *pbind.PermInterface) error {
|
||||
// check if the interface contract is deployed or not. if not
|
||||
// permissions apis will not work. return error
|
||||
p.ethClnt = ethClnt
|
||||
|
||||
if _, err := pbind.NewPermInterface(p.permConfig.InterfAddress, p.ethClnt); err != nil {
|
||||
return err
|
||||
}
|
||||
p.permEnabled = true
|
||||
p.key = key
|
||||
p.permInterf = pc
|
||||
|
||||
return nil
|
||||
}*/
|
||||
|
||||
func (s *QuorumControlsAPI) OrgList() []types.OrgInfo {
|
||||
return types.OrgInfoMap.GetOrgList()
|
||||
}
|
||||
|
@ -254,7 +230,7 @@ func (s *QuorumControlsAPI) UpdateAccountStatus(orgId string, acct common.Addres
|
|||
// check if the account is network admin
|
||||
func (s *QuorumControlsAPI) isNetworkAdmin(account common.Address) bool {
|
||||
ac := types.AcctInfoMap.GetAccount(account)
|
||||
return ac != nil && ac.RoleId == s.permConfig.NwAdminRole
|
||||
return ac != nil && ac.RoleId == s.permCtrl.permConfig.NwAdminRole
|
||||
}
|
||||
|
||||
func (s *QuorumControlsAPI) isOrgAdmin(account common.Address, orgId string) (ExecStatus, error) {
|
||||
|
@ -371,7 +347,7 @@ func (s *QuorumControlsAPI) valAccountStatusChange(orgId string, account common.
|
|||
return ErrAccountNotThere, errors.New("account not there")
|
||||
}
|
||||
|
||||
if ac.IsOrgAdmin && (ac.RoleId == s.permConfig.NwAdminRole || ac.RoleId == s.permConfig.OrgAdminRole) && (op == 1 || op == 3) {
|
||||
if ac.IsOrgAdmin && (ac.RoleId == s.permCtrl.permConfig.NwAdminRole || ac.RoleId == s.permCtrl.permConfig.OrgAdminRole) && (op == 1 || op == 3) {
|
||||
return ErrOpNotAllowed, errors.New("operation not allowed on org admin account")
|
||||
}
|
||||
|
||||
|
@ -401,7 +377,7 @@ func (s *QuorumControlsAPI) checkOrgAdminExists(orgId, roleId string, account co
|
|||
if ac.OrgId != orgId {
|
||||
return ErrAccountInUse, errors.New("account part of another org")
|
||||
}
|
||||
if roleId != "" && roleId == s.permConfig.OrgAdminRole && ac.IsOrgAdmin {
|
||||
if roleId != "" && roleId == s.permCtrl.permConfig.OrgAdminRole && ac.IsOrgAdmin {
|
||||
return ErrAccountOrgAdmin, errors.New("account already org admin for the org")
|
||||
}
|
||||
}
|
||||
|
@ -411,11 +387,11 @@ func (s *QuorumControlsAPI) checkOrgAdminExists(orgId, roleId string, account co
|
|||
func (s *QuorumControlsAPI) valSubOrgBreadthDepth(porgId string) (ExecStatus, error) {
|
||||
org := types.OrgInfoMap.GetOrg(porgId)
|
||||
|
||||
if s.permConfig.SubOrgDepth.Cmp(org.Level) == 0 {
|
||||
if s.permCtrl.permConfig.SubOrgDepth.Cmp(org.Level) == 0 {
|
||||
return ErrMaxDepth, errors.New("max depth for suborgs reached")
|
||||
}
|
||||
|
||||
if s.permConfig.SubOrgBreadth.Cmp(big.NewInt(int64(len(org.SubOrgList)))) == 0 {
|
||||
if s.permCtrl.permConfig.SubOrgBreadth.Cmp(big.NewInt(int64(len(org.SubOrgList)))) == 0 {
|
||||
return ErrMaxBreadth, errors.New("max breadth for suborgs reached")
|
||||
}
|
||||
|
||||
|
@ -484,7 +460,7 @@ func (s *QuorumControlsAPI) executePermAction(action PermAction, args txArgs) Ex
|
|||
}
|
||||
|
||||
// check if any previous op is pending approval for network admin
|
||||
if s.checkPendingOp(s.permConfig.NwAdminOrg, pinterf) {
|
||||
if s.checkPendingOp(s.permCtrl.permConfig.NwAdminOrg, pinterf) {
|
||||
return ErrPendingApprovals
|
||||
}
|
||||
// check if org already exists
|
||||
|
@ -510,7 +486,7 @@ func (s *QuorumControlsAPI) executePermAction(action PermAction, args txArgs) Ex
|
|||
return ErrNotNetworkAdmin
|
||||
}
|
||||
|
||||
if !s.validatePendingOp(s.permConfig.NwAdminOrg, args.orgId, args.url, args.acctId, 1, pinterf) {
|
||||
if !s.validatePendingOp(s.permCtrl.permConfig.NwAdminOrg, args.orgId, args.url, args.acctId, 1, pinterf) {
|
||||
return ErrNothingToApprove
|
||||
}
|
||||
|
||||
|
@ -583,7 +559,7 @@ func (s *QuorumControlsAPI) executePermAction(action PermAction, args txArgs) Ex
|
|||
} else {
|
||||
return ErrOpNotAllowed
|
||||
}
|
||||
if !s.validatePendingOp(s.permConfig.NwAdminOrg, args.orgId, "", common.Address{}, pendingOp, pinterf) {
|
||||
if !s.validatePendingOp(s.permCtrl.permConfig.NwAdminOrg, args.orgId, "", common.Address{}, pendingOp, pinterf) {
|
||||
return ErrNothingToApprove
|
||||
}
|
||||
|
||||
|
@ -625,7 +601,7 @@ func (s *QuorumControlsAPI) executePermAction(action PermAction, args txArgs) Ex
|
|||
return ErrInvalidInput
|
||||
}
|
||||
// check if caller is network admin
|
||||
if args.roleId != s.permConfig.OrgAdminRole && args.roleId != s.permConfig.NwAdminRole {
|
||||
if args.roleId != s.permCtrl.permConfig.OrgAdminRole && args.roleId != s.permCtrl.permConfig.NwAdminRole {
|
||||
return ErrOpNotAllowed
|
||||
}
|
||||
|
||||
|
@ -652,7 +628,7 @@ func (s *QuorumControlsAPI) executePermAction(action PermAction, args txArgs) Ex
|
|||
return ErrInvalidAccount
|
||||
}
|
||||
// validate pending op
|
||||
if !s.validatePendingOp(s.permConfig.NwAdminOrg, ac.OrgId, "", args.acctId, 4, pinterf) {
|
||||
if !s.validatePendingOp(s.permCtrl.permConfig.NwAdminOrg, ac.OrgId, "", args.acctId, 4, pinterf) {
|
||||
return ErrNothingToApprove
|
||||
}
|
||||
|
||||
|
@ -682,7 +658,7 @@ func (s *QuorumControlsAPI) executePermAction(action PermAction, args txArgs) Ex
|
|||
}
|
||||
|
||||
// admin roles cannot be removed
|
||||
if args.roleId == s.permConfig.OrgAdminRole || args.roleId == s.permConfig.NwAdminRole {
|
||||
if args.roleId == s.permCtrl.permConfig.OrgAdminRole || args.roleId == s.permCtrl.permConfig.NwAdminRole {
|
||||
return ErrAdminRoles
|
||||
}
|
||||
|
||||
|
@ -705,7 +681,7 @@ func (s *QuorumControlsAPI) executePermAction(action PermAction, args txArgs) Ex
|
|||
if args.acctId == (common.Address{0}) {
|
||||
return ErrInvalidInput
|
||||
}
|
||||
if args.roleId == s.permConfig.OrgAdminRole || args.roleId == s.permConfig.NwAdminRole {
|
||||
if args.roleId == s.permCtrl.permConfig.OrgAdminRole || args.roleId == s.permCtrl.permConfig.NwAdminRole {
|
||||
return ErrInvalidRole
|
||||
}
|
||||
// check if caller is network admin
|
||||
|
@ -748,7 +724,7 @@ func (s *QuorumControlsAPI) executePermAction(action PermAction, args txArgs) Ex
|
|||
// validateAccount validates the account and returns the wallet associated with that for signing the transaction
|
||||
func (s *QuorumControlsAPI) validateAccount(from common.Address) (accounts.Wallet, error) {
|
||||
acct := accounts.Account{Address: from}
|
||||
w, err := s.acctMgr.Find(acct)
|
||||
w, err := s.permCtrl.eth.AccountManager().Find(acct)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -758,7 +734,7 @@ func (s *QuorumControlsAPI) validateAccount(from common.Address) (accounts.Walle
|
|||
func (s *QuorumControlsAPI) newPermInterfaceSession(w accounts.Wallet, txa ethapi.SendTxArgs) *pbind.PermInterfaceSession {
|
||||
frmAcct, transactOpts, gasLimit, gasPrice, nonce := s.getTxParams(txa, w)
|
||||
ps := &pbind.PermInterfaceSession{
|
||||
Contract: s.permInterf,
|
||||
Contract: s.permCtrl.permInterf,
|
||||
CallOpts: bind.CallOpts{
|
||||
Pending: true,
|
||||
},
|
||||
|
@ -789,7 +765,7 @@ func (s *QuorumControlsAPI) getTxParams(txa ethapi.SendTxArgs, w accounts.Wallet
|
|||
if txa.Nonce != nil {
|
||||
nonce = new(big.Int).SetUint64(uint64(*txa.Nonce))
|
||||
} else {
|
||||
nonce = new(big.Int).SetUint64(s.txPool.Nonce(frmAcct.Address))
|
||||
nonce = new(big.Int).SetUint64(s.permCtrl.eth.TxPool().Nonce(frmAcct.Address))
|
||||
}
|
||||
return frmAcct, transactOpts, gasLimit, gasPrice, nonce
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated - DO NOT EDIT.
|
||||
// This file is a generated binding and any manual changes will be lost.
|
||||
|
||||
package permission
|
||||
package bind
|
||||
|
||||
import (
|
||||
"math/big"
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated - DO NOT EDIT.
|
||||
// This file is a generated binding and any manual changes will be lost.
|
||||
|
||||
package permission
|
||||
package bind
|
||||
|
||||
import (
|
||||
"math/big"
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated - DO NOT EDIT.
|
||||
// This file is a generated binding and any manual changes will be lost.
|
||||
|
||||
package permission
|
||||
package bind
|
||||
|
||||
import (
|
||||
"math/big"
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated - DO NOT EDIT.
|
||||
// This file is a generated binding and any manual changes will be lost.
|
||||
|
||||
package permission
|
||||
package bind
|
||||
|
||||
import (
|
||||
"math/big"
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated - DO NOT EDIT.
|
||||
// This file is a generated binding and any manual changes will be lost.
|
||||
|
||||
package permission
|
||||
package bind
|
||||
|
||||
import (
|
||||
"math/big"
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated - DO NOT EDIT.
|
||||
// This file is a generated binding and any manual changes will be lost.
|
||||
|
||||
package permission
|
||||
package bind
|
||||
|
||||
import (
|
||||
"math/big"
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated - DO NOT EDIT.
|
||||
// This file is a generated binding and any manual changes will be lost.
|
||||
|
||||
package permission
|
||||
package bind
|
||||
|
||||
import (
|
||||
"math/big"
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated - DO NOT EDIT.
|
||||
// This file is a generated binding and any manual changes will be lost.
|
||||
|
||||
package permission
|
||||
package bind
|
||||
|
||||
import (
|
||||
"math/big"
|
|
@ -7,7 +7,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"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/eth"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
|
@ -16,6 +15,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
pbind "github.com/ethereum/go-ethereum/permission/bind"
|
||||
"github.com/ethereum/go-ethereum/raft"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"io/ioutil"
|
||||
|
@ -57,7 +57,6 @@ type PermissionCtrl struct {
|
|||
ethClnt *ethclient.Client
|
||||
eth *eth.Ethereum
|
||||
isRaft bool
|
||||
permissionedMode bool
|
||||
key *ecdsa.PrivateKey
|
||||
dataDir string
|
||||
permUpgr *pbind.PermUpgr
|
||||
|
@ -73,10 +72,6 @@ type PermissionCtrl struct {
|
|||
acctChan chan struct{}
|
||||
}
|
||||
|
||||
func (p *PermissionCtrl) Interface() *pbind.PermInterface {
|
||||
return p.permInterf
|
||||
}
|
||||
|
||||
// This function takes the local config data where all the information is in string
|
||||
// converts that to address and populates the global permissions config
|
||||
func populateConfig(config PermissionLocalConfig) types.PermissionConfig {
|
||||
|
@ -136,70 +131,95 @@ func ParsePermissionConifg(dir string) (types.PermissionConfig, error) {
|
|||
}
|
||||
|
||||
func waitForSync(e *eth.Ethereum) {
|
||||
log.Info("AJ-wait for sync")
|
||||
for !types.GetSyncStatus() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
for e.Downloader().Synchronising() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
log.Info("AJ-wait for sync over")
|
||||
}
|
||||
|
||||
// Creates the controls structure for permissions
|
||||
func NewQuorumPermissionCtrl(stack *node.Node, permissionedMode, isRaft bool, pconfig *types.PermissionConfig) (*PermissionCtrl, error) {
|
||||
func NewQuorumPermissionCtrl(stack *node.Node, isRaft bool, pconfig *types.PermissionConfig) (*PermissionCtrl, error) {
|
||||
// Create a new ethclient to for interfacing with the contract
|
||||
clnt, e, err := controls.CreateEthClient(stack)
|
||||
//waitForSync(e)
|
||||
log.Info("AJ-permission eth client create")
|
||||
return &PermissionCtrl{stack, nil, nil, isRaft, stack.GetNodeKey(), stack.DataDir(), nil, nil, nil, nil, nil, nil, pconfig, make(chan struct{}), make(chan struct{}), make(chan struct{}), make(chan struct{})}, nil
|
||||
}
|
||||
|
||||
func (p *PermissionCtrl) InitializeService() error {
|
||||
clnt, ethereum, err := controls.CreateEthClient(p.node)
|
||||
if err != nil {
|
||||
log.Error("creating eth client failed")
|
||||
return err
|
||||
}
|
||||
waitForSync(ethereum)
|
||||
if err != nil {
|
||||
log.Error("Unable to create ethereum client for permissions check", "err", err)
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
if pconfig.IsEmpty() && permissionedMode {
|
||||
if p.permConfig.IsEmpty() {
|
||||
log.Error("permission-config.json is missing contract address")
|
||||
return nil, errors.New("permission-config.json is missing contract address")
|
||||
return errors.New("permission-config.json is missing contract address")
|
||||
}
|
||||
pu, err := pbind.NewPermUpgr(pconfig.UpgrdAddress, clnt)
|
||||
pu, err := pbind.NewPermUpgr(p.permConfig.UpgrdAddress, clnt)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
// check if permissioning contract is there at address. If not return from here
|
||||
pm, err := pbind.NewPermInterface(pconfig.InterfAddress, clnt)
|
||||
pm, err := pbind.NewPermInterface(p.permConfig.InterfAddress, clnt)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
pmAcct, err := pbind.NewAcctManager(pconfig.AccountAddress, clnt)
|
||||
pmAcct, err := pbind.NewAcctManager(p.permConfig.AccountAddress, clnt)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
pmNode, err := pbind.NewNodeManager(pconfig.NodeAddress, clnt)
|
||||
pmNode, err := pbind.NewNodeManager(p.permConfig.NodeAddress, clnt)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
pmRole, err := pbind.NewRoleManager(pconfig.RoleAddress, clnt)
|
||||
pmRole, err := pbind.NewRoleManager(p.permConfig.RoleAddress, clnt)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
pmOrg, err := pbind.NewOrgManager(pconfig.OrgAddress, clnt)
|
||||
pmOrg, err := pbind.NewOrgManager(p.permConfig.OrgAddress, clnt)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
return &PermissionCtrl{stack, clnt, e, isRaft, permissionedMode, stack.GetNodeKey(), stack.DataDir(), pu, pm, pmNode, pmAcct, pmRole, pmOrg, pconfig, make(chan struct{}), make(chan struct{}), make(chan struct{}), make(chan struct{})}, nil
|
||||
p.permUpgr = pu
|
||||
p.permInterf = pm
|
||||
p.permAcct = pmAcct
|
||||
p.permNode = pmNode
|
||||
p.permRole = pmRole
|
||||
p.permOrg = pmOrg
|
||||
p.ethClnt = clnt
|
||||
p.eth = ethereum
|
||||
log.Info("permission service initalized")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Starts the node permissioning and event monitoring for permissions
|
||||
// smart contracts
|
||||
func (p *PermissionCtrl) Start(srvr *p2p.Server) error {
|
||||
log.Info("permission service started...")
|
||||
|
||||
if p.ethClnt == nil || p.eth == nil {
|
||||
log.Info("permission service not initialized")
|
||||
return nil
|
||||
}
|
||||
log.Info("permission service start...")
|
||||
// Permissions initialization
|
||||
if err := p.init(); err != nil {
|
||||
log.Error("Permissions init failed", "err", err)
|
||||
|
@ -217,7 +237,7 @@ func (p *PermissionCtrl) Start(srvr *p2p.Server) error {
|
|||
|
||||
// monitor org level account management events
|
||||
go p.manageAccountPermissions()
|
||||
|
||||
log.Info("permission service started")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -227,7 +247,7 @@ func (s *PermissionCtrl) APIs() []rpc.API {
|
|||
{
|
||||
Namespace: "quorumPermission",
|
||||
Version: "1.0",
|
||||
Service: NewQuorumControlsAPI(s.eth.TxPool(), s.eth.AccountManager(), s.permConfig, s.permInterf),
|
||||
Service: NewQuorumControlsAPI(s),
|
||||
Public: true,
|
||||
},
|
||||
}
|
||||
|
@ -238,6 +258,9 @@ func (s *PermissionCtrl) Protocols() []p2p.Protocol {
|
|||
}
|
||||
|
||||
func (p *PermissionCtrl) Stop() error {
|
||||
if p.eth == nil || p.ethClnt == nil {
|
||||
return nil
|
||||
}
|
||||
log.Info("stopping permission service...")
|
||||
p.roleChan <- struct{}{}
|
||||
p.orgChan <- struct{}{}
|
||||
|
|
Loading…
Reference in New Issue