diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 440212719..822b586d4 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -391,10 +391,11 @@ func startQuorumPermissionService(ctx *cli.Context, stack *node.Node) { log.Error("loading of permission-config.json failed", "error", err) return } + } else { + // permissions not enabled hence none of the services will be available. + return } - log.Info("AJ-perm-config loaded", "config", permissionConfig) - // start the permissions management service pc, err := permission.NewQuorumPermissionCtrl(stack, ctx.GlobalBool(utils.EnableNodePermissionFlag.Name), ctx.GlobalBool(utils.RaftModeFlag.Name), &permissionConfig) if err != nil { @@ -409,7 +410,7 @@ func startQuorumPermissionService(ctx *cli.Context, stack *node.Node) { rpcClient, err := stack.Attach() /**/ if err != nil { - utils.Fatalf("Unable to connnect to the node: %v", err) + utils.Fatalf("Unable to connect to the node: %v", err) } stateReader := ethclient.NewClient(rpcClient) diff --git a/controls/permission/permission.go b/controls/permission/permission.go index 838c81373..1bdbacb73 100644 --- a/controls/permission/permission.go +++ b/controls/permission/permission.go @@ -33,6 +33,23 @@ const ( NodeDelete ) +// permission config for bootstrapping +type PermissionLocalConfig struct { + UpgrdAddress string + InterfAddress string + ImplAddress string + NodeAddress string + AccountAddress string + RoleAddress string + VoterAddress string + OrgAddress string + NwAdminOrg string + NwAdminRole string + OrgAdminRole string + + Accounts []string //initial list of account that need full access +} + type PermissionCtrl struct { node *node.Node ethClnt *ethclient.Client @@ -50,6 +67,31 @@ type PermissionCtrl struct { permConfig *types.PermissionConfig } +// 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 { + var permConfig types.PermissionConfig + permConfig.UpgrdAddress = common.HexToAddress(config.UpgrdAddress) + permConfig.InterfAddress = common.HexToAddress(config.InterfAddress) + permConfig.ImplAddress = common.HexToAddress(config.ImplAddress) + permConfig.OrgAddress = common.HexToAddress(config.OrgAddress) + permConfig.RoleAddress = common.HexToAddress(config.RoleAddress) + permConfig.NodeAddress = common.HexToAddress(config.NodeAddress) + permConfig.AccountAddress = common.HexToAddress(config.AccountAddress) + permConfig.VoterAddress = common.HexToAddress(config.VoterAddress) + + permConfig.NwAdminOrg = config.NwAdminOrg + permConfig.NwAdminRole = config.NwAdminOrg + permConfig.OrgAdminRole = config.OrgAdminRole + + // populate the account list as passed in config + for _, val := range config.Accounts { + permConfig.Accounts = append(permConfig.Accounts, common.HexToAddress(val)) + } + + return permConfig +} + func ParsePermissionConifg(dir string) (types.PermissionConfig, error) { fileName := "permission-config.json" fullPath := filepath.Join(dir, fileName) @@ -64,12 +106,15 @@ func ParsePermissionConifg(dir string) (types.PermissionConfig, error) { log.Error("error reading permission-config.json file", err) return types.PermissionConfig{}, err } - var permConfig types.PermissionConfig - err = json.Unmarshal(blob, &permConfig) + var permlocConfig PermissionLocalConfig + err = json.Unmarshal(blob, &permlocConfig) if err != nil { log.Error("error unmarshalling permission-config.json file", err) return types.PermissionConfig{}, err } + + permConfig := populateConfig(permlocConfig) + return permConfig, nil } @@ -83,62 +128,66 @@ func NewQuorumPermissionCtrl(stack *node.Node, permissionedMode, isRaft bool, pc } if pconfig.IsEmpty() && permissionedMode { - utils.Fatalf("permission-config.json is missing contract address") + log.Error("permission-config.json is missing contract address") + return nil, errors.New("permission-config.json is missing contract address") } - - if !permissionedMode { - return &PermissionCtrl{stack, stateReader, e, isRaft, permissionedMode, stack.GetNodeKey(), stack.DataDir(), nil, nil, nil, nil, nil, nil, pconfig}, nil - } - pu, err := pbind.NewPermUpgr(common.HexToAddress(pconfig.UpgrdAddress), stateReader) + pu, err := pbind.NewPermUpgr(pconfig.UpgrdAddress, stateReader) if err != nil { log.Error("Permissions not enabled for the network", "err", err) return nil, err } // check if permissioning contract is there at address. If not return from here - pm, err := pbind.NewPermInterface(common.HexToAddress(pconfig.InterfAddress), stateReader) + pm, err := pbind.NewPermInterface(pconfig.InterfAddress, stateReader) if err != nil { log.Error("Permissions not enabled for the network", "err", err) return nil, err } - pmAcct, err := pbind.NewAcctManager(common.HexToAddress(pconfig.AccountAddress), stateReader) + pmAcct, err := pbind.NewAcctManager(pconfig.AccountAddress, stateReader) if err != nil { log.Error("Permissions not enabled for the network", "err", err) return nil, err } - pmNode, err := pbind.NewNodeManager(common.HexToAddress(pconfig.NodeAddress), stateReader) + pmNode, err := pbind.NewNodeManager(pconfig.NodeAddress, stateReader) if err != nil { log.Error("Permissions not enabled for the network", "err", err) return nil, err } - pmRole, err := pbind.NewRoleManager(common.HexToAddress(pconfig.RoleAddress), stateReader) + pmRole, err := pbind.NewRoleManager(pconfig.RoleAddress, stateReader) if err != nil { log.Error("Permissions not enabled for the network", "err", err) return nil, err } - pmOrg, err := pbind.NewOrgManager(common.HexToAddress(pconfig.OrgAddress), stateReader) + pmOrg, err := pbind.NewOrgManager(pconfig.OrgAddress, stateReader) if err != nil { log.Error("Permissions not enabled for the network", "err", err) return nil, err } - - log.Info("AJ-permission contracts initialized") return &PermissionCtrl{stack, stateReader, e, isRaft, permissionedMode, stack.GetNodeKey(), stack.DataDir(), pu, pm, pmNode, pmAcct, pmRole, pmOrg, pconfig}, nil } -// Starts the node permissioning and account access control monitoring +// Starts the node permissioning and event monitoring for permissions +// smart contracts func (p *PermissionCtrl) Start() error { // Permissions initialization if err := p.init(); err != nil { log.Error("Permissions init failed", "err", err) return err } + + // monitor org management related events p.manageOrgPermissions() + + // monitor org level node management events p.manageNodePermissions() + + // monitor org level role management events p.manageRolePermissions() + + // monitor org level account management events p.manageAccountPermissions() return nil @@ -146,9 +195,6 @@ func (p *PermissionCtrl) Start() error { // Sets the initial values for the network func (p *PermissionCtrl) init() error { - if !p.permissionedMode { - return nil - } // populate the initial list of permissioned nodes and account accesses if err := p.populateInitPermissions(); err != nil { return err @@ -544,10 +590,8 @@ func (p *PermissionCtrl) formatEnodeId(enodeId, ipAddrPort, discPort, raftPort s return newEnodeId } -// Thus function checks if the its the initial network boot up and if yes -// populates the initial network enode details from static-nodes.json into -// smart contracts. Sets the accounts access to full access for the initial -// initial list of accounts as given in genesis.json file +// Thus function checks if the its the initial network boot up status and if no +// populates permissioning model with details from permission-config.json func (p *PermissionCtrl) populateInitPermissions() error { auth := bind.NewKeyedTransactor(p.key) permInterfSession := &pbind.PermInterfaceSession{ @@ -566,33 +610,16 @@ func (p *PermissionCtrl) populateInitPermissions() error { networkInitialized, err := permInterfSession.GetNetworkBootStatus() if err != nil { // handle the scenario of no contract code. - if err.Error() == "no contract code at given address" { - return err - } log.Warn("Failed to retrieve network boot status ", "err", err) return err } - if networkInitialized && !p.permissionedMode { - // Network is initialized with permissions and node is joining in a non-permissioned - // option. stop the node from coming up - utils.Fatalf("Joining a permissioned network in non-permissioned mode is not permitted. Bring up geth with --permissioned.") - } - - if !p.permissionedMode { - log.Info("Node started in non-permissioned mode") - return errors.New("Node started in non-permissioned mode") - } - if !networkInitialized { if err := p.bootupNetwork(permInterfSession); err != nil { return err } - log.Info("AJ-network boot completed") } else { - log.Info("AJ-network already booted") //populate orgs, nodes, roles and accounts from contract - p.populateOrgsFromContract(auth) p.populateNodesFromContract(auth) @@ -600,7 +627,6 @@ func (p *PermissionCtrl) populateInitPermissions() error { p.populateRolesFromContract(auth) p.populateAccountsFromContract(auth) - log.Info("AJ-all data loaded from contract") } ShowCacheData() @@ -608,21 +634,17 @@ func (p *PermissionCtrl) populateInitPermissions() error { return nil } +// initialize the permissions model and populate initial values func (p *PermissionCtrl) bootupNetwork(permInterfSession *pbind.PermInterfaceSession) error { - // Ensure that there is at least one account given as a part of genesis.json - // which will have full access. If not throw a fatal error - // Do not want a network with no access - log.Info("AJ-network not initialized") - permInterfSession.TransactOpts.Nonce = new(big.Int).SetUint64(p.eth.TxPool().Nonce(permInterfSession.TransactOpts.From)) if _, err := permInterfSession.SetPolicy(p.permConfig.NwAdminOrg, p.permConfig.NwAdminRole, p.permConfig.OrgAdminRole); err != nil { - log.Error("AJ-permIntr.setPolicy failed", "err", err) + log.Error("bootupNetwork SetPolicy failed", "err", err) return err } log.Info("AJ-permInter setPolicy done") permInterfSession.TransactOpts.Nonce = new(big.Int).SetUint64(p.eth.TxPool().Nonce(permInterfSession.TransactOpts.From)) - if _, err := permInterfSession.Init(common.HexToAddress(p.permConfig.OrgAddress), common.HexToAddress(p.permConfig.RoleAddress), common.HexToAddress(p.permConfig.AccountAddress), common.HexToAddress(p.permConfig.VoterAddress), common.HexToAddress(p.permConfig.NodeAddress)); err != nil { - log.Error("AJ-permIntr.init failed", "err", err) + if _, err := permInterfSession.Init(p.permConfig.OrgAddress, p.permConfig.RoleAddress, p.permConfig.AccountAddress, p.permConfig.VoterAddress, p.permConfig.NodeAddress); err != nil { + log.Error("bootupNetwork init failed", "err", err) return err } log.Info("AJ-permInter init done") @@ -828,11 +850,11 @@ func (p *PermissionCtrl) populateInitAccountAccess(permissionsSession *pbind.Per log.Info("AJ-adding account ", "A", a) nonce := p.eth.TxPool().Nonce(permissionsSession.TransactOpts.From) permissionsSession.TransactOpts.Nonce = new(big.Int).SetUint64(nonce) - _, er := permissionsSession.AddAdminAccounts(common.HexToAddress(a)) + _, er := permissionsSession.AddAdminAccounts(a) if er != nil { utils.Fatalf("error adding permission initial account list account: %s, error:%v", a, er) } - types.AcctInfoMap.UpsertAccount(p.permConfig.NwAdminOrg, p.permConfig.NwAdminRole, common.HexToAddress(a), true, 2) + types.AcctInfoMap.UpsertAccount(p.permConfig.NwAdminOrg, p.permConfig.NwAdminRole, a, true, 2) } log.Info("AJ-add initial account list ...done") } diff --git a/core/types/permissions_cache.go b/core/types/permissions_cache.go index f619f1173..44c6edca3 100644 --- a/core/types/permissions_cache.go +++ b/core/types/permissions_cache.go @@ -78,19 +78,19 @@ type OrgStruct struct { // permission config for bootstrapping type PermissionConfig struct { - UpgrdAddress string - InterfAddress string - ImplAddress string - NodeAddress string - AccountAddress string - RoleAddress string - VoterAddress string - OrgAddress string + UpgrdAddress common.Address + InterfAddress common.Address + ImplAddress common.Address + NodeAddress common.Address + AccountAddress common.Address + RoleAddress common.Address + VoterAddress common.Address + OrgAddress common.Address NwAdminOrg string NwAdminRole string OrgAdminRole string - Accounts []string //initial list of account that need full access + Accounts []common.Address //initial list of account that need full access } type OrgKey struct { @@ -169,7 +169,7 @@ var AcctInfoMap = NewAcctCache() var orgKeyLock sync.Mutex func (pc *PermissionConfig) IsEmpty() bool { - return pc.InterfAddress == "" || pc.NodeAddress == "" || pc.AccountAddress == "" + return pc.InterfAddress == common.HexToAddress("0x0") || pc.NodeAddress == common.HexToAddress("0x0") || pc.AccountAddress == common.HexToAddress("0x0") } // sets default access to ReadOnly