additional changes

This commit is contained in:
vsmk98 2018-11-13 16:15:28 +08:00
parent e3112a05ac
commit 3a3850af2c
8 changed files with 166 additions and 69 deletions

View File

@ -361,16 +361,15 @@ func startNode(ctx *cli.Context, stack *node.Node) {
}
func startQuorumPermissionService(ctx *cli.Context, stack *node.Node) {
if permEnabled := ctx.GlobalBool(utils.EnableNodePermissionFlag.Name); permEnabled {
// start the permissions management service
pc, err := permission.NewQuorumPermissionCtrl(stack, ctx.GlobalBool(utils.RaftModeFlag.Name))
if err != nil {
utils.Fatalf("Failed to start Quorum Permission contract service: %v", err)
}
pc.Start()
log.Info("Node Permission service started")
// start the permissions management service
pc, err := permission.NewQuorumPermissionCtrl(stack, ctx.GlobalBool(utils.EnableNodePermissionFlag.Name),ctx.GlobalBool(utils.RaftModeFlag.Name))
if err != nil {
utils.Fatalf("Failed to start Quorum Permission contract service: %v", err)
}
err = pc.Start()
log.Info("Node Permission service started")
// Changes for managing org level cluster keys for privateFor txns
kc, err := cluster.NewOrgKeyCtrl(stack)
if err != nil {

File diff suppressed because one or more lines are too long

View File

@ -136,6 +136,17 @@ contract Permissions {
{
return voteStatus[getNodeIndex(_enodeId)][_voter];
}
function isVoter(address _acctid) external view returns (bool)
{
bool flag = false;
for (uint i=0; i<voterAcctList.length; i++){
if (voterAcctList[i] == _acctid){
flag = true;
break;
}
}
return flag;
}
// for potential external use
// Get enode id by index
function getEnodeId(uint _index) external view returns (string)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -4,6 +4,7 @@ import (
"crypto/ecdsa"
"encoding/json"
"fmt"
"errors"
"io/ioutil"
"math/big"
"os"
@ -41,13 +42,14 @@ type PermissionCtrl struct {
ethClnt *ethclient.Client
eth *eth.Ethereum
isRaft bool
permissionedMode bool
key *ecdsa.PrivateKey
dataDir string
pm *pbind.Permissions
}
// Creates the controls structure for permissions
func NewQuorumPermissionCtrl(stack *node.Node, isRaft bool) (*PermissionCtrl, error) {
func NewQuorumPermissionCtrl(stack *node.Node, permissionedMode, isRaft bool) (*PermissionCtrl, error) {
if types.AcctMapErr != nil {
log.Error("error initializing account access map", "err", types.AcctMapErr)
return nil, types.AcctMapErr
@ -66,17 +68,19 @@ func NewQuorumPermissionCtrl(stack *node.Node, isRaft bool) (*PermissionCtrl, er
return nil, err
}
return &PermissionCtrl{stack, stateReader, e, isRaft, stack.GetNodeKey(), stack.DataDir(), pm}, nil
return &PermissionCtrl{stack, stateReader, e, isRaft, permissionedMode, stack.GetNodeKey(), stack.DataDir(), pm}, nil
}
// Starts the node permissioning and account access control monitoring
func (p *PermissionCtrl) Start() error {
log.Info("SMK-Inside Start @ 77")
// At node level update QuorumPermissions to indicate new permissioning is in use
server := p.node.Server()
server.QuorumPermissions = true
// Permissions initialization
if err := p.init(); err != nil {
log.Info("SMK-Inside init error @ 84")
log.Error("Permissions init failed : ", "err", err)
return err
}
@ -92,18 +96,22 @@ func (p *PermissionCtrl) Start() error {
// This functions updates the initial values for the network
func (p *PermissionCtrl) init() error {
log.Info("SMK-init @100")
// populate the initial list of permissioned nodes and account accesses
if err := p.populateInitPermission(); err != nil {
log.Info("SMK-init @103 error")
return err
}
// call populates the account permissions based on past history
if err := p.populateAcctPermissions(); err != nil {
log.Info("SMK-init @109 error")
return err
}
// call populates the node details from contract to KnownNodes
if err := p.populatePermissionedNodes(); err != nil {
log.Info("SMK-init @1115 error")
return err
}
@ -330,14 +338,18 @@ func (p *PermissionCtrl) populatePermissionedNodes() error {
// populates the nodes list from permissioned-nodes.json into the permissions
// smart contract
func (p *PermissionCtrl) populateAcctPermissions() error {
log.Info("SMK-populateAcctPermissions @336 ")
opts := &bind.FilterOpts{}
pastEvents, err := p.pm.PermissionsFilterer.FilterAccountAccessModified(opts)
log.Info("SMK-populateAcctPermissions @337 ", "err", err, "pastEvents", pastEvents)
if err == nil {
recExists := true
log.Info("SMK-populateAcctPermissions @340 ")
for recExists {
recExists = pastEvents.Next()
if recExists {
log.Info("SMK-populateAcctPermissions @344 ", "Account", pastEvents.Event.Address, "access",pastEvents.Event.Access)
types.AddAccountAccess(pastEvents.Event.Address, pastEvents.Event.Access)
}
}
@ -419,28 +431,46 @@ func (p *PermissionCtrl) populateInitPermission() error {
GasPrice: big.NewInt(0),
},
}
log.Info("SMK-populateInitPermission @429")
tx, err := permissionsSession.GetNetworkBootStatus()
if err != nil {
log.Info("SMK-populateInitPermission @433", "err", err)
log.Warn("Failed to udpate network boot status ", "err", err)
}
if tx && !p.permissionedMode {
// Network is initialized with permissions and node is joining in a non-permissioned
// option. stop the node from coming up
types.SetDefaultAccess()
log.Info("SMK-populateInitPermission @447")
}
if !p.permissionedMode{
return errors.New("Node started in non-permissioned mode")
log.Info("SMK-populateInitPermission @452")
}
if tx != true {
// populate initial account access to full access
log.Info("SMK-populateInitPermission @456")
err = p.populateInitAccountAccess(permissionsSession)
if err != nil {
log.Info("SMK-populateInitPermission @459 error")
return err
}
// populate the initial node list from static-nodes.json
err := p.populateStaticNodesToContract(permissionsSession)
if err != nil {
log.Info("SMK-populateInitPermission @466 error")
return err
}
// update network status to boot completed
log.Info("SMK-populateInitPermission @466 calling updateNetworkStatus")
err = p.updateNetworkStatus(permissionsSession)
if err != nil {
log.Info("SMK-populateInitPermission @474 updateNetworkStatus error")
return err
}
}
@ -482,6 +512,7 @@ func (p *PermissionCtrl) populateInitAccountAccess(permissionsSession *pbind.Per
for _, account := range wallet.Accounts() {
nonce := p.eth.TxPool().Nonce(permissionsSession.TransactOpts.From)
permissionsSession.TransactOpts.Nonce = new(big.Int).SetUint64(nonce)
log.Info("SMK-populateInitPermission adding @485", "account", account.Address)
_, err := permissionsSession.UpdateAccountAccess(account.Address, uint8(types.FullAccess))
if err != nil {

View File

@ -169,28 +169,32 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) bool {
switch action {
case AddVoter:
tx, err = ps.AddVoter(args.voter)
case RemoveVoter:
tx, err = ps.RemoveVoter(args.voter)
case ProposeNode:
if checkVoterExists(ps){
node, err = discover.ParseNode(args.nodeId)
if err != nil {
log.Error("invalid node id: %v", err)
return false
}
enodeID := node.ID.String()
ipAddr := node.IP.String()
port := fmt.Sprintf("%v", node.TCP)
discPort := fmt.Sprintf("%v", node.UDP)
raftPort := fmt.Sprintf("%v", node.RaftPort)
ipAddrPort := ipAddr + ":" + port
tx, err = ps.ProposeNode(enodeID, ipAddrPort, discPort, raftPort)
} else {
if !checkVoterExists(ps){
return false
}
node, err = discover.ParseNode(args.nodeId)
if err != nil {
log.Error("invalid node id: %v", err)
return false
}
enodeID := node.ID.String()
ipAddr := node.IP.String()
port := fmt.Sprintf("%v", node.TCP)
discPort := fmt.Sprintf("%v", node.UDP)
raftPort := fmt.Sprintf("%v", node.RaftPort)
ipAddrPort := ipAddr + ":" + port
tx, err = ps.ProposeNode(enodeID, ipAddrPort, discPort, raftPort)
case ApproveNode:
if !checkIsVoter(ps, args.txa.From){
return false
}
node, err = discover.ParseNode(args.nodeId)
if err != nil {
log.Error("invalid node id: %v", err)
@ -198,19 +202,23 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) bool {
}
enodeID := node.ID.String()
tx, err = ps.ApproveNode(enodeID)
case ProposeNodeDeactivation:
if checkVoterExists(ps){
node, err = discover.ParseNode(args.nodeId)
if err != nil {
log.Error("invalid node id: %v", err)
return false
}
enodeID := node.ID.String()
tx, err = ps.ProposeDeactivation(enodeID)
} else {
if !checkVoterExists(ps){
return false
}
node, err = discover.ParseNode(args.nodeId)
if err != nil {
log.Error("invalid node id: %v", err)
return false
}
enodeID := node.ID.String()
tx, err = ps.ProposeDeactivation(enodeID)
case ApproveNodeDeactivation:
if !checkIsVoter(ps, args.txa.From){
return false
}
node, err = discover.ParseNode(args.nodeId)
if err != nil {
log.Error("invalid node id: %v", err)
@ -218,19 +226,23 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) bool {
}
enodeID := node.ID.String()
tx, err = ps.DeactivateNode(enodeID)
case ProposeNodeActivation:
if checkVoterExists(ps){
node, err = discover.ParseNode(args.nodeId)
if err != nil {
log.Error("invalid node id: %v", err)
return false
}
enodeID := node.ID.String()
tx, err = ps.ProposeNodeActivation(enodeID)
} else {
if !checkVoterExists(ps){
return false
}
node, err = discover.ParseNode(args.nodeId)
if err != nil {
log.Error("invalid node id: %v", err)
return false
}
enodeID := node.ID.String()
tx, err = ps.ProposeNodeActivation(enodeID)
case ApproveNodeActivation:
if !checkIsVoter(ps, args.txa.From){
return false
}
node, err = discover.ParseNode(args.nodeId)
if err != nil {
log.Error("invalid node id: %v", err)
@ -238,25 +250,29 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) bool {
}
enodeID := node.ID.String()
tx, err = ps.ActivateNode(enodeID)
case ProposeNodeBlacklisting:
if checkVoterExists(ps){
node, err = discover.ParseNode(args.nodeId)
if err != nil {
log.Error("invalid node id: %v", err)
return false
}
enodeID := node.ID.String()
ipAddr := node.IP.String()
port := fmt.Sprintf("%v", node.TCP)
discPort := fmt.Sprintf("%v", node.UDP)
raftPort := fmt.Sprintf("%v", node.RaftPort)
ipAddrPort := ipAddr + ":" + port
tx, err = ps.ProposeNodeBlacklisting(enodeID, ipAddrPort, discPort, raftPort)
} else {
case ProposeNodeBlacklisting:
if !checkVoterExists(ps){
return false
}
node, err = discover.ParseNode(args.nodeId)
if err != nil {
log.Error("invalid node id: %v", err)
return false
}
enodeID := node.ID.String()
ipAddr := node.IP.String()
port := fmt.Sprintf("%v", node.TCP)
discPort := fmt.Sprintf("%v", node.UDP)
raftPort := fmt.Sprintf("%v", node.RaftPort)
ipAddrPort := ipAddr + ":" + port
tx, err = ps.ProposeNodeBlacklisting(enodeID, ipAddrPort, discPort, raftPort)
case ApproveNodeBlacklisting:
if !checkIsVoter(ps, args.txa.From){
return false
}
node, err = discover.ParseNode(args.nodeId)
if err != nil {
log.Error("invalid node id: %v", err)
@ -264,6 +280,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) bool {
}
enodeID := node.ID.String()
tx, err = ps.BlacklistNode(enodeID)
case SetAccountAccess:
var access uint64
access, err = strconv.ParseUint(args.accessType, 10, 8)
@ -271,8 +288,8 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) bool {
return false
}
tx, err = ps.UpdateAccountAccess(args.acctId, uint8(access))
}
if err != nil {
log.Error("Failed to execute permission action", "action", action, "err", err)
return false
@ -323,6 +340,14 @@ func checkVoterExists(ps *pbind.PermissionsSession) bool {
return false
}
// checks if any accounts is a valid voter to approve the action
func checkIsVoter(ps *pbind.PermissionsSession, acctId common.Address) bool {
tx, err := ps.IsVoter(acctId)
if err == nil && tx {
return true
}
return false
}
// newPermSession creates a new permission contract session
func (s *PermissionAPI) newPermSession(w accounts.Wallet, txa ethapi.SendTxArgs) *pbind.PermissionsSession {
frmAcct, transactOpts, gasLimit, gasPrice, nonce := s.getTxParams(txa, w)

View File

@ -22,11 +22,15 @@ type OrgStruct struct {
OrgId string
Keys []string
}
var DefaultAccess = FullAccess
var AcctMap, AcctMapErr = lru.NewARC(100)
var OrgKeyMap, OrgKeyMapErr = lru.NewARC(100)
func SetDefaultAccess() {
DefaultAccess = ReadOnly
}
func AddAccountAccess(acctId common.Address, access uint8) {
AcctMap.Add(acctId, &PermStruct{AcctId: acctId, AcctAccess: AccessType(access)})
}
@ -38,11 +42,12 @@ func GetAcctAccess(acctId common.Address) AccessType {
return vo.AcctAccess
}
}
if AcctMap.Len() == 0 {
return FullAccess
} else {
return ReadOnly
}
return DefaultAccess
// if AcctMap.Len() == 0 {
// return FullAccess
// } else {
// return ReadOnly
// }
}
func AddOrgKey(orgId string, key string) {