Improve cache implementation and error handling for permissions (#961)

This commit is contained in:
Sai V 2020-06-03 08:14:50 +08:00 committed by GitHub
parent dcab518e50
commit d205bdbda7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 977 additions and 531 deletions

View File

@ -23,15 +23,8 @@ echo "---> building geth done"
echo "---> cloning quorum-cloud and quorum-acceptance-tests ..."
git clone https://github.com/jpmorganchase/quorum-acceptance-tests.git ${TRAVIS_HOME}/quorum-acceptance-tests
# use quorum-geth-upgrade-1.9.7 branch
cd ${TRAVIS_HOME}/quorum-acceptance-tests
git checkout quorum-geth-upgrade-1.9.7
cd -
git clone https://github.com/jpmorganchase/quorum-cloud.git ${TRAVIS_HOME}/quorum-cloud
# use quorum-geth-upgrade-1.9.7 branch
cd ${TRAVIS_HOME}/quorum-cloud
git checkout quorum-geth-upgrade-1.9.7
cd -
echo "---> cloning done"
echo "---> getting tessera jar ..."

View File

@ -1,12 +1,12 @@
package types
import (
"errors"
"math/big"
"sync"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/p2p/enode"
lru "github.com/hashicorp/golang-lru"
)
@ -110,60 +110,38 @@ type PermissionConfig struct {
SubOrgBreadth *big.Int `json:"subOrgBreadth"`
}
type OrgKey struct {
OrgId string
}
type NodeKey struct {
OrgId string
Url string
}
type RoleKey struct {
OrgId string
RoleId string
}
type AccountKey struct {
AcctId common.Address
}
type OrgCache struct {
c *lru.Cache
mux sync.Mutex
}
type NodeCache struct {
c *lru.Cache
}
type RoleCache struct {
c *lru.Cache
}
type AcctCache struct {
c *lru.Cache
}
func NewOrgCache() *OrgCache {
c, _ := lru.New(defaultOrgMapLimit)
return &OrgCache{c, sync.Mutex{}}
}
func NewNodeCache() *NodeCache {
c, _ := lru.New(defaultNodeMapLimit)
return &NodeCache{c}
}
func NewRoleCache() *RoleCache {
c, _ := lru.New(defaultRoleMapLimit)
return &RoleCache{c}
}
func NewAcctCache() *AcctCache {
c, _ := lru.New(defaultAccountMapLimit)
return &AcctCache{c}
}
var (
ErrNotNetworkAdmin = errors.New("Operation can be performed by network admin only. Account not a network admin.")
ErrNotOrgAdmin = errors.New("Operation can be performed by org admin only. Account not a org admin.")
ErrNodePresent = errors.New("EnodeId already part of network.")
ErrInvalidNode = errors.New("Invalid enode id")
ErrInvalidAccount = errors.New("Invalid account id")
ErrOrgExists = errors.New("Org already exist")
ErrPendingApprovals = errors.New("Pending approvals for the organization. Approve first")
ErrNothingToApprove = errors.New("Nothing to approve")
ErrOpNotAllowed = errors.New("Operation not allowed")
ErrNodeOrgMismatch = errors.New("Enode id passed does not belong to the organization.")
ErrBlacklistedNode = errors.New("Blacklisted node. Operation not allowed")
ErrBlacklistedAccount = errors.New("Blacklisted account. Operation not allowed")
ErrAccountOrgAdmin = errors.New("Account already org admin for the org")
ErrOrgAdminExists = errors.New("Org admin exist for the org")
ErrAccountInUse = errors.New("Account already in use in another organization")
ErrRoleExists = errors.New("Role exist for the org")
ErrRoleActive = errors.New("Accounts linked to the role. Cannot be removed")
ErrAdminRoles = errors.New("Admin role cannot be removed")
ErrInvalidOrgName = errors.New("Org id cannot contain special characters")
ErrInvalidParentOrg = errors.New("Invalid parent org id")
ErrAccountNotThere = errors.New("Account does not exist")
ErrOrgNotOwner = errors.New("Account does not belong to this org")
ErrMaxDepth = errors.New("Max depth for sub orgs reached")
ErrMaxBreadth = errors.New("Max breadth for sub orgs reached")
ErrNodeDoesNotExists = errors.New("Node does not exist")
ErrOrgDoesNotExists = errors.New("Org does not exist")
ErrInactiveRole = errors.New("Role is already inactive")
ErrInvalidRole = errors.New("Invalid role")
ErrInvalidInput = errors.New("Invalid input")
ErrNotMasterOrg = errors.New("Org is not a master org")
)
var syncStarted = false
@ -172,15 +150,114 @@ var QIP714BlockReached = false
var networkAdminRole string
var orgAdminRole string
const defaultOrgMapLimit = 2000
const defaultRoleMapLimit = 2500
const defaultNodeMapLimit = 1000
const defaultAccountMapLimit = 6000
var (
OrgInfoMap *OrgCache
NodeInfoMap *NodeCache
RoleInfoMap *RoleCache
AcctInfoMap *AcctCache
)
var OrgInfoMap = NewOrgCache()
var NodeInfoMap = NewNodeCache()
var RoleInfoMap = NewRoleCache()
var AcctInfoMap = NewAcctCache()
type OrgKey struct {
OrgId string
}
type OrgCache struct {
c *lru.Cache
mux sync.Mutex
evicted bool
populateCacheFunc func(orgId string) (*OrgInfo, error)
}
func (o *OrgCache) PopulateCacheFunc(cf func(string) (*OrgInfo, error)) {
o.populateCacheFunc = cf
}
func NewOrgCache(cacheSize int) *OrgCache {
orgCache := OrgCache{evicted: false}
onEvictedFunc := func(k interface{}, v interface{}) {
orgCache.evicted = true
}
orgCache.c, _ = lru.NewWithEvict(cacheSize, onEvictedFunc)
return &orgCache
}
type RoleKey struct {
OrgId string
RoleId string
}
type RoleCache struct {
c *lru.Cache
evicted bool
populateCacheFunc func(*RoleKey) (*RoleInfo, error)
}
func (r *RoleCache) PopulateCacheFunc(cf func(*RoleKey) (*RoleInfo, error)) {
r.populateCacheFunc = cf
}
func NewRoleCache(cacheSize int) *RoleCache {
roleCache := RoleCache{evicted: false}
onEvictedFunc := func(k interface{}, v interface{}) {
roleCache.evicted = true
}
roleCache.c, _ = lru.NewWithEvict(cacheSize, onEvictedFunc)
return &roleCache
}
type NodeKey struct {
OrgId string
Url string
}
type NodeCache struct {
c *lru.Cache
evicted bool
populateCacheFunc func(string) (*NodeInfo, error)
populateAndValidateFunc func(string, string) bool
}
func (n *NodeCache) PopulateValidateFunc(cf func(string, string) bool) {
n.populateAndValidateFunc = cf
}
func (n *NodeCache) PopulateCacheFunc(cf func(string) (*NodeInfo, error)) {
n.populateCacheFunc = cf
}
func NewNodeCache(cacheSize int) *NodeCache {
nodeCache := NodeCache{evicted: false}
onEvictedFunc := func(k interface{}, v interface{}) {
nodeCache.evicted = true
}
nodeCache.c, _ = lru.NewWithEvict(cacheSize, onEvictedFunc)
return &nodeCache
}
type AccountKey struct {
AcctId common.Address
}
type AcctCache struct {
c *lru.Cache
evicted bool
populateCacheFunc func(account common.Address) (*AccountInfo, error)
}
func (a *AcctCache) PopulateCacheFunc(cf func(common.Address) (*AccountInfo, error)) {
a.populateCacheFunc = cf
}
func NewAcctCache(cacheSize int) *AcctCache {
acctCache := AcctCache{evicted: false}
onEvictedFunc := func(k interface{}, v interface{}) {
acctCache.evicted = true
}
acctCache.c, _ = lru.NewWithEvict(cacheSize, onEvictedFunc)
return &acctCache
}
func (pc *PermissionConfig) IsEmpty() bool {
return pc.InterfAddress == common.HexToAddress("0x0")
@ -233,6 +310,17 @@ func (o *OrgCache) UpsertOrg(orgId, parentOrg, ultimateParent string, level *big
o.c.Add(key, norg)
}
func (o *OrgCache) UpsertOrgWithSubOrgList(orgRec *OrgInfo) {
var key OrgKey
if orgRec.ParentOrgId == "" {
key = OrgKey{OrgId: orgRec.OrgId}
} else {
key = OrgKey{OrgId: orgRec.ParentOrgId + "." + orgRec.OrgId}
}
orgRec.FullOrgId = key.OrgId
o.c.Add(key, orgRec)
}
func containsKey(s []string, e string) bool {
for _, a := range s {
if a == e {
@ -242,14 +330,25 @@ func containsKey(s []string, e string) bool {
return false
}
func (o *OrgCache) GetOrg(orgId string) *OrgInfo {
defer o.mux.Unlock()
o.mux.Lock()
func (o *OrgCache) GetOrg(orgId string) (*OrgInfo, error) {
key := OrgKey{OrgId: orgId}
if ent, ok := o.c.Get(key); ok {
return ent.(*OrgInfo)
return ent.(*OrgInfo), nil
}
return nil
// check if the org cache is evicted. if yes we need
// fetch the record from the contract
if o.evicted {
// call cache population function to populate from contract
orgRec, err := o.populateCacheFunc(orgId)
if err != nil {
return nil, err
}
// insert the received record into cache
o.UpsertOrgWithSubOrgList(orgRec)
//return the record
return orgRec, nil
}
return nil, ErrOrgDoesNotExists
}
func (o *OrgCache) GetOrgList() []OrgInfo {
@ -267,15 +366,30 @@ func (n *NodeCache) UpsertNode(orgId string, url string, status NodeStatus) {
n.c.Add(key, &NodeInfo{orgId, url, status})
}
func (n *NodeCache) GetNodeByUrl(url string) *NodeInfo {
func (n *NodeCache) GetNodeByUrl(url string) (*NodeInfo, error) {
for _, k := range n.c.Keys() {
ent := k.(NodeKey)
if ent.Url == url {
v, _ := n.c.Get(ent)
return v.(*NodeInfo)
return v.(*NodeInfo), nil
}
}
return nil
// check if the node cache is evicted. if yes we need
// fetch the record from the contract
if n.evicted {
// call cache population function to populate from contract
nodeRec, err := n.populateCacheFunc(url)
if err != nil {
return nil, err
}
// insert the received record into cache
n.UpsertNode(nodeRec.OrgId, nodeRec.Url, nodeRec.Status)
//return the record
return nodeRec, err
}
return nil, ErrNodeDoesNotExists
}
func (n *NodeCache) GetNodeList() []NodeInfo {
@ -293,11 +407,25 @@ func (a *AcctCache) UpsertAccount(orgId string, role string, acct common.Address
a.c.Add(key, &AccountInfo{orgId, role, acct, orgAdmin, status})
}
func (a *AcctCache) GetAccount(acct common.Address) *AccountInfo {
func (a *AcctCache) GetAccount(acct common.Address) (*AccountInfo, error) {
if v, ok := a.c.Get(AccountKey{acct}); ok {
return v.(*AccountInfo)
return v.(*AccountInfo), nil
}
return nil
// check if the account cache is evicted. if yes we need
// fetch the record from the contract
if a.evicted {
// call function to populate cache with the record
acctRec, err := a.populateCacheFunc(acct)
// insert the received record into cache
if err != nil {
return nil, err
}
a.UpsertAccount(acctRec.OrgId, acctRec.RoleId, acctRec.AcctId, acctRec.IsOrgAdmin, acctRec.Status)
//return the record
return acctRec, nil
}
return nil, nil
}
func (a *AcctCache) GetAcctList() []AccountInfo {
@ -328,7 +456,12 @@ func (a *AcctCache) GetAcctListRole(orgId, roleId string) []AccountInfo {
v, _ := a.c.Get(k)
vp := v.(*AccountInfo)
if vp.RoleId == roleId && (vp.OrgId == orgId || OrgInfoMap.GetOrg(vp.OrgId).UltimateParent == orgId) {
orgRec, err := OrgInfoMap.GetOrg(vp.OrgId)
if err != nil {
return nil
}
if vp.RoleId == roleId && (vp.OrgId == orgId || (orgRec != nil && orgRec.UltimateParent == orgId)) {
alist = append(alist, *vp)
}
}
@ -341,12 +474,26 @@ func (r *RoleCache) UpsertRole(orgId string, role string, voter bool, admin bool
}
func (r *RoleCache) GetRole(orgId string, roleId string) *RoleInfo {
func (r *RoleCache) GetRole(orgId string, roleId string) (*RoleInfo, error) {
key := RoleKey{OrgId: orgId, RoleId: roleId}
if ent, ok := r.c.Get(key); ok {
return ent.(*RoleInfo)
return ent.(*RoleInfo), nil
}
return nil
// check if the role cache is evicted. if yes we need
// fetch the record from the contract
if r.evicted {
// call cache population function to populate from contract
roleRec, err := r.populateCacheFunc(&RoleKey{RoleId: roleId, OrgId: orgId})
if err != nil {
return nil, err
}
// insert the received record into cache
r.UpsertRole(roleRec.OrgId, roleRec.RoleId, roleRec.IsVoter, roleRec.IsAdmin, roleRec.Access, roleRec.Active)
//return the record
return roleRec, nil
}
return nil, ErrInvalidRole
}
func (r *RoleCache) GetRoleList() []RoleInfo {
@ -369,21 +516,23 @@ func GetAcctAccess(acctId common.Address) AccessType {
}
// check if the org status is fine to do the transaction
a := AcctInfoMap.GetAccount(acctId)
a, _ := AcctInfoMap.GetAccount(acctId)
if a != nil && a.Status == AcctActive {
// get the org details and ultimate org details. check org status
// if the org is not approved or pending suspension
o := OrgInfoMap.GetOrg(a.OrgId)
o, _ := OrgInfoMap.GetOrg(a.OrgId)
if o != nil && (o.Status == OrgApproved || o.Status == OrgPendingSuspension) {
u := OrgInfoMap.GetOrg(o.UltimateParent)
u, _ := OrgInfoMap.GetOrg(o.UltimateParent)
if u != nil && (u.Status == OrgApproved || u.Status == OrgPendingSuspension) {
if a.RoleId == networkAdminRole || a.RoleId == orgAdminRole {
return FullAccess
}
if r := RoleInfoMap.GetRole(a.OrgId, a.RoleId); r != nil && r.Active {
r, _ := RoleInfoMap.GetRole(a.OrgId, a.RoleId)
if r != nil && r.Active {
return r.Access
}
if r := RoleInfoMap.GetRole(o.UltimateParent, a.RoleId); r != nil && r.Active {
r, _ = RoleInfoMap.GetRole(o.UltimateParent, a.RoleId)
if r != nil && r.Active {
return r.Access
}
}
@ -392,6 +541,7 @@ func GetAcctAccess(acctId common.Address) AccessType {
return DefaultAccess
}
// validates if the account can transact from the current node
func ValidateNodeForTxn(hexnodeId string, from common.Address) bool {
if !QIP714BlockReached || hexnodeId == "" {
return true
@ -402,20 +552,32 @@ func ValidateNodeForTxn(hexnodeId string, from common.Address) bool {
return false
}
ac := AcctInfoMap.GetAccount(from)
ac, _ := AcctInfoMap.GetAccount(from)
if ac == nil {
return true
}
ultimateParent := OrgInfoMap.GetOrg(ac.OrgId).UltimateParent
acOrgRec, err := OrgInfoMap.GetOrg(ac.OrgId)
if err != nil {
return false
}
// scan through the node list and validate
for _, n := range NodeInfoMap.GetNodeList() {
if OrgInfoMap.GetOrg(n.OrgId).UltimateParent == ultimateParent {
orgRec, err := OrgInfoMap.GetOrg(n.OrgId)
if err != nil {
return false
}
if orgRec.UltimateParent == acOrgRec.UltimateParent {
recEnodeId, _ := enode.ParseV4(n.Url)
if recEnodeId.ID() == passedEnodeId.ID() {
if recEnodeId.ID() == passedEnodeId.ID() && n.Status == NodeApproved {
return true
}
}
}
if NodeInfoMap.evicted {
return NodeInfoMap.populateAndValidateFunc(hexnodeId, acOrgRec.UltimateParent)
}
return false
}

View File

@ -8,6 +8,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
testifyassert "github.com/stretchr/testify/assert"
)
@ -51,16 +52,20 @@ func TestSetDefaults(t *testing.T) {
func TestOrgCache_UpsertOrg(t *testing.T) {
assert := testifyassert.New(t)
OrgInfoMap = NewOrgCache(params.DEFAULT_ORGCACHE_SIZE)
//add a org and get the org details
OrgInfoMap.UpsertOrg(NETWORKADMIN, "", NETWORKADMIN, big.NewInt(1), OrgApproved)
orgInfo := OrgInfoMap.GetOrg(NETWORKADMIN)
orgInfo, err := OrgInfoMap.GetOrg(NETWORKADMIN)
assert.True(err == nil, "errors encountered")
assert.False(orgInfo == nil, fmt.Sprintf("Expected org details, got nil"))
assert.True(orgInfo.OrgId == NETWORKADMIN, fmt.Sprintf("Expected org id %v, got %v", NETWORKADMIN, orgInfo.OrgId))
// update org status to suspended
OrgInfoMap.UpsertOrg(NETWORKADMIN, "", NETWORKADMIN, big.NewInt(1), OrgSuspended)
orgInfo = OrgInfoMap.GetOrg(NETWORKADMIN)
orgInfo, err = OrgInfoMap.GetOrg(NETWORKADMIN)
assert.True(err == nil, "errors encountered")
assert.True(orgInfo.Status == OrgSuspended, fmt.Sprintf("Expected org status %v, got %v", OrgSuspended, orgInfo.Status))
@ -83,9 +88,13 @@ func TestOrgCache_UpsertOrg(t *testing.T) {
func TestNodeCache_UpsertNode(t *testing.T) {
assert := testifyassert.New(t)
NodeInfoMap = NewNodeCache(params.DEFAULT_NODECACHE_SIZE)
// add a node into the cache and validate
NodeInfoMap.UpsertNode(NETWORKADMIN, NODE1, NodeApproved)
nodeInfo := NodeInfoMap.GetNodeByUrl(NODE1)
nodeInfo, err := NodeInfoMap.GetNodeByUrl(NODE1)
assert.True(err == nil, fmt.Sprintf("got errors in node fetch"))
assert.False(nodeInfo == nil, fmt.Sprintf("Expected node details, got nil"))
assert.True(nodeInfo.OrgId == NETWORKADMIN, fmt.Sprintf("Expected org id for node %v, got %v", NETWORKADMIN, nodeInfo.OrgId))
assert.True(nodeInfo.Url == NODE1, fmt.Sprintf("Expected node id %v, got %v", NODE1, nodeInfo.Url))
@ -97,16 +106,21 @@ func TestNodeCache_UpsertNode(t *testing.T) {
// check node details update by updating node status
NodeInfoMap.UpsertNode(ORGADMIN, NODE2, NodeDeactivated)
nodeInfo = NodeInfoMap.GetNodeByUrl(NODE2)
nodeInfo, err = NodeInfoMap.GetNodeByUrl(NODE2)
assert.True(err == nil, fmt.Sprintf("got errors in node fetch"))
assert.True(nodeInfo.Status == NodeDeactivated, fmt.Sprintf("Expected node status %v, got %v", NodeDeactivated, nodeInfo.Status))
}
func TestRoleCache_UpsertRole(t *testing.T) {
assert := testifyassert.New(t)
RoleInfoMap = NewRoleCache(params.DEFAULT_ROLECACHE_SIZE)
// add a role into the cache and validate
RoleInfoMap.UpsertRole(NETWORKADMIN, NETWORKADMIN, true, true, FullAccess, true)
roleInfo := RoleInfoMap.GetRole(NETWORKADMIN, NETWORKADMIN)
roleInfo, err := RoleInfoMap.GetRole(NETWORKADMIN, NETWORKADMIN)
assert.True(err == nil, "errors encountered")
assert.False(roleInfo == nil, fmt.Sprintf("Expected role details, got nil"))
assert.True(roleInfo.OrgId == NETWORKADMIN, fmt.Sprintf("Expected org id for node %v, got %v", NETWORKADMIN, roleInfo.OrgId))
assert.True(roleInfo.RoleId == NETWORKADMIN, fmt.Sprintf("Expected node id %v, got %v", NETWORKADMIN, roleInfo.RoleId))
@ -118,16 +132,22 @@ func TestRoleCache_UpsertRole(t *testing.T) {
// update role status and validate
RoleInfoMap.UpsertRole(ORGADMIN, ORGADMIN, true, true, FullAccess, false)
roleInfo = RoleInfoMap.GetRole(ORGADMIN, ORGADMIN)
roleInfo, err = RoleInfoMap.GetRole(ORGADMIN, ORGADMIN)
assert.True(err == nil, "errors encountered")
assert.True(!roleInfo.Active, fmt.Sprintf("Expected role active status to be %v, got %v", true, roleInfo.Active))
}
func TestAcctCache_UpsertAccount(t *testing.T) {
assert := testifyassert.New(t)
AcctInfoMap = NewAcctCache(params.DEFAULT_ACCOUNTCACHE_SIZE)
// add an account into the cache and validate
AcctInfoMap.UpsertAccount(NETWORKADMIN, NETWORKADMIN, Acct1, true, AcctActive)
acctInfo := AcctInfoMap.GetAccount(Acct1)
acctInfo, err := AcctInfoMap.GetAccount(Acct1)
assert.True(err == nil)
assert.False(acctInfo == nil, fmt.Sprintf("Expected account details, got nil"))
assert.True(acctInfo.OrgId == NETWORKADMIN, fmt.Sprintf("Expected org id for the account to be %v, got %v", NETWORKADMIN, acctInfo.OrgId))
assert.True(acctInfo.AcctId == Acct1, fmt.Sprintf("Expected account id %x, got %x", Acct1, acctInfo.AcctId))
@ -139,7 +159,9 @@ func TestAcctCache_UpsertAccount(t *testing.T) {
// update account status and validate
AcctInfoMap.UpsertAccount(ORGADMIN, ORGADMIN, Acct2, true, AcctBlacklisted)
acctInfo = AcctInfoMap.GetAccount(Acct2)
acctInfo, err = AcctInfoMap.GetAccount(Acct2)
assert.True(err == nil)
assert.True(acctInfo.Status == AcctBlacklisted, fmt.Sprintf("Expected account status to be %v, got %v", AcctBlacklisted, acctInfo.Status))
// validate the list for org and role functions
@ -234,11 +256,12 @@ func TestValidateNodeForTxn_whenUsingOnlyHexNodeId(t *testing.T) {
// test the cache limit
func TestLRUCacheLimit(t *testing.T) {
for i := 0; i < defaultOrgMapLimit; i++ {
for i := 0; i < params.DEFAULT_ORGCACHE_SIZE; i++ {
orgName := "ORG" + strconv.Itoa(i)
OrgInfoMap.UpsertOrg(orgName, "", NETWORKADMIN, big.NewInt(1), OrgApproved)
}
o := OrgInfoMap.GetOrg("ORG1")
o, err := OrgInfoMap.GetOrg("ORG1")
testifyassert.True(t, err == nil)
testifyassert.True(t, o != nil)
}

View File

@ -1,7 +1,11 @@
package params
const (
PERMISSIONED_CONFIG = "permissioned-nodes.json"
BLACKLIST_CONFIG = "disallowed-nodes.json"
PERMISSION_MODEL_CONFIG = "permission-config.json"
PERMISSIONED_CONFIG = "permissioned-nodes.json"
BLACKLIST_CONFIG = "disallowed-nodes.json"
PERMISSION_MODEL_CONFIG = "permission-config.json"
DEFAULT_ORGCACHE_SIZE = 2000
DEFAULT_ROLECACHE_SIZE = 2500
DEFAULT_NODECACHE_SIZE = 1000
DEFAULT_ACCOUNTCACHE_SIZE = 6000
)

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -31,7 +31,7 @@ var (
const PermUpgrABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"getPermImpl\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_proposedImpl\",\"type\":\"address\"}],\"name\":\"confirmImplChange\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getGuardian\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getPermInterface\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_permInterface\",\"type\":\"address\"},{\"name\":\"_permImpl\",\"type\":\"address\"}],\"name\":\"init\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_guardian\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"
// PermUpgrBin is the compiled bytecode used for deploying new contracts.
var PermUpgrBin = "0x608060405234801561001057600080fd5b5060405160208061079f8339810180604052602081101561003057600080fd5b505160008054600160a060020a03909216600160a060020a03199092169190911790556002805460a060020a60ff021916905561072d806100726000396000f3fe608060405234801561001057600080fd5b506004361061005a5760e060020a60003504630e32cf90811461005f57806322bcb39a14610083578063a75b87d2146100ab578063e572515c146100b3578063f09a4016146100bb575b600080fd5b6100676100e9565b60408051600160a060020a039092168252519081900360200190f35b6100a96004803603602081101561009957600080fd5b5035600160a060020a03166100f8565b005b610067610341565b610067610350565b6100a9600480360360408110156100d157600080fd5b50600160a060020a038135811691602001351661035f565b600154600160a060020a031690565b600054600160a060020a0316331461017157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c69642063616c6c6572000000000000000000000000000000000000604482015290519081900360640190fd5b60608060606000600160009054906101000a9004600160a060020a0316600160a060020a031663cc9ba6fa6040518163ffffffff1660e060020a02815260040160006040518083038186803b1580156101c957600080fd5b505afa1580156101dd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052608081101561020657600080fd5b81019080805164010000000081111561021e57600080fd5b8201602081018481111561023157600080fd5b815164010000000081118282018710171561024b57600080fd5b5050929190602001805164010000000081111561026757600080fd5b8201602081018481111561027a57600080fd5b815164010000000081118282018710171561029457600080fd5b505092919060200180516401000000008111156102b057600080fd5b820160208101848111156102c357600080fd5b81516401000000008111828201871017156102dd57600080fd5b50506020909101519498509296509194509192506103029150869050858585856104e2565b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03878116919091179182905561033a9116610686565b5050505050565b600054600160a060020a031690565b600254600160a060020a031690565b600054600160a060020a031633146103d857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c69642063616c6c6572000000000000000000000000000000000000604482015290519081900360640190fd5b60025474010000000000000000000000000000000000000000900460ff161561046257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f63616e206265206578656375746564206f6e6c79206f6e636500000000000000604482015290519081900360640190fd5b60018054600160a060020a0380841673ffffffffffffffffffffffffffffffffffffffff199283161792839055600280548683169316929092179091556104a99116610686565b50506002805474ff0000000000000000000000000000000000000000191674010000000000000000000000000000000000000000179055565b84600160a060020a031663f5ad584a858585856040518563ffffffff1660e060020a0281526004018080602001806020018060200185151515158152602001848103845288818151815260200191508051906020019080838360005b8381101561055657818101518382015260200161053e565b50505050905090810190601f1680156105835780820380516001836020036101000a031916815260200191505b50848103835287518152875160209182019189019080838360005b838110156105b657818101518382015260200161059e565b50505050905090810190601f1680156105e35780820380516001836020036101000a031916815260200191505b50848103825286518152865160209182019188019080838360005b838110156106165781810151838201526020016105fe565b50505050905090810190601f1680156106435780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b15801561066757600080fd5b505af115801561067b573d6000803e3d6000fd5b505050505050505050565b600254604080517f511bbd9f000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301529151919092169163511bbd9f91602480830192600092919082900301818387803b1580156106ed57600080fd5b505af115801561033a573d6000803e3d6000fdfea165627a7a72305820c72c50e5bc751713bb5b2ee801ec643bd840b7557519b323814578a72c448a0e0029"
var PermUpgrBin = "0x608060405234801561001057600080fd5b5060405160208061079f8339810180604052602081101561003057600080fd5b505160008054600160a060020a03909216600160a060020a03199092169190911790556002805460a060020a60ff021916905561072d806100726000396000f3fe608060405234801561001057600080fd5b506004361061005a5760e060020a60003504630e32cf90811461005f57806322bcb39a14610083578063a75b87d2146100ab578063e572515c146100b3578063f09a4016146100bb575b600080fd5b6100676100e9565b60408051600160a060020a039092168252519081900360200190f35b6100a96004803603602081101561009957600080fd5b5035600160a060020a03166100f8565b005b610067610341565b610067610350565b6100a9600480360360408110156100d157600080fd5b50600160a060020a038135811691602001351661035f565b600154600160a060020a031690565b600054600160a060020a0316331461017157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c69642063616c6c6572000000000000000000000000000000000000604482015290519081900360640190fd5b60608060606000600160009054906101000a9004600160a060020a0316600160a060020a031663cc9ba6fa6040518163ffffffff1660e060020a02815260040160006040518083038186803b1580156101c957600080fd5b505afa1580156101dd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052608081101561020657600080fd5b81019080805164010000000081111561021e57600080fd5b8201602081018481111561023157600080fd5b815164010000000081118282018710171561024b57600080fd5b5050929190602001805164010000000081111561026757600080fd5b8201602081018481111561027a57600080fd5b815164010000000081118282018710171561029457600080fd5b505092919060200180516401000000008111156102b057600080fd5b820160208101848111156102c357600080fd5b81516401000000008111828201871017156102dd57600080fd5b50506020909101519498509296509194509192506103029150869050858585856104e2565b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03878116919091179182905561033a9116610686565b5050505050565b600054600160a060020a031690565b600254600160a060020a031690565b600054600160a060020a031633146103d857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c69642063616c6c6572000000000000000000000000000000000000604482015290519081900360640190fd5b60025474010000000000000000000000000000000000000000900460ff161561046257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f63616e206265206578656375746564206f6e6c79206f6e636500000000000000604482015290519081900360640190fd5b60018054600160a060020a0380841673ffffffffffffffffffffffffffffffffffffffff199283161792839055600280548683169316929092179091556104a99116610686565b50506002805474ff0000000000000000000000000000000000000000191674010000000000000000000000000000000000000000179055565b84600160a060020a031663f5ad584a858585856040518563ffffffff1660e060020a0281526004018080602001806020018060200185151515158152602001848103845288818151815260200191508051906020019080838360005b8381101561055657818101518382015260200161053e565b50505050905090810190601f1680156105835780820380516001836020036101000a031916815260200191505b50848103835287518152875160209182019189019080838360005b838110156105b657818101518382015260200161059e565b50505050905090810190601f1680156105e35780820380516001836020036101000a031916815260200191505b50848103825286518152865160209182019188019080838360005b838110156106165781810151838201526020016105fe565b50505050905090810190601f1680156106435780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b15801561066757600080fd5b505af115801561067b573d6000803e3d6000fd5b505050505050505050565b600254604080517f511bbd9f000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301529151919092169163511bbd9f91602480830192600092919082900301818387803b1580156106ed57600080fd5b505af115801561033a573d6000803e3d6000fdfea165627a7a723058202734d6e2a425add14568c5fd8433249acecdcc90474937bbe9c0cc5474e806e70029"
// DeployPermUpgr deploys a new Ethereum contract, binding an instance of PermUpgr to it.
func DeployPermUpgr(auth *bind.TransactOpts, backend bind.ContractBackend, _guardian common.Address) (common.Address, *types.Transaction, *PermUpgr, error) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -95,6 +95,9 @@ contract NodeManager {
*/
function getNodeDetails(string calldata enodeId) external view
returns (string memory _orgId, string memory _enodeId, uint256 _nodeStatus) {
if (nodeIdToIndex[keccak256(abi.encode(_enodeId))] == 0) {
return ("", enodeId, 0);
}
uint256 nodeIndex = _getNodeIndex(enodeId);
return (nodeList[nodeIndex].orgId, nodeList[nodeIndex].enodeId,
nodeList[nodeIndex].status);

View File

@ -195,6 +195,33 @@ contract OrgManager {
orgList[_orgIndex].ultParent, orgList[_orgIndex].level, orgList[_orgIndex].status);
}
/** @notice returns org info for a given org id
* @param _orgId org id
* @return org id
* @return parent org id
* @return ultimate parent id
* @return level in the org tree
* @return status
*/
function getOrgDetails(string calldata _orgId) external view returns (string memory,
string memory, string memory, uint256, uint256) {
if (!checkOrgExists(_orgId)){
return (_orgId, "", "", 0,0);
}
uint256 _orgIndex = _getOrgIndex(_orgId);
return (orgList[_orgIndex].orgId, orgList[_orgIndex].parentId,
orgList[_orgIndex].ultParent, orgList[_orgIndex].level, orgList[_orgIndex].status);
}
/** @notice returns the array of sub org indexes for the given org
* @param _orgId org id
* @return array of sub org indexes
*/
function getSubOrgIndexes(string calldata _orgId) external view returns (uint[] memory) {
require(checkOrgExists(_orgId) == true, "org does not exist");
uint256 _orgIndex = _getOrgIndex(_orgId);
return (orgList[_orgIndex].subOrgIndexList);
}
/** @notice returns the master org id for the given org or sub org
* @param _orgId org id
* @return master org id
@ -219,6 +246,9 @@ contract OrgManager {
*/
function checkOrgStatus(string memory _orgId, uint256 _orgStatus)
public view returns (bool){
if (OrgIndex[keccak256(abi.encodePacked(_orgId))] == 0) {
return false;
}
uint256 id = _getOrgIndex(_orgId);
return ((OrgIndex[keccak256(abi.encodePacked(_orgId))] != 0)
&& orgList[id].status == _orgStatus);
@ -334,7 +364,7 @@ contract OrgManager {
/** @notice returns the org index from the org list for the given org
* @return org index
*/
function _getOrgIndex(string memory _orgId) public view returns (uint){
function _getOrgIndex(string memory _orgId) private view returns (uint){
return OrgIndex[keccak256(abi.encodePacked(_orgId))] - 1;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
[{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_action","type":"uint256"}],"name":"updateOrg","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_action","type":"uint256"}],"name":"approveOrgStatusUpdate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"}],"name":"getUltimateParent","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_pOrgId","type":"string"},{"name":"_orgId","type":"string"}],"name":"addSubOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"}],"name":"_getOrgIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_orgIndex","type":"uint256"}],"name":"getOrgInfo","outputs":[{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNumberOfOrgs","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"},{"name":"_orgStatus","type":"uint256"}],"name":"checkOrgStatus","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_breadth","type":"uint256"},{"name":"_depth","type":"uint256"}],"name":"setUpOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"}],"name":"approveOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"}],"name":"addOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"}],"name":"checkOrgExists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_permUpgradable","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_porgId","type":"string"},{"indexed":false,"name":"_ultParent","type":"string"},{"indexed":false,"name":"_level","type":"uint256"},{"indexed":false,"name":"_status","type":"uint256"}],"name":"OrgApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_porgId","type":"string"},{"indexed":false,"name":"_ultParent","type":"string"},{"indexed":false,"name":"_level","type":"uint256"},{"indexed":false,"name":"_status","type":"uint256"}],"name":"OrgPendingApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_porgId","type":"string"},{"indexed":false,"name":"_ultParent","type":"string"},{"indexed":false,"name":"_level","type":"uint256"}],"name":"OrgSuspended","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_porgId","type":"string"},{"indexed":false,"name":"_ultParent","type":"string"},{"indexed":false,"name":"_level","type":"uint256"}],"name":"OrgSuspensionRevoked","type":"event"}]
[{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_action","type":"uint256"}],"name":"updateOrg","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_action","type":"uint256"}],"name":"approveOrgStatusUpdate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"}],"name":"getUltimateParent","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_pOrgId","type":"string"},{"name":"_orgId","type":"string"}],"name":"addSubOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_orgIndex","type":"uint256"}],"name":"getOrgInfo","outputs":[{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"}],"name":"getSubOrgIndexes","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNumberOfOrgs","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"},{"name":"_orgStatus","type":"uint256"}],"name":"checkOrgStatus","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_breadth","type":"uint256"},{"name":"_depth","type":"uint256"}],"name":"setUpOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"}],"name":"approveOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"}],"name":"getOrgDetails","outputs":[{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"}],"name":"addOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"}],"name":"checkOrgExists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_permUpgradable","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_porgId","type":"string"},{"indexed":false,"name":"_ultParent","type":"string"},{"indexed":false,"name":"_level","type":"uint256"},{"indexed":false,"name":"_status","type":"uint256"}],"name":"OrgApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_porgId","type":"string"},{"indexed":false,"name":"_ultParent","type":"string"},{"indexed":false,"name":"_level","type":"uint256"},{"indexed":false,"name":"_status","type":"uint256"}],"name":"OrgPendingApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_porgId","type":"string"},{"indexed":false,"name":"_ultParent","type":"string"},{"indexed":false,"name":"_level","type":"uint256"}],"name":"OrgSuspended","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_porgId","type":"string"},{"indexed":false,"name":"_ultParent","type":"string"},{"indexed":false,"name":"_level","type":"uint256"}],"name":"OrgSuspensionRevoked","type":"event"}]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
608060405234801561001057600080fd5b5060405160208061079f8339810180604052602081101561003057600080fd5b505160008054600160a060020a03909216600160a060020a03199092169190911790556002805460a060020a60ff021916905561072d806100726000396000f3fe608060405234801561001057600080fd5b506004361061005a5760e060020a60003504630e32cf90811461005f57806322bcb39a14610083578063a75b87d2146100ab578063e572515c146100b3578063f09a4016146100bb575b600080fd5b6100676100e9565b60408051600160a060020a039092168252519081900360200190f35b6100a96004803603602081101561009957600080fd5b5035600160a060020a03166100f8565b005b610067610341565b610067610350565b6100a9600480360360408110156100d157600080fd5b50600160a060020a038135811691602001351661035f565b600154600160a060020a031690565b600054600160a060020a0316331461017157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c69642063616c6c6572000000000000000000000000000000000000604482015290519081900360640190fd5b60608060606000600160009054906101000a9004600160a060020a0316600160a060020a031663cc9ba6fa6040518163ffffffff1660e060020a02815260040160006040518083038186803b1580156101c957600080fd5b505afa1580156101dd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052608081101561020657600080fd5b81019080805164010000000081111561021e57600080fd5b8201602081018481111561023157600080fd5b815164010000000081118282018710171561024b57600080fd5b5050929190602001805164010000000081111561026757600080fd5b8201602081018481111561027a57600080fd5b815164010000000081118282018710171561029457600080fd5b505092919060200180516401000000008111156102b057600080fd5b820160208101848111156102c357600080fd5b81516401000000008111828201871017156102dd57600080fd5b50506020909101519498509296509194509192506103029150869050858585856104e2565b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03878116919091179182905561033a9116610686565b5050505050565b600054600160a060020a031690565b600254600160a060020a031690565b600054600160a060020a031633146103d857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c69642063616c6c6572000000000000000000000000000000000000604482015290519081900360640190fd5b60025474010000000000000000000000000000000000000000900460ff161561046257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f63616e206265206578656375746564206f6e6c79206f6e636500000000000000604482015290519081900360640190fd5b60018054600160a060020a0380841673ffffffffffffffffffffffffffffffffffffffff199283161792839055600280548683169316929092179091556104a99116610686565b50506002805474ff0000000000000000000000000000000000000000191674010000000000000000000000000000000000000000179055565b84600160a060020a031663f5ad584a858585856040518563ffffffff1660e060020a0281526004018080602001806020018060200185151515158152602001848103845288818151815260200191508051906020019080838360005b8381101561055657818101518382015260200161053e565b50505050905090810190601f1680156105835780820380516001836020036101000a031916815260200191505b50848103835287518152875160209182019189019080838360005b838110156105b657818101518382015260200161059e565b50505050905090810190601f1680156105e35780820380516001836020036101000a031916815260200191505b50848103825286518152865160209182019188019080838360005b838110156106165781810151838201526020016105fe565b50505050905090810190601f1680156106435780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b15801561066757600080fd5b505af115801561067b573d6000803e3d6000fd5b505050505050505050565b600254604080517f511bbd9f000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301529151919092169163511bbd9f91602480830192600092919082900301818387803b1580156106ed57600080fd5b505af115801561033a573d6000803e3d6000fdfea165627a7a72305820c72c50e5bc751713bb5b2ee801ec643bd840b7557519b323814578a72c448a0e0029
608060405234801561001057600080fd5b5060405160208061079f8339810180604052602081101561003057600080fd5b505160008054600160a060020a03909216600160a060020a03199092169190911790556002805460a060020a60ff021916905561072d806100726000396000f3fe608060405234801561001057600080fd5b506004361061005a5760e060020a60003504630e32cf90811461005f57806322bcb39a14610083578063a75b87d2146100ab578063e572515c146100b3578063f09a4016146100bb575b600080fd5b6100676100e9565b60408051600160a060020a039092168252519081900360200190f35b6100a96004803603602081101561009957600080fd5b5035600160a060020a03166100f8565b005b610067610341565b610067610350565b6100a9600480360360408110156100d157600080fd5b50600160a060020a038135811691602001351661035f565b600154600160a060020a031690565b600054600160a060020a0316331461017157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c69642063616c6c6572000000000000000000000000000000000000604482015290519081900360640190fd5b60608060606000600160009054906101000a9004600160a060020a0316600160a060020a031663cc9ba6fa6040518163ffffffff1660e060020a02815260040160006040518083038186803b1580156101c957600080fd5b505afa1580156101dd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052608081101561020657600080fd5b81019080805164010000000081111561021e57600080fd5b8201602081018481111561023157600080fd5b815164010000000081118282018710171561024b57600080fd5b5050929190602001805164010000000081111561026757600080fd5b8201602081018481111561027a57600080fd5b815164010000000081118282018710171561029457600080fd5b505092919060200180516401000000008111156102b057600080fd5b820160208101848111156102c357600080fd5b81516401000000008111828201871017156102dd57600080fd5b50506020909101519498509296509194509192506103029150869050858585856104e2565b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03878116919091179182905561033a9116610686565b5050505050565b600054600160a060020a031690565b600254600160a060020a031690565b600054600160a060020a031633146103d857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c69642063616c6c6572000000000000000000000000000000000000604482015290519081900360640190fd5b60025474010000000000000000000000000000000000000000900460ff161561046257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f63616e206265206578656375746564206f6e6c79206f6e636500000000000000604482015290519081900360640190fd5b60018054600160a060020a0380841673ffffffffffffffffffffffffffffffffffffffff199283161792839055600280548683169316929092179091556104a99116610686565b50506002805474ff0000000000000000000000000000000000000000191674010000000000000000000000000000000000000000179055565b84600160a060020a031663f5ad584a858585856040518563ffffffff1660e060020a0281526004018080602001806020018060200185151515158152602001848103845288818151815260200191508051906020019080838360005b8381101561055657818101518382015260200161053e565b50505050905090810190601f1680156105835780820380516001836020036101000a031916815260200191505b50848103835287518152875160209182019189019080838360005b838110156105b657818101518382015260200161059e565b50505050905090810190601f1680156105e35780820380516001836020036101000a031916815260200191505b50848103825286518152865160209182019188019080838360005b838110156106165781810151838201526020016105fe565b50505050905090810190601f1680156106435780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b15801561066757600080fd5b505af115801561067b573d6000803e3d6000fd5b505050505050505050565b600254604080517f511bbd9f000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301529151919092169163511bbd9f91602480830192600092919082900301818387803b1580156106ed57600080fd5b505af115801561033a573d6000803e3d6000fdfea165627a7a723058202734d6e2a425add14568c5fd8433249acecdcc90474937bbe9c0cc5474e806e70029

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -13,6 +13,7 @@ import (
"time"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth"
@ -173,7 +174,8 @@ func (p *PermissionCtrl) AfterStart() error {
}
// populate the initial list of permissioned nodes and account accesses
if err := p.populateInitPermissions(); err != nil {
if err := p.populateInitPermissions(params.DEFAULT_ORGCACHE_SIZE, params.DEFAULT_ROLECACHE_SIZE,
params.DEFAULT_NODECACHE_SIZE, params.DEFAULT_ACCOUNTCACHE_SIZE); err != nil {
return fmt.Errorf("populateInitPermissions failed: %v", err)
}
@ -569,8 +571,11 @@ func (p *PermissionCtrl) manageAccountPermissions() error {
types.AcctInfoMap.UpsertAccount(evtAccessRevoked.OrgId, evtAccessRevoked.RoleId, evtAccessRevoked.Account, evtAccessRevoked.OrgAdmin, types.AcctActive)
case evtStatusChanged := <-chStatusChanged:
ac := types.AcctInfoMap.GetAccount(evtStatusChanged.Account)
types.AcctInfoMap.UpsertAccount(evtStatusChanged.OrgId, ac.RoleId, evtStatusChanged.Account, ac.IsOrgAdmin, types.AcctStatus(int(evtStatusChanged.Status.Uint64())))
if ac, err := types.AcctInfoMap.GetAccount(evtStatusChanged.Account); ac != nil {
types.AcctInfoMap.UpsertAccount(evtStatusChanged.OrgId, ac.RoleId, evtStatusChanged.Account, ac.IsOrgAdmin, types.AcctStatus(int(evtStatusChanged.Status.Uint64())))
} else {
log.Info("error fetching account information", "err", err)
}
case <-stopChan:
log.Info("quit account contract watch")
return
@ -610,9 +615,25 @@ func (p *PermissionCtrl) disconnectNode(enodeId string) {
}
func (p *PermissionCtrl) instantiateCache(orgCacheSize, roleCacheSize, nodeCacheSize, accountCacheSize int) {
// instantiate the cache objects for permissions
types.OrgInfoMap = types.NewOrgCache(orgCacheSize)
types.OrgInfoMap.PopulateCacheFunc(p.populateOrgToCache)
types.RoleInfoMap = types.NewRoleCache(roleCacheSize)
types.RoleInfoMap.PopulateCacheFunc(p.populateRoleToCache)
types.NodeInfoMap = types.NewNodeCache(nodeCacheSize)
types.NodeInfoMap.PopulateCacheFunc(p.populateNodeCache)
types.NodeInfoMap.PopulateValidateFunc(p.populateNodeCacheAndValidate)
types.AcctInfoMap = types.NewAcctCache(accountCacheSize)
types.AcctInfoMap.PopulateCacheFunc(p.populateAccountToCache)
}
// Thus function checks if the initial network boot up status and if no
// populates permissions model with details from permission-config.json
func (p *PermissionCtrl) populateInitPermissions() error {
func (p *PermissionCtrl) populateInitPermissions(orgCacheSize, roleCacheSize, nodeCacheSize, accountCacheSize int) error {
auth := bind.NewKeyedTransactor(p.key)
permInterfSession := &pbind.PermInterfaceSession{
Contract: p.permInterf,
@ -627,6 +648,8 @@ func (p *PermissionCtrl) populateInitPermissions() error {
},
}
p.instantiateCache(orgCacheSize, roleCacheSize, nodeCacheSize, accountCacheSize)
networkInitialized, err := permInterfSession.GetNetworkBootStatus()
if err != nil {
// handle the scenario of no contract code.
@ -651,7 +674,6 @@ func (p *PermissionCtrl) populateInitPermissions() error {
}
}
}
return nil
}
@ -839,7 +861,7 @@ func (p *PermissionCtrl) manageRolePermissions() error {
types.RoleInfoMap.UpsertRole(evtRoleCreated.OrgId, evtRoleCreated.RoleId, evtRoleCreated.IsVoter, evtRoleCreated.IsAdmin, types.AccessType(int(evtRoleCreated.BaseAccess.Uint64())), true)
case evtRoleRevoked := <-chRoleRevoked:
if r := types.RoleInfoMap.GetRole(evtRoleRevoked.OrgId, evtRoleRevoked.RoleId); r != nil {
if r, _ := types.RoleInfoMap.GetRole(evtRoleRevoked.OrgId, evtRoleRevoked.RoleId); r != nil {
types.RoleInfoMap.UpsertRole(evtRoleRevoked.OrgId, evtRoleRevoked.RoleId, r.IsVoter, r.IsAdmin, r.Access, false)
} else {
log.Error("Revoke role - cache is missing role", "org", evtRoleRevoked.OrgId, "role", evtRoleRevoked.RoleId)
@ -852,3 +874,129 @@ func (p *PermissionCtrl) manageRolePermissions() error {
}()
return nil
}
// getter to get an account record from the contract
func (p *PermissionCtrl) populateAccountToCache(acctId common.Address) (*types.AccountInfo, error) {
permAcctInterface := &pbind.AcctManagerSession{
Contract: p.permAcct,
CallOpts: bind.CallOpts{
Pending: true,
},
}
account, orgId, roleId, status, isAdmin, err := permAcctInterface.GetAccountDetails(acctId)
if err != nil {
return nil, err
}
if status.Int64() == 0 {
return nil, types.ErrAccountNotThere
}
return &types.AccountInfo{AcctId: account, OrgId: orgId, RoleId: roleId, Status: types.AcctStatus(status.Int64()), IsOrgAdmin: isAdmin}, nil
}
// getter to get a org record from the contract
func (p *PermissionCtrl) populateOrgToCache(orgId string) (*types.OrgInfo, error) {
permOrgInterface := &pbind.OrgManagerSession{
Contract: p.permOrg,
CallOpts: bind.CallOpts{
Pending: true,
},
}
org, parentOrgId, ultimateParentId, orgLevel, orgStatus, err := permOrgInterface.GetOrgDetails(orgId)
if err != nil {
return nil, err
}
if orgStatus.Int64() == 0 {
return nil, types.ErrOrgDoesNotExists
}
orgInfo := types.OrgInfo{OrgId: org, ParentOrgId: parentOrgId, UltimateParent: ultimateParentId, Status: types.OrgStatus(orgStatus.Int64()), Level: orgLevel}
// now need to build the list of sub orgs for this org
subOrgIndexes, err := permOrgInterface.GetSubOrgIndexes(orgId)
if err != nil {
return nil, err
}
if len(subOrgIndexes) == 0 {
return &orgInfo, nil
}
// range through the sub org indexes and get the org ids to populate the suborg list
for _, s := range subOrgIndexes {
subOrgId, _, _, _, _, err := permOrgInterface.GetOrgInfo(s)
if err != nil {
return nil, err
}
orgInfo.SubOrgList = append(orgInfo.SubOrgList, orgId+"."+subOrgId)
}
return &orgInfo, nil
}
// getter to get a role record from the contract
func (p *PermissionCtrl) populateRoleToCache(roleKey *types.RoleKey) (*types.RoleInfo, error) {
permRoleInterface := &pbind.RoleManagerSession{
Contract: p.permRole,
CallOpts: bind.CallOpts{
Pending: true,
},
}
roleDetails, err := permRoleInterface.GetRoleDetails(roleKey.RoleId, roleKey.OrgId)
if err != nil {
return nil, err
}
if roleDetails.OrgId == "" {
return nil, types.ErrInvalidRole
}
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
}
// getter to get a role record from the contract
func (p *PermissionCtrl) populateNodeCache(url string) (*types.NodeInfo, error) {
permNodeInterface := &pbind.NodeManagerSession{
Contract: p.permNode,
CallOpts: bind.CallOpts{
Pending: true,
},
}
nodeDetails, err := permNodeInterface.GetNodeDetails(url)
if err != nil {
return nil, err
}
if nodeDetails.NodeStatus.Int64() == 0 {
return nil, types.ErrNodeDoesNotExists
}
return &types.NodeInfo{OrgId: nodeDetails.OrgId, Url: nodeDetails.EnodeId, Status: types.NodeStatus(nodeDetails.NodeStatus.Int64())}, nil
}
// getter to get a node record from the contract
func (p *PermissionCtrl) populateNodeCacheAndValidate(hexNodeId, ultimateParentId string) bool {
permNodeInterface := &pbind.NodeManagerSession{
Contract: p.permNode,
CallOpts: bind.CallOpts{
Pending: true,
},
}
txnAllowed := false
passedEnode, _ := enode.ParseV4(hexNodeId)
if numberOfNodes, err := permNodeInterface.GetNumberOfNodes(); err == nil {
numNodes := numberOfNodes.Uint64()
for k := uint64(0); k < numNodes; k++ {
if nodeStruct, err := permNodeInterface.GetNodeDetailsFromIndex(big.NewInt(int64(k))); err == nil {
if orgRec, err := types.OrgInfoMap.GetOrg(nodeStruct.OrgId); err != nil {
if orgRec.UltimateParent == ultimateParentId {
recEnode, _ := enode.ParseV4(nodeStruct.EnodeId)
if recEnode.ID() == passedEnode.ID() {
txnAllowed = true
types.NodeInfoMap.UpsertNode(nodeStruct.OrgId, nodeStruct.EnodeId, types.NodeStatus(int(nodeStruct.NodeStatus.Int64())))
}
}
}
}
}
}
return txnAllowed
}

View File

@ -9,6 +9,7 @@ import (
"log"
"math/big"
"os"
"strconv"
"testing"
"github.com/ethereum/go-ethereum/accounts"
@ -36,10 +37,16 @@ const (
arbitraryOrgAdminRole = "ORG_ADMIN_ROLE"
arbitraryNode1 = "enode://ac6b1096ca56b9f6d004b779ae3728bf83f8e22453404cc3cef16a3d9b96608bc67c4b30db88e0a5a6c6390213f7acbe1153ff6d23ce57380104288ae19373ef@127.0.0.1:21000?discport=0&raftport=50401"
arbitraryNode2 = "enode://0ba6b9f606a43a95edc6247cdb1c1e105145817be7bcafd6b2c0ba15d58145f0dc1a194f70ba73cd6f4cdd6864edc7687f311254c7555cc32e4d45aeb1b80416@127.0.0.1:21001?discport=0&raftport=50402"
arbitraryNode3 = "enode://579f786d4e2830bbcc02815a27e8a9bacccc9605df4dc6f20bcc1a6eb391e7225fff7cb83e5b4ecd1f3a94d8b733803f2f66b7e871961e7b029e22c155c3a778@127.0.0.1:21002?discport=0&raftport=50403"
arbitraryNode4 = "enode://3d9ca5956b38557aba991e31cf510d4df641dce9cc26bfeb7de082f0c07abb6ede3a58410c8f249dabeecee4ad3979929ac4c7c496ad20b8cfdd061b7401b4f5@127.0.0.1:21003?discport=0&raftport=50404"
arbitraryOrgToAdd = "ORG1"
arbitrarySubOrg = "SUB1"
arbitrartNewRole1 = "NEW_ROLE_1"
arbitrartNewRole2 = "NEW_ROLE_2"
orgCacheSize = 4
roleCacheSize = 4
nodeCacheSize = 2
accountCacheSize = 4
)
var ErrAccountsLinked = errors.New("Accounts linked to the role. Cannot be removed")
@ -196,7 +203,7 @@ func TestPermissionCtrl_PopulateInitPermissions_AfterNetworkIsInitialized(t *tes
testObject := typicalPermissionCtrl(t)
assert.NoError(t, testObject.AfterStart())
err := testObject.populateInitPermissions()
err := testObject.populateInitPermissions(orgCacheSize, roleCacheSize, nodeCacheSize, accountCacheSize)
assert.NoError(t, err)
@ -236,7 +243,7 @@ func typicalQuorumControlsAPI(t *testing.T) *QuorumControlsAPI {
if !assert.NoError(t, pc.AfterStart()) {
t.Fail()
}
if !assert.NoError(t, pc.populateInitPermissions()) {
if !assert.NoError(t, pc.populateInitPermissions(orgCacheSize, roleCacheSize, nodeCacheSize, accountCacheSize)) {
t.Fail()
}
return NewQuorumControlsAPI(pc)
@ -251,7 +258,7 @@ func TestQuorumControlsAPI_ListAPIs(t *testing.T) {
assert.Equal(t, orgDetails.RoleList[0].RoleId, arbitraryNetworkAdminRole)
orgDetails, err = testObject.GetOrgDetails("XYZ")
assert.Equal(t, err, errors.New("org does not exist"))
assert.Equal(t, err, errors.New("Org does not exist"))
// test NodeList
assert.Equal(t, len(testObject.NodeList()), 0)
@ -318,9 +325,21 @@ func TestQuorumControlsAPI_OrgAPIs(t *testing.T) {
_, err = testObject.AddSubOrg(arbitraryNetworkAdminOrg, "", "", txa)
assert.Equal(t, err, errors.New("Invalid input"))
_, err = testObject.GetOrgDetails(arbitraryOrgToAdd)
assert.NoError(t, err)
// caching tests - cache size for org is 4. add 4 sub orgs
// this will result in cache eviction
// get org details after this
for i := 0; i < orgCacheSize; i++ {
subOrgId := "TESTSUBORG" + strconv.Itoa(i)
_, err = testObject.AddSubOrg(arbitraryNetworkAdminOrg, subOrgId, "", txa)
assert.NoError(t, err)
types.OrgInfoMap.UpsertOrg(subOrgId, arbitraryNetworkAdminOrg, arbitraryNetworkAdminOrg, big.NewInt(2), types.OrgApproved)
}
assert.Equal(t, orgCacheSize, len(types.OrgInfoMap.GetOrgList()))
orgDetails, err := testObject.GetOrgDetails(arbitraryNetworkAdminOrg)
assert.Equal(t, orgDetails.AcctList[0].AcctId, guardianAddress)
assert.Equal(t, orgDetails.RoleList[0].RoleId, arbitraryNetworkAdminRole)
}
func TestQuorumControlsAPI_NodeAPIs(t *testing.T) {
@ -366,6 +385,21 @@ func TestQuorumControlsAPI_NodeAPIs(t *testing.T) {
_, err = testObject.ApproveBlackListedNodeRecovery(arbitraryNetworkAdminOrg, arbitraryNode2, txa)
assert.NoError(t, err)
types.NodeInfoMap.UpsertNode(arbitraryNetworkAdminOrg, arbitraryNode2, types.NodeApproved)
// caching tests - cache size for node is 3. add 2 nodes which will
// result in node eviction from cache. get evicted node details using api
_, err = testObject.AddNode(arbitraryNetworkAdminOrg, arbitraryNode3, txa)
assert.NoError(t, err)
types.NodeInfoMap.UpsertNode(arbitraryNetworkAdminOrg, arbitraryNode3, types.NodeApproved)
_, err = testObject.AddNode(arbitraryNetworkAdminOrg, arbitraryNode4, txa)
assert.NoError(t, err)
types.NodeInfoMap.UpsertNode(arbitraryNetworkAdminOrg, arbitraryNode4, types.NodeApproved)
assert.Equal(t, nodeCacheSize, len(types.NodeInfoMap.GetNodeList()))
nodeInfo, err := types.NodeInfoMap.GetNodeByUrl(arbitraryNode4)
assert.True(t, err == nil, "node fetch returned error")
assert.Equal(t, types.NodeApproved, nodeInfo.Status)
}
func TestQuorumControlsAPI_RoleAndAccountsAPIs(t *testing.T) {
@ -452,6 +486,38 @@ func TestQuorumControlsAPI_RoleAndAccountsAPIs(t *testing.T) {
assert.NoError(t, err)
types.AcctInfoMap.UpsertAccount(arbitraryNetworkAdminOrg, arbitrartNewRole2, acct, true, types.AcctActive)
// check role cache. the cache size is set to 4
// insert 4 records and then retrieve the 1st role
for i := 0; i < roleCacheSize; i++ {
roleId := "TESTROLE" + strconv.Itoa(i)
_, err = testObject.AddNewRole(arbitraryNetworkAdminOrg, roleId, uint8(types.FullAccess), false, false, txa)
assert.NoError(t, err)
types.RoleInfoMap.UpsertRole(arbitraryNetworkAdminOrg, roleId, false, false, types.FullAccess, true)
}
assert.Equal(t, roleCacheSize, len(types.RoleInfoMap.GetRoleList()))
roleInfo, err := types.RoleInfoMap.GetRole(arbitraryNetworkAdminOrg, arbitrartNewRole1)
assert.True(t, err == nil, "error encountered")
assert.Equal(t, roleInfo.RoleId, arbitrartNewRole1)
// check account cache
var AccountArray [4]common.Address
AccountArray[0] = common.StringToAddress("0fbdc686b912d7722dc86510934589e0aaf3b55a")
AccountArray[1] = common.StringToAddress("9186eb3d20cbd1f5f992a950d808c4495153abd5")
AccountArray[2] = common.StringToAddress("0638e1574728b6d862dd5d3a3e0942c3be47d996")
AccountArray[3] = common.StringToAddress("ae9bc6cd5145e67fbd1887a5145271fd182f0ee7")
for i := 0; i < accountCacheSize; i++ {
_, err = testObject.AddAccountToOrg(AccountArray[i], arbitraryNetworkAdminOrg, arbitrartNewRole1, txa)
assert.NoError(t, err)
types.AcctInfoMap.UpsertAccount(arbitraryNetworkAdminOrg, arbitrartNewRole1, AccountArray[i], false, types.AcctActive)
}
assert.Equal(t, accountCacheSize, len(types.AcctInfoMap.GetAcctList()))
acctInfo, err := types.AcctInfoMap.GetAccount(acct)
assert.True(t, err == nil, "error encountered")
assert.True(t, acctInfo != nil, "account details nil")
}
func getArbitraryAccount() common.Address {
@ -475,8 +541,8 @@ func typicalPermissionCtrl(t *testing.T) *PermissionCtrl {
Accounts: []common.Address{
guardianAddress,
},
SubOrgDepth: big.NewInt(3),
SubOrgBreadth: big.NewInt(3),
SubOrgDepth: big.NewInt(10),
SubOrgBreadth: big.NewInt(10),
})
if err != nil {
t.Fatal(err)
@ -507,7 +573,7 @@ func TestPermissionCtrl_whenUpdateFile(t *testing.T) {
testObject := typicalPermissionCtrl(t)
assert.NoError(t, testObject.AfterStart())
err := testObject.populateInitPermissions()
err := testObject.populateInitPermissions(orgCacheSize, roleCacheSize, nodeCacheSize, accountCacheSize)
assert.NoError(t, err)
d, _ := ioutil.TempDir("", "qdata")