github.com/RobustRoundRobin/quorum@v20.10.0+incompatible/permission/permission.go (about)

     1  package permission
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"math/big"
     9  	"os"
    10  	"path/filepath"
    11  	"reflect"
    12  	"sync"
    13  	"time"
    14  
    15  	"github.com/ethereum/go-ethereum/accounts/abi/bind"
    16  	"github.com/ethereum/go-ethereum/common"
    17  	"github.com/ethereum/go-ethereum/core"
    18  	"github.com/ethereum/go-ethereum/core/types"
    19  	"github.com/ethereum/go-ethereum/eth"
    20  	"github.com/ethereum/go-ethereum/ethclient"
    21  	"github.com/ethereum/go-ethereum/event"
    22  	"github.com/ethereum/go-ethereum/log"
    23  	"github.com/ethereum/go-ethereum/node"
    24  	"github.com/ethereum/go-ethereum/p2p"
    25  	"github.com/ethereum/go-ethereum/p2p/enode"
    26  	"github.com/ethereum/go-ethereum/params"
    27  	pbind "github.com/ethereum/go-ethereum/permission/bind"
    28  	"github.com/ethereum/go-ethereum/raft"
    29  	"github.com/ethereum/go-ethereum/rpc"
    30  )
    31  
    32  type NodeOperation uint8
    33  
    34  const (
    35  	NodeAdd NodeOperation = iota
    36  	NodeDelete
    37  )
    38  
    39  type PermissionCtrl struct {
    40  	node       *node.Node
    41  	ethClnt    bind.ContractBackend
    42  	eth        *eth.Ethereum
    43  	key        *ecdsa.PrivateKey
    44  	dataDir    string
    45  	permUpgr   *pbind.PermUpgr
    46  	permInterf *pbind.PermInterface
    47  	permNode   *pbind.NodeManager
    48  	permAcct   *pbind.AcctManager
    49  	permRole   *pbind.RoleManager
    50  	permOrg    *pbind.OrgManager
    51  	permConfig *types.PermissionConfig
    52  
    53  	startWaitGroup *sync.WaitGroup // waitgroup to make sure all dependencies are ready before we start the service
    54  	stopFeed       event.Feed      // broadcasting stopEvent when service is being stopped
    55  	errorChan      chan error      // channel to capture error when starting aysnc
    56  
    57  	mux sync.Mutex
    58  }
    59  
    60  // to signal all watches when service is stopped
    61  type stopEvent struct {
    62  }
    63  
    64  // function reads the permissions config file passed and populates the
    65  // config structure accordingly
    66  func ParsePermissionConfig(dir string) (types.PermissionConfig, error) {
    67  	fullPath := filepath.Join(dir, params.PERMISSION_MODEL_CONFIG)
    68  	f, err := os.Open(fullPath)
    69  	if err != nil {
    70  		log.Error("can't open file", "file", fullPath, "error", err)
    71  		return types.PermissionConfig{}, err
    72  	}
    73  	defer func() {
    74  		_ = f.Close()
    75  	}()
    76  
    77  	var permConfig types.PermissionConfig
    78  	blob, err := ioutil.ReadFile(fullPath)
    79  	if err != nil {
    80  		log.Error("error reading file", "err", err, "file", fullPath)
    81  	}
    82  
    83  	err = json.Unmarshal(blob, &permConfig)
    84  	if err != nil {
    85  		log.Error("error unmarshalling the file", "err", err, "file", fullPath)
    86  	}
    87  
    88  	if len(permConfig.Accounts) == 0 {
    89  		return types.PermissionConfig{}, fmt.Errorf("no accounts given in %s. Network cannot boot up", params.PERMISSION_MODEL_CONFIG)
    90  	}
    91  	if permConfig.SubOrgDepth.Cmp(big.NewInt(0)) == 0 || permConfig.SubOrgBreadth.Cmp(big.NewInt(0)) == 0 {
    92  		return types.PermissionConfig{}, fmt.Errorf("sub org breadth depth not passed in %s. Network cannot boot up", params.PERMISSION_MODEL_CONFIG)
    93  	}
    94  	if permConfig.IsEmpty() {
    95  		return types.PermissionConfig{}, fmt.Errorf("missing contract addresses in %s", params.PERMISSION_MODEL_CONFIG)
    96  	}
    97  
    98  	return permConfig, nil
    99  }
   100  
   101  // Create a service instance for permissioning
   102  //
   103  // Permission Service depends on the following:
   104  // 1. EthService to be ready
   105  // 2. Downloader to sync up blocks
   106  // 3. InProc RPC server to be ready
   107  func NewQuorumPermissionCtrl(stack *node.Node, pconfig *types.PermissionConfig) (*PermissionCtrl, error) {
   108  	wg := &sync.WaitGroup{}
   109  	wg.Add(1)
   110  	p := &PermissionCtrl{
   111  		node:           stack,
   112  		key:            stack.GetNodeKey(),
   113  		dataDir:        stack.DataDir(),
   114  		permConfig:     pconfig,
   115  		startWaitGroup: wg,
   116  		errorChan:      make(chan error),
   117  	}
   118  
   119  	stopChan, stopSubscription := p.subscribeStopEvent()
   120  	inProcRPCServerSub := stack.EventMux().Subscribe(rpc.InProcServerReadyEvent{})
   121  	log.Debug("permission service: waiting for InProcRPC Server")
   122  
   123  	go func(_wg *sync.WaitGroup) {
   124  		defer func(start time.Time) {
   125  			log.Debug("permission service: InProcRPC server is ready", "took", time.Since(start))
   126  			stopSubscription.Unsubscribe()
   127  			inProcRPCServerSub.Unsubscribe()
   128  			_wg.Done()
   129  		}(time.Now())
   130  		select {
   131  		case <-inProcRPCServerSub.Chan():
   132  		case <-stopChan:
   133  		}
   134  	}(wg) // wait for inproc RPC to be ready
   135  	return p, nil
   136  }
   137  
   138  func (p *PermissionCtrl) bindContract(contractInstance interface{}, bindFunc func() (interface{}, error)) error {
   139  	element := reflect.ValueOf(contractInstance).Elem()
   140  	instance, err := bindFunc()
   141  	if err != nil {
   142  		return err
   143  	}
   144  	element.Set(reflect.ValueOf(instance))
   145  	return nil
   146  }
   147  
   148  // This is to make sure all contract instances are ready and initialized
   149  //
   150  // Required to be call after standard service start lifecycle
   151  func (p *PermissionCtrl) AfterStart() error {
   152  	log.Debug("permission service: binding contracts")
   153  	err := <-p.errorChan // capture any error happened during asyncStart. Also wait here if asyncStart is not yet finish
   154  	if err != nil {
   155  		return err
   156  	}
   157  	if err := p.bindContract(&p.permUpgr, func() (interface{}, error) { return pbind.NewPermUpgr(p.permConfig.UpgrdAddress, p.ethClnt) }); err != nil {
   158  		return err
   159  	}
   160  	if err := p.bindContract(&p.permInterf, func() (interface{}, error) { return pbind.NewPermInterface(p.permConfig.InterfAddress, p.ethClnt) }); err != nil {
   161  		return err
   162  	}
   163  	if err := p.bindContract(&p.permAcct, func() (interface{}, error) { return pbind.NewAcctManager(p.permConfig.AccountAddress, p.ethClnt) }); err != nil {
   164  		return err
   165  	}
   166  	if err := p.bindContract(&p.permNode, func() (interface{}, error) { return pbind.NewNodeManager(p.permConfig.NodeAddress, p.ethClnt) }); err != nil {
   167  		return err
   168  	}
   169  	if err := p.bindContract(&p.permRole, func() (interface{}, error) { return pbind.NewRoleManager(p.permConfig.RoleAddress, p.ethClnt) }); err != nil {
   170  		return err
   171  	}
   172  	if err := p.bindContract(&p.permOrg, func() (interface{}, error) { return pbind.NewOrgManager(p.permConfig.OrgAddress, p.ethClnt) }); err != nil {
   173  		return err
   174  	}
   175  
   176  	// populate the initial list of permissioned nodes and account accesses
   177  	if err := p.populateInitPermissions(params.DEFAULT_ORGCACHE_SIZE, params.DEFAULT_ROLECACHE_SIZE,
   178  		params.DEFAULT_NODECACHE_SIZE, params.DEFAULT_ACCOUNTCACHE_SIZE); err != nil {
   179  		return fmt.Errorf("populateInitPermissions failed: %v", err)
   180  	}
   181  
   182  	// set the default access to ReadOnly
   183  	types.SetDefaults(p.permConfig.NwAdminRole, p.permConfig.OrgAdminRole)
   184  
   185  	for _, f := range []func() error{
   186  		p.monitorQIP714Block,       // monitor block number to activate new permissions controls
   187  		p.manageOrgPermissions,     // monitor org management related events
   188  		p.manageNodePermissions,    // monitor org  level node management events
   189  		p.manageRolePermissions,    // monitor org level role management events
   190  		p.manageAccountPermissions, // monitor org level account management events
   191  	} {
   192  		if err := f(); err != nil {
   193  			return err
   194  		}
   195  	}
   196  
   197  	log.Info("permission service: is now ready")
   198  
   199  	return nil
   200  }
   201  
   202  // start service asynchronously due to dependencies
   203  func (p *PermissionCtrl) asyncStart() {
   204  	var ethereum *eth.Ethereum
   205  	// will be blocked here until node is up
   206  	if err := p.node.Service(&ethereum); err != nil {
   207  		p.errorChan <- fmt.Errorf("dependent ethereum service not started")
   208  		return
   209  	}
   210  	defer func() {
   211  		p.errorChan <- nil
   212  	}()
   213  	// for cases where the node is joining an existing network, permission service
   214  	// can be brought up only after block syncing is complete. This function
   215  	// waits for block syncing before the starting permissions
   216  	p.startWaitGroup.Add(1)
   217  	go func(_wg *sync.WaitGroup) {
   218  		log.Debug("permission service: waiting for downloader")
   219  		stopChan, stopSubscription := p.subscribeStopEvent()
   220  		pollingTicker := time.NewTicker(10 * time.Millisecond)
   221  		defer func(start time.Time) {
   222  			log.Debug("permission service: downloader completed", "took", time.Since(start))
   223  			stopSubscription.Unsubscribe()
   224  			pollingTicker.Stop()
   225  			_wg.Done()
   226  		}(time.Now())
   227  		for {
   228  			select {
   229  			case <-pollingTicker.C:
   230  				if types.GetSyncStatus() && !ethereum.Downloader().Synchronising() {
   231  					return
   232  				}
   233  			case <-stopChan:
   234  				return
   235  			}
   236  		}
   237  	}(p.startWaitGroup) // wait for downloader to sync if any
   238  
   239  	log.Debug("permission service: waiting for all dependencies to be ready")
   240  	p.startWaitGroup.Wait()
   241  	client, err := p.node.Attach()
   242  	if err != nil {
   243  		p.errorChan <- fmt.Errorf("unable to create rpc client: %v", err)
   244  		return
   245  	}
   246  	p.ethClnt = ethclient.NewClient(client)
   247  	p.eth = ethereum
   248  }
   249  
   250  func (p *PermissionCtrl) Start(srvr *p2p.Server) error {
   251  	log.Debug("permission service: starting")
   252  	go func() {
   253  		log.Debug("permission service: starting async")
   254  		p.asyncStart()
   255  	}()
   256  	return nil
   257  }
   258  
   259  func (p *PermissionCtrl) APIs() []rpc.API {
   260  	return []rpc.API{
   261  		{
   262  			Namespace: "quorumPermission",
   263  			Version:   "1.0",
   264  			Service:   NewQuorumControlsAPI(p),
   265  			Public:    true,
   266  		},
   267  	}
   268  }
   269  
   270  func (p *PermissionCtrl) Protocols() []p2p.Protocol {
   271  	return []p2p.Protocol{}
   272  }
   273  
   274  func (p *PermissionCtrl) Stop() error {
   275  	log.Info("permission service: stopping")
   276  	p.stopFeed.Send(stopEvent{})
   277  	log.Info("permission service: stopped")
   278  	return nil
   279  }
   280  
   281  // monitors QIP714Block and set default access
   282  func (p *PermissionCtrl) monitorQIP714Block() error {
   283  	// if QIP714block is not given, set the default access
   284  	// to readonly
   285  	if p.eth.BlockChain().Config().QIP714Block == nil {
   286  		types.SetDefaultAccess()
   287  		return nil
   288  	}
   289  	//QIP714block is given, monitor block count
   290  	go func() {
   291  		chainHeadCh := make(chan core.ChainHeadEvent, 1)
   292  		headSub := p.eth.BlockChain().SubscribeChainHeadEvent(chainHeadCh)
   293  		defer headSub.Unsubscribe()
   294  		stopChan, stopSubscription := p.subscribeStopEvent()
   295  		defer stopSubscription.Unsubscribe()
   296  		for {
   297  			select {
   298  			case head := <-chainHeadCh:
   299  				if p.eth.BlockChain().Config().IsQIP714(head.Block.Number()) {
   300  					types.SetDefaultAccess()
   301  					return
   302  				}
   303  			case <-stopChan:
   304  				return
   305  			}
   306  		}
   307  	}()
   308  	return nil
   309  }
   310  
   311  // monitors org management related events happening via smart contracts
   312  // and updates cache accordingly
   313  func (p *PermissionCtrl) manageOrgPermissions() error {
   314  	chPendingApproval := make(chan *pbind.OrgManagerOrgPendingApproval, 1)
   315  	chOrgApproved := make(chan *pbind.OrgManagerOrgApproved, 1)
   316  	chOrgSuspended := make(chan *pbind.OrgManagerOrgSuspended, 1)
   317  	chOrgReactivated := make(chan *pbind.OrgManagerOrgSuspensionRevoked, 1)
   318  
   319  	opts := &bind.WatchOpts{}
   320  	var blockNumber uint64 = 1
   321  	opts.Start = &blockNumber
   322  
   323  	if _, err := p.permOrg.OrgManagerFilterer.WatchOrgPendingApproval(opts, chPendingApproval); err != nil {
   324  		return fmt.Errorf("failed WatchNodePendingApproval: %v", err)
   325  	}
   326  
   327  	if _, err := p.permOrg.OrgManagerFilterer.WatchOrgApproved(opts, chOrgApproved); err != nil {
   328  		return fmt.Errorf("failed WatchNodePendingApproval: %v", err)
   329  	}
   330  
   331  	if _, err := p.permOrg.OrgManagerFilterer.WatchOrgSuspended(opts, chOrgSuspended); err != nil {
   332  		return fmt.Errorf("failed WatchNodePendingApproval: %v", err)
   333  	}
   334  
   335  	if _, err := p.permOrg.OrgManagerFilterer.WatchOrgSuspensionRevoked(opts, chOrgReactivated); err != nil {
   336  		return fmt.Errorf("failed WatchNodePendingApproval: %v", err)
   337  	}
   338  
   339  	go func() {
   340  		stopChan, stopSubscription := p.subscribeStopEvent()
   341  		defer stopSubscription.Unsubscribe()
   342  		for {
   343  			select {
   344  			case evtPendingApproval := <-chPendingApproval:
   345  				types.OrgInfoMap.UpsertOrg(evtPendingApproval.OrgId, evtPendingApproval.PorgId, evtPendingApproval.UltParent, evtPendingApproval.Level, types.OrgStatus(evtPendingApproval.Status.Uint64()))
   346  
   347  			case evtOrgApproved := <-chOrgApproved:
   348  				types.OrgInfoMap.UpsertOrg(evtOrgApproved.OrgId, evtOrgApproved.PorgId, evtOrgApproved.UltParent, evtOrgApproved.Level, types.OrgApproved)
   349  
   350  			case evtOrgSuspended := <-chOrgSuspended:
   351  				types.OrgInfoMap.UpsertOrg(evtOrgSuspended.OrgId, evtOrgSuspended.PorgId, evtOrgSuspended.UltParent, evtOrgSuspended.Level, types.OrgSuspended)
   352  
   353  			case evtOrgReactivated := <-chOrgReactivated:
   354  				types.OrgInfoMap.UpsertOrg(evtOrgReactivated.OrgId, evtOrgReactivated.PorgId, evtOrgReactivated.UltParent, evtOrgReactivated.Level, types.OrgApproved)
   355  			case <-stopChan:
   356  				log.Info("quit org contract watch")
   357  				return
   358  			}
   359  		}
   360  	}()
   361  	return nil
   362  }
   363  
   364  func (p *PermissionCtrl) subscribeStopEvent() (chan stopEvent, event.Subscription) {
   365  	c := make(chan stopEvent)
   366  	s := p.stopFeed.Subscribe(c)
   367  	return c, s
   368  }
   369  
   370  // Monitors node management events and updates cache accordingly
   371  func (p *PermissionCtrl) manageNodePermissions() error {
   372  	chNodeApproved := make(chan *pbind.NodeManagerNodeApproved, 1)
   373  	chNodeProposed := make(chan *pbind.NodeManagerNodeProposed, 1)
   374  	chNodeDeactivated := make(chan *pbind.NodeManagerNodeDeactivated, 1)
   375  	chNodeActivated := make(chan *pbind.NodeManagerNodeActivated, 1)
   376  	chNodeBlacklisted := make(chan *pbind.NodeManagerNodeBlacklisted)
   377  	chNodeRecoveryInit := make(chan *pbind.NodeManagerNodeRecoveryInitiated, 1)
   378  	chNodeRecoveryDone := make(chan *pbind.NodeManagerNodeRecoveryCompleted, 1)
   379  
   380  	opts := &bind.WatchOpts{}
   381  	var blockNumber uint64 = 1
   382  	opts.Start = &blockNumber
   383  
   384  	if _, err := p.permNode.NodeManagerFilterer.WatchNodeApproved(opts, chNodeApproved); err != nil {
   385  		return fmt.Errorf("failed WatchNodeApproved: %v", err)
   386  	}
   387  
   388  	if _, err := p.permNode.NodeManagerFilterer.WatchNodeProposed(opts, chNodeProposed); err != nil {
   389  		return fmt.Errorf("failed WatchNodeProposed: %v", err)
   390  	}
   391  
   392  	if _, err := p.permNode.NodeManagerFilterer.WatchNodeDeactivated(opts, chNodeDeactivated); err != nil {
   393  		return fmt.Errorf("failed NodeDeactivated: %v", err)
   394  	}
   395  	if _, err := p.permNode.NodeManagerFilterer.WatchNodeActivated(opts, chNodeActivated); err != nil {
   396  		return fmt.Errorf("failed WatchNodeActivated: %v", err)
   397  	}
   398  
   399  	if _, err := p.permNode.NodeManagerFilterer.WatchNodeBlacklisted(opts, chNodeBlacklisted); err != nil {
   400  		return fmt.Errorf("failed NodeBlacklisting: %v", err)
   401  	}
   402  
   403  	if _, err := p.permNode.NodeManagerFilterer.WatchNodeRecoveryInitiated(opts, chNodeRecoveryInit); err != nil {
   404  		return fmt.Errorf("failed NodeRecoveryInitiated: %v", err)
   405  	}
   406  
   407  	if _, err := p.permNode.NodeManagerFilterer.WatchNodeRecoveryCompleted(opts, chNodeRecoveryDone); err != nil {
   408  		return fmt.Errorf("failed NodeRecoveryCompleted: %v", err)
   409  	}
   410  
   411  	go func() {
   412  		stopChan, stopSubscription := p.subscribeStopEvent()
   413  		defer stopSubscription.Unsubscribe()
   414  		for {
   415  			select {
   416  			case evtNodeApproved := <-chNodeApproved:
   417  				p.updatePermissionedNodes(evtNodeApproved.EnodeId, NodeAdd)
   418  				types.NodeInfoMap.UpsertNode(evtNodeApproved.OrgId, evtNodeApproved.EnodeId, types.NodeApproved)
   419  
   420  			case evtNodeProposed := <-chNodeProposed:
   421  				types.NodeInfoMap.UpsertNode(evtNodeProposed.OrgId, evtNodeProposed.EnodeId, types.NodePendingApproval)
   422  
   423  			case evtNodeDeactivated := <-chNodeDeactivated:
   424  				p.updatePermissionedNodes(evtNodeDeactivated.EnodeId, NodeDelete)
   425  				types.NodeInfoMap.UpsertNode(evtNodeDeactivated.OrgId, evtNodeDeactivated.EnodeId, types.NodeDeactivated)
   426  
   427  			case evtNodeActivated := <-chNodeActivated:
   428  				p.updatePermissionedNodes(evtNodeActivated.EnodeId, NodeAdd)
   429  				types.NodeInfoMap.UpsertNode(evtNodeActivated.OrgId, evtNodeActivated.EnodeId, types.NodeApproved)
   430  
   431  			case evtNodeBlacklisted := <-chNodeBlacklisted:
   432  				types.NodeInfoMap.UpsertNode(evtNodeBlacklisted.OrgId, evtNodeBlacklisted.EnodeId, types.NodeBlackListed)
   433  				p.updateDisallowedNodes(evtNodeBlacklisted.EnodeId, NodeAdd)
   434  				p.updatePermissionedNodes(evtNodeBlacklisted.EnodeId, NodeDelete)
   435  
   436  			case evtNodeRecoveryInit := <-chNodeRecoveryInit:
   437  				types.NodeInfoMap.UpsertNode(evtNodeRecoveryInit.OrgId, evtNodeRecoveryInit.EnodeId, types.NodeRecoveryInitiated)
   438  
   439  			case evtNodeRecoveryDone := <-chNodeRecoveryDone:
   440  				types.NodeInfoMap.UpsertNode(evtNodeRecoveryDone.OrgId, evtNodeRecoveryDone.EnodeId, types.NodeApproved)
   441  				p.updateDisallowedNodes(evtNodeRecoveryDone.EnodeId, NodeDelete)
   442  				p.updatePermissionedNodes(evtNodeRecoveryDone.EnodeId, NodeAdd)
   443  
   444  			case <-stopChan:
   445  				log.Info("quit node contract watch")
   446  				return
   447  			}
   448  		}
   449  	}()
   450  	return nil
   451  }
   452  
   453  // adds or deletes and entry from a given file
   454  func (p *PermissionCtrl) updateFile(fileName, enodeId string, operation NodeOperation, createFile bool) {
   455  	// Load the nodes from the config file
   456  	var nodeList []string
   457  	index := 0
   458  	// if createFile is false means the file is already existing. read the file
   459  	if !createFile {
   460  		blob, err := ioutil.ReadFile(fileName)
   461  		if err != nil && !createFile {
   462  			log.Error("Failed to access the file", "fileName", fileName, "err", err)
   463  			return
   464  		}
   465  
   466  		if err := json.Unmarshal(blob, &nodeList); err != nil {
   467  			log.Error("Failed to load nodes list from file", "fileName", fileName, "err", err)
   468  			return
   469  		}
   470  
   471  		// logic to update the permissioned-nodes.json file based on action
   472  
   473  		recExists := false
   474  		for i, eid := range nodeList {
   475  			if eid == enodeId {
   476  				index = i
   477  				recExists = true
   478  				break
   479  			}
   480  		}
   481  		if (operation == NodeAdd && recExists) || (operation == NodeDelete && !recExists) {
   482  			return
   483  		}
   484  	}
   485  	if operation == NodeAdd {
   486  		nodeList = append(nodeList, enodeId)
   487  	} else {
   488  		nodeList = append(nodeList[:index], nodeList[index+1:]...)
   489  	}
   490  	blob, _ := json.Marshal(nodeList)
   491  
   492  	p.mux.Lock()
   493  	defer p.mux.Unlock()
   494  
   495  	if err := ioutil.WriteFile(fileName, blob, 0644); err != nil {
   496  		log.Error("Error writing new node info to file", "fileName", fileName, "err", err)
   497  	}
   498  }
   499  
   500  // updates node information in the permissioned-nodes.json file based on node
   501  // management activities in smart contract
   502  func (p *PermissionCtrl) updatePermissionedNodes(enodeId string, operation NodeOperation) {
   503  	log.Debug("updatePermissionedNodes", "DataDir", p.dataDir, "file", params.PERMISSIONED_CONFIG)
   504  
   505  	path := filepath.Join(p.dataDir, params.PERMISSIONED_CONFIG)
   506  	if _, err := os.Stat(path); err != nil {
   507  		log.Error("Read Error for permissioned-nodes.json file. This is because 'permissioned' flag is specified but no permissioned-nodes.json file is present", "err", err)
   508  		return
   509  	}
   510  
   511  	p.updateFile(path, enodeId, operation, false)
   512  	if operation == NodeDelete {
   513  		p.disconnectNode(enodeId)
   514  	}
   515  }
   516  
   517  //this function populates the black listed node information into the disallowed-nodes.json file
   518  func (p *PermissionCtrl) updateDisallowedNodes(url string, operation NodeOperation) {
   519  	log.Debug("updateDisallowedNodes", "DataDir", p.dataDir, "file", params.BLACKLIST_CONFIG)
   520  
   521  	fileExists := true
   522  	path := filepath.Join(p.dataDir, params.BLACKLIST_CONFIG)
   523  	// Check if the file is existing. If the file is not existing create the file
   524  	if _, err := os.Stat(path); err != nil {
   525  		log.Error("Read Error for disallowed-nodes.json file", "err", err)
   526  		if _, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0644); err != nil {
   527  			log.Error("Failed to create disallowed-nodes.json file", "err", err)
   528  			return
   529  		}
   530  		fileExists = false
   531  	}
   532  
   533  	if fileExists {
   534  		p.updateFile(path, url, operation, false)
   535  	} else {
   536  		p.updateFile(path, url, operation, true)
   537  	}
   538  }
   539  
   540  // Monitors account access related events and updates the cache accordingly
   541  func (p *PermissionCtrl) manageAccountPermissions() error {
   542  	chAccessModified := make(chan *pbind.AcctManagerAccountAccessModified)
   543  	chAccessRevoked := make(chan *pbind.AcctManagerAccountAccessRevoked)
   544  	chStatusChanged := make(chan *pbind.AcctManagerAccountStatusChanged)
   545  
   546  	opts := &bind.WatchOpts{}
   547  	var blockNumber uint64 = 1
   548  	opts.Start = &blockNumber
   549  
   550  	if _, err := p.permAcct.AcctManagerFilterer.WatchAccountAccessModified(opts, chAccessModified); err != nil {
   551  		return fmt.Errorf("failed AccountAccessModified: %v", err)
   552  	}
   553  
   554  	if _, err := p.permAcct.AcctManagerFilterer.WatchAccountAccessRevoked(opts, chAccessRevoked); err != nil {
   555  		return fmt.Errorf("failed AccountAccessRevoked: %v", err)
   556  	}
   557  
   558  	if _, err := p.permAcct.AcctManagerFilterer.WatchAccountStatusChanged(opts, chStatusChanged); err != nil {
   559  		return fmt.Errorf("failed AccountStatusChanged: %v", err)
   560  	}
   561  
   562  	go func() {
   563  		stopChan, stopSubscription := p.subscribeStopEvent()
   564  		defer stopSubscription.Unsubscribe()
   565  		for {
   566  			select {
   567  			case evtAccessModified := <-chAccessModified:
   568  				types.AcctInfoMap.UpsertAccount(evtAccessModified.OrgId, evtAccessModified.RoleId, evtAccessModified.Account, evtAccessModified.OrgAdmin, types.AcctStatus(int(evtAccessModified.Status.Uint64())))
   569  
   570  			case evtAccessRevoked := <-chAccessRevoked:
   571  				types.AcctInfoMap.UpsertAccount(evtAccessRevoked.OrgId, evtAccessRevoked.RoleId, evtAccessRevoked.Account, evtAccessRevoked.OrgAdmin, types.AcctActive)
   572  
   573  			case evtStatusChanged := <-chStatusChanged:
   574  				if ac, err := types.AcctInfoMap.GetAccount(evtStatusChanged.Account); ac != nil {
   575  					types.AcctInfoMap.UpsertAccount(evtStatusChanged.OrgId, ac.RoleId, evtStatusChanged.Account, ac.IsOrgAdmin, types.AcctStatus(int(evtStatusChanged.Status.Uint64())))
   576  				} else {
   577  					log.Info("error fetching account information", "err", err)
   578  				}
   579  			case <-stopChan:
   580  				log.Info("quit account contract watch")
   581  				return
   582  			}
   583  		}
   584  	}()
   585  	return nil
   586  }
   587  
   588  // Disconnect the node from the network
   589  func (p *PermissionCtrl) disconnectNode(enodeId string) {
   590  	if p.eth.BlockChain().Config().Istanbul == nil && p.eth.BlockChain().Config().Clique == nil {
   591  		var raftService *raft.RaftService
   592  		if err := p.node.Service(&raftService); err == nil {
   593  			raftApi := raft.NewPublicRaftAPI(raftService)
   594  
   595  			//get the raftId for the given enodeId
   596  			raftId, err := raftApi.GetRaftId(enodeId)
   597  			if err == nil {
   598  				raftApi.RemovePeer(raftId)
   599  			} else {
   600  				log.Error("failed to get raft id", "err", err, "enodeId", enodeId)
   601  			}
   602  		}
   603  	} else {
   604  		// Istanbul  or clique - disconnect the peer
   605  		server := p.node.Server()
   606  		if server != nil {
   607  			node, err := enode.ParseV4(enodeId)
   608  			if err == nil {
   609  				server.RemovePeer(node)
   610  			} else {
   611  				log.Error("failed parse node id", "err", err, "enodeId", enodeId)
   612  			}
   613  		}
   614  	}
   615  
   616  }
   617  
   618  func (p *PermissionCtrl) instantiateCache(orgCacheSize, roleCacheSize, nodeCacheSize, accountCacheSize int) {
   619  	// instantiate the cache objects for permissions
   620  	types.OrgInfoMap = types.NewOrgCache(orgCacheSize)
   621  	types.OrgInfoMap.PopulateCacheFunc(p.populateOrgToCache)
   622  
   623  	types.RoleInfoMap = types.NewRoleCache(roleCacheSize)
   624  	types.RoleInfoMap.PopulateCacheFunc(p.populateRoleToCache)
   625  
   626  	types.NodeInfoMap = types.NewNodeCache(nodeCacheSize)
   627  	types.NodeInfoMap.PopulateCacheFunc(p.populateNodeCache)
   628  	types.NodeInfoMap.PopulateValidateFunc(p.populateNodeCacheAndValidate)
   629  
   630  	types.AcctInfoMap = types.NewAcctCache(accountCacheSize)
   631  	types.AcctInfoMap.PopulateCacheFunc(p.populateAccountToCache)
   632  }
   633  
   634  // Thus function checks if the initial network boot up status and if no
   635  // populates permissions model with details from permission-config.json
   636  func (p *PermissionCtrl) populateInitPermissions(orgCacheSize, roleCacheSize, nodeCacheSize, accountCacheSize int) error {
   637  	auth := bind.NewKeyedTransactor(p.key)
   638  	permInterfSession := &pbind.PermInterfaceSession{
   639  		Contract: p.permInterf,
   640  		CallOpts: bind.CallOpts{
   641  			Pending: true,
   642  		},
   643  		TransactOpts: bind.TransactOpts{
   644  			From:     auth.From,
   645  			Signer:   auth.Signer,
   646  			GasLimit: 47000000,
   647  			GasPrice: big.NewInt(0),
   648  		},
   649  	}
   650  
   651  	p.instantiateCache(orgCacheSize, roleCacheSize, nodeCacheSize, accountCacheSize)
   652  
   653  	networkInitialized, err := permInterfSession.GetNetworkBootStatus()
   654  	if err != nil {
   655  		// handle the scenario of no contract code.
   656  		log.Warn("Failed to retrieve network boot status ", "err", err)
   657  		return err
   658  	}
   659  
   660  	if !networkInitialized {
   661  		if err := p.bootupNetwork(permInterfSession); err != nil {
   662  			return err
   663  		}
   664  	} else {
   665  		//populate orgs, nodes, roles and accounts from contract
   666  		for _, f := range []func(auth *bind.TransactOpts) error{
   667  			p.populateOrgsFromContract,
   668  			p.populateNodesFromContract,
   669  			p.populateRolesFromContract,
   670  			p.populateAccountsFromContract,
   671  		} {
   672  			if err := f(auth); err != nil {
   673  				return err
   674  			}
   675  		}
   676  	}
   677  	return nil
   678  }
   679  
   680  // initialize the permissions model and populate initial values
   681  func (p *PermissionCtrl) bootupNetwork(permInterfSession *pbind.PermInterfaceSession) error {
   682  	if _, err := permInterfSession.SetPolicy(p.permConfig.NwAdminOrg, p.permConfig.NwAdminRole, p.permConfig.OrgAdminRole); err != nil {
   683  		log.Error("bootupNetwork SetPolicy failed", "err", err)
   684  		return err
   685  	}
   686  	if _, err := permInterfSession.Init(p.permConfig.SubOrgBreadth, p.permConfig.SubOrgDepth); err != nil {
   687  		log.Error("bootupNetwork init failed", "err", err)
   688  		return err
   689  	}
   690  
   691  	types.OrgInfoMap.UpsertOrg(p.permConfig.NwAdminOrg, "", p.permConfig.NwAdminOrg, big.NewInt(1), types.OrgApproved)
   692  	types.RoleInfoMap.UpsertRole(p.permConfig.NwAdminOrg, p.permConfig.NwAdminRole, true, true, types.FullAccess, true)
   693  	// populate the initial node list from static-nodes.json
   694  	if err := p.populateStaticNodesToContract(permInterfSession); err != nil {
   695  		return err
   696  	}
   697  	// populate initial account access to full access
   698  	if err := p.populateInitAccountAccess(permInterfSession); err != nil {
   699  		return err
   700  	}
   701  
   702  	// update network status to boot completed
   703  	if err := p.updateNetworkStatus(permInterfSession); err != nil {
   704  		log.Error("failed to updated network boot status", "error", err)
   705  		return err
   706  	}
   707  	return nil
   708  }
   709  
   710  // populates the account access details from contract into cache
   711  func (p *PermissionCtrl) populateAccountsFromContract(auth *bind.TransactOpts) error {
   712  	//populate accounts
   713  	permAcctSession := &pbind.AcctManagerSession{
   714  		Contract: p.permAcct,
   715  		CallOpts: bind.CallOpts{
   716  			Pending: true,
   717  		},
   718  	}
   719  
   720  	if numberOfRoles, err := permAcctSession.GetNumberOfAccounts(); err == nil {
   721  		iOrgNum := numberOfRoles.Uint64()
   722  		for k := uint64(0); k < iOrgNum; k++ {
   723  			if addr, org, role, status, orgAdmin, err := permAcctSession.GetAccountDetailsFromIndex(big.NewInt(int64(k))); err == nil {
   724  				types.AcctInfoMap.UpsertAccount(org, role, addr, orgAdmin, types.AcctStatus(int(status.Int64())))
   725  			}
   726  		}
   727  	} else {
   728  		return err
   729  	}
   730  	return nil
   731  }
   732  
   733  // populates the role details from contract into cache
   734  func (p *PermissionCtrl) populateRolesFromContract(auth *bind.TransactOpts) error {
   735  	//populate roles
   736  	permRoleSession := &pbind.RoleManagerSession{
   737  		Contract: p.permRole,
   738  		CallOpts: bind.CallOpts{
   739  			Pending: true,
   740  		},
   741  	}
   742  	if numberOfRoles, err := permRoleSession.GetNumberOfRoles(); err == nil {
   743  		iOrgNum := numberOfRoles.Uint64()
   744  		for k := uint64(0); k < iOrgNum; k++ {
   745  			if roleStruct, err := permRoleSession.GetRoleDetailsFromIndex(big.NewInt(int64(k))); err == nil {
   746  				types.RoleInfoMap.UpsertRole(roleStruct.OrgId, roleStruct.RoleId, roleStruct.Voter, roleStruct.Admin, types.AccessType(int(roleStruct.AccessType.Int64())), roleStruct.Active)
   747  			}
   748  		}
   749  
   750  	} else {
   751  		return err
   752  	}
   753  	return nil
   754  }
   755  
   756  // populates the node details from contract into cache
   757  func (p *PermissionCtrl) populateNodesFromContract(auth *bind.TransactOpts) error {
   758  	//populate nodes
   759  	permNodeSession := &pbind.NodeManagerSession{
   760  		Contract: p.permNode,
   761  		CallOpts: bind.CallOpts{
   762  			Pending: true,
   763  		},
   764  	}
   765  	if numberOfNodes, err := permNodeSession.GetNumberOfNodes(); err == nil {
   766  		iOrgNum := numberOfNodes.Uint64()
   767  		for k := uint64(0); k < iOrgNum; k++ {
   768  			if nodeStruct, err := permNodeSession.GetNodeDetailsFromIndex(big.NewInt(int64(k))); err == nil {
   769  				types.NodeInfoMap.UpsertNode(nodeStruct.OrgId, nodeStruct.EnodeId, types.NodeStatus(int(nodeStruct.NodeStatus.Int64())))
   770  			}
   771  		}
   772  	} else {
   773  		return err
   774  	}
   775  	return nil
   776  }
   777  
   778  // populates the org details from contract into cache
   779  func (p *PermissionCtrl) populateOrgsFromContract(auth *bind.TransactOpts) error {
   780  	//populate orgs
   781  	permOrgSession := &pbind.OrgManagerSession{
   782  		Contract: p.permOrg,
   783  		CallOpts: bind.CallOpts{
   784  			Pending: true,
   785  		},
   786  	}
   787  	if numberOfOrgs, err := permOrgSession.GetNumberOfOrgs(); err == nil {
   788  		iOrgNum := numberOfOrgs.Uint64()
   789  		for k := uint64(0); k < iOrgNum; k++ {
   790  			if orgId, porgId, ultParent, level, status, err := permOrgSession.GetOrgInfo(big.NewInt(int64(k))); err == nil {
   791  				types.OrgInfoMap.UpsertOrg(orgId, porgId, ultParent, level, types.OrgStatus(int(status.Int64())))
   792  			}
   793  		}
   794  	} else {
   795  		return err
   796  	}
   797  	return nil
   798  }
   799  
   800  // Reads the node list from static-nodes.json and populates into the contract
   801  func (p *PermissionCtrl) populateStaticNodesToContract(permissionsSession *pbind.PermInterfaceSession) error {
   802  	nodes := p.node.Server().Config.StaticNodes
   803  	for _, node := range nodes {
   804  		_, err := permissionsSession.AddAdminNode(node.String())
   805  		if err != nil {
   806  			log.Warn("Failed to propose node", "err", err, "enode", node.EnodeID())
   807  			return err
   808  		}
   809  		types.NodeInfoMap.UpsertNode(p.permConfig.NwAdminOrg, node.String(), 2)
   810  	}
   811  	return nil
   812  }
   813  
   814  // Invokes the initAccounts function of smart contract to set the initial
   815  // set of accounts access to full access
   816  func (p *PermissionCtrl) populateInitAccountAccess(permissionsSession *pbind.PermInterfaceSession) error {
   817  	for _, a := range p.permConfig.Accounts {
   818  		_, er := permissionsSession.AddAdminAccount(a)
   819  		if er != nil {
   820  			log.Warn("Error adding permission initial account list", "err", er, "account", a)
   821  			return er
   822  		}
   823  		types.AcctInfoMap.UpsertAccount(p.permConfig.NwAdminOrg, p.permConfig.NwAdminRole, a, true, 2)
   824  	}
   825  	return nil
   826  }
   827  
   828  // updates network boot status to true
   829  func (p *PermissionCtrl) updateNetworkStatus(permissionsSession *pbind.PermInterfaceSession) error {
   830  	_, err := permissionsSession.UpdateNetworkBootStatus()
   831  	if err != nil {
   832  		log.Warn("Failed to udpate network boot status ", "err", err)
   833  		return err
   834  	}
   835  	return nil
   836  }
   837  
   838  // monitors role management related events and updated cache
   839  func (p *PermissionCtrl) manageRolePermissions() error {
   840  	chRoleCreated := make(chan *pbind.RoleManagerRoleCreated, 1)
   841  	chRoleRevoked := make(chan *pbind.RoleManagerRoleRevoked, 1)
   842  
   843  	opts := &bind.WatchOpts{}
   844  	var blockNumber uint64 = 1
   845  	opts.Start = &blockNumber
   846  
   847  	if _, err := p.permRole.RoleManagerFilterer.WatchRoleCreated(opts, chRoleCreated); err != nil {
   848  		return fmt.Errorf("failed WatchRoleCreated: %v", err)
   849  	}
   850  
   851  	if _, err := p.permRole.RoleManagerFilterer.WatchRoleRevoked(opts, chRoleRevoked); err != nil {
   852  		return fmt.Errorf("failed WatchRoleRemoved: %v", err)
   853  	}
   854  
   855  	go func() {
   856  		stopChan, stopSubscription := p.subscribeStopEvent()
   857  		defer stopSubscription.Unsubscribe()
   858  		for {
   859  			select {
   860  			case evtRoleCreated := <-chRoleCreated:
   861  				types.RoleInfoMap.UpsertRole(evtRoleCreated.OrgId, evtRoleCreated.RoleId, evtRoleCreated.IsVoter, evtRoleCreated.IsAdmin, types.AccessType(int(evtRoleCreated.BaseAccess.Uint64())), true)
   862  
   863  			case evtRoleRevoked := <-chRoleRevoked:
   864  				if r, _ := types.RoleInfoMap.GetRole(evtRoleRevoked.OrgId, evtRoleRevoked.RoleId); r != nil {
   865  					types.RoleInfoMap.UpsertRole(evtRoleRevoked.OrgId, evtRoleRevoked.RoleId, r.IsVoter, r.IsAdmin, r.Access, false)
   866  				} else {
   867  					log.Error("Revoke role - cache is missing role", "org", evtRoleRevoked.OrgId, "role", evtRoleRevoked.RoleId)
   868  				}
   869  			case <-stopChan:
   870  				log.Info("quit role contract watch")
   871  				return
   872  			}
   873  		}
   874  	}()
   875  	return nil
   876  }
   877  
   878  // getter to get an account record from the contract
   879  func (p *PermissionCtrl) populateAccountToCache(acctId common.Address) (*types.AccountInfo, error) {
   880  	permAcctInterface := &pbind.AcctManagerSession{
   881  		Contract: p.permAcct,
   882  		CallOpts: bind.CallOpts{
   883  			Pending: true,
   884  		},
   885  	}
   886  	account, orgId, roleId, status, isAdmin, err := permAcctInterface.GetAccountDetails(acctId)
   887  	if err != nil {
   888  		return nil, err
   889  	}
   890  
   891  	if status.Int64() == 0 {
   892  		return nil, types.ErrAccountNotThere
   893  	}
   894  	return &types.AccountInfo{AcctId: account, OrgId: orgId, RoleId: roleId, Status: types.AcctStatus(status.Int64()), IsOrgAdmin: isAdmin}, nil
   895  }
   896  
   897  // getter to get a org record from the contract
   898  func (p *PermissionCtrl) populateOrgToCache(orgId string) (*types.OrgInfo, error) {
   899  	permOrgInterface := &pbind.OrgManagerSession{
   900  		Contract: p.permOrg,
   901  		CallOpts: bind.CallOpts{
   902  			Pending: true,
   903  		},
   904  	}
   905  	org, parentOrgId, ultimateParentId, orgLevel, orgStatus, err := permOrgInterface.GetOrgDetails(orgId)
   906  	if err != nil {
   907  		return nil, err
   908  	}
   909  	if orgStatus.Int64() == 0 {
   910  		return nil, types.ErrOrgDoesNotExists
   911  	}
   912  	orgInfo := types.OrgInfo{OrgId: org, ParentOrgId: parentOrgId, UltimateParent: ultimateParentId, Status: types.OrgStatus(orgStatus.Int64()), Level: orgLevel}
   913  	// now need to build the list of sub orgs for this org
   914  	subOrgIndexes, err := permOrgInterface.GetSubOrgIndexes(orgId)
   915  	if err != nil {
   916  		return nil, err
   917  	}
   918  
   919  	if len(subOrgIndexes) == 0 {
   920  		return &orgInfo, nil
   921  	}
   922  
   923  	// range through the sub org indexes and get the org ids to populate the suborg list
   924  	for _, s := range subOrgIndexes {
   925  		subOrgId, _, _, _, _, err := permOrgInterface.GetOrgInfo(s)
   926  
   927  		if err != nil {
   928  			return nil, err
   929  		}
   930  		orgInfo.SubOrgList = append(orgInfo.SubOrgList, orgId+"."+subOrgId)
   931  
   932  	}
   933  	return &orgInfo, nil
   934  }
   935  
   936  // getter to get a role record from the contract
   937  func (p *PermissionCtrl) populateRoleToCache(roleKey *types.RoleKey) (*types.RoleInfo, error) {
   938  	permRoleInterface := &pbind.RoleManagerSession{
   939  		Contract: p.permRole,
   940  		CallOpts: bind.CallOpts{
   941  			Pending: true,
   942  		},
   943  	}
   944  	roleDetails, err := permRoleInterface.GetRoleDetails(roleKey.RoleId, roleKey.OrgId)
   945  
   946  	if err != nil {
   947  		return nil, err
   948  	}
   949  
   950  	if roleDetails.OrgId == "" {
   951  		return nil, types.ErrInvalidRole
   952  	}
   953  	return &types.RoleInfo{OrgId: roleDetails.OrgId, RoleId: roleDetails.RoleId, IsVoter: roleDetails.Voter, IsAdmin: roleDetails.Admin, Access: types.AccessType(roleDetails.AccessType.Int64()), Active: roleDetails.Active}, nil
   954  }
   955  
   956  // getter to get a role record from the contract
   957  func (p *PermissionCtrl) populateNodeCache(url string) (*types.NodeInfo, error) {
   958  	permNodeInterface := &pbind.NodeManagerSession{
   959  		Contract: p.permNode,
   960  		CallOpts: bind.CallOpts{
   961  			Pending: true,
   962  		},
   963  	}
   964  	nodeDetails, err := permNodeInterface.GetNodeDetails(url)
   965  	if err != nil {
   966  		return nil, err
   967  	}
   968  
   969  	if nodeDetails.NodeStatus.Int64() == 0 {
   970  		return nil, types.ErrNodeDoesNotExists
   971  	}
   972  	return &types.NodeInfo{OrgId: nodeDetails.OrgId, Url: nodeDetails.EnodeId, Status: types.NodeStatus(nodeDetails.NodeStatus.Int64())}, nil
   973  }
   974  
   975  // getter to get a node record from the contract
   976  func (p *PermissionCtrl) populateNodeCacheAndValidate(hexNodeId, ultimateParentId string) bool {
   977  	permNodeInterface := &pbind.NodeManagerSession{
   978  		Contract: p.permNode,
   979  		CallOpts: bind.CallOpts{
   980  			Pending: true,
   981  		},
   982  	}
   983  	txnAllowed := false
   984  	passedEnode, _ := enode.ParseV4(hexNodeId)
   985  	if numberOfNodes, err := permNodeInterface.GetNumberOfNodes(); err == nil {
   986  		numNodes := numberOfNodes.Uint64()
   987  		for k := uint64(0); k < numNodes; k++ {
   988  			if nodeStruct, err := permNodeInterface.GetNodeDetailsFromIndex(big.NewInt(int64(k))); err == nil {
   989  				if orgRec, err := types.OrgInfoMap.GetOrg(nodeStruct.OrgId); err != nil {
   990  					if orgRec.UltimateParent == ultimateParentId {
   991  						recEnode, _ := enode.ParseV4(nodeStruct.EnodeId)
   992  						if recEnode.ID() == passedEnode.ID() {
   993  							txnAllowed = true
   994  							types.NodeInfoMap.UpsertNode(nodeStruct.OrgId, nodeStruct.EnodeId, types.NodeStatus(int(nodeStruct.NodeStatus.Int64())))
   995  						}
   996  					}
   997  				}
   998  			}
   999  		}
  1000  	}
  1001  	return txnAllowed
  1002  }