diff --git a/core/tx_pool.go b/core/tx_pool.go index 324ec40c1..b2d5914de 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -618,7 +618,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { // Check if the sender account is authorized to perform the transaction if isQuorum { log.Info("Inside if before checkAccount") - if err := checkAccount(from); err != nil { + if err := checkAccount(from, tx.To()); err != nil { return ErrUnAuthorizedAccount } } @@ -1208,13 +1208,37 @@ func (as *accountSet) add(addr common.Address) { // checks if the account is permissioned for transaction -func checkAccount(acctId common.Address) error { +func checkAccount(fromAcct common.Address, toAcct *common.Address) error { log.Info("Inside checkAccount to validate") - access := types.GetAcctAccess(acctId) - if access != 99 { - err := errors.New("Account not permissioned") + access := types.GetAcctAccess(fromAcct) + + switch access { + case types.FullAccess: + log.Info("Full Access so no issue") + return nil + + case types.ReadOnly: + log.Info("Read only access cannot transact") + err := errors.New("Account Does not have transaction permissions") return err + + case types.Transact: + if toAcct == nil { + log.Info("Not entitled for contract create call ") + err := errors.New("Account Does not have contract create permissions") + return err + }else { + return nil + } + case types.ContractDeploy: + if toAcct != nil { + log.Info("Not entitled for transaction call ") + err := errors.New("Account Does not have transacte permissions") + return err + }else { + return nil + } } - log.Info("returning null") + log.Info("returning nil") return nil } diff --git a/core/types/permissions_cache.go b/core/types/permissions_cache.go index 245bd9cd0..3e1892113 100644 --- a/core/types/permissions_cache.go +++ b/core/types/permissions_cache.go @@ -6,9 +6,18 @@ import ( "github.com/ethereum/go-ethereum/log" ) +type AccessType uint8 + +const ( + FullAccess AccessType = iota + ReadOnly + Transact + ContractDeploy +) + type PermStruct struct { AcctId common.Address - Access uint8 + AcctAccess AccessType } type PermAccountsMap map[common.Address][] *PermStruct @@ -21,23 +30,23 @@ func AddAccountAccess(acctId common.Address, access uint8) { mu := sync.RWMutex{} mu.Lock() - AcctMap[acctId] = &PermStruct {AcctId : acctId, Access : access} + AcctMap[acctId] = &PermStruct {AcctId : acctId, AcctAccess : AccessType(access)} mu.Unlock() } -func GetAcctAccess(acctId common.Address) uint8 { +func GetAcctAccess(acctId common.Address) AccessType { mu := sync.RWMutex{} if len(AcctMap) != 0 { if _, ok := AcctMap[acctId]; ok { - log.Info("Inside GetAcct sending :", "acctId", AcctMap[acctId].AcctId, "access", AcctMap[acctId].Access) + log.Info("Inside GetAcct sending :", "acctId", AcctMap[acctId].AcctId, "access", AcctMap[acctId].AcctAccess) mu.RLock() - access := AcctMap[acctId].Access + acctAccess := AcctMap[acctId].AcctAccess mu.RUnlock() - return access + return acctAccess } } - return 99 + return FullAccess } diff --git a/permissions/Permissions.sol b/permissions/Permissions.sol index 14dfe5943..42f9974da 100644 --- a/permissions/Permissions.sol +++ b/permissions/Permissions.sol @@ -4,10 +4,14 @@ contract Permissions { enum NodeStatus { NotInList, PendingApproval, Approved, PendingDeactivation, Deactivated } - enum AccountAccess { FullAccess, ReadOnly, Transact, ContractDeploy, NoAccess } + enum AccountAccess {FullAccess, ReadOnly, Transact, ContractDeploy} struct nodeDetails { string enodeId; + //e.g. 127.0.0.1:20005 + string ipAddrPort; + string discPort; + string raftPort; bool canWrite; bool canLead; NodeStatus status; @@ -20,15 +24,15 @@ contract Permissions { } mapping (address => acctAccess) acctAccessList; - event NewNodeProposed (string _enodeId, bool _canWrite, bool _canLead); - event NodeApproved(string _enodeId); + event NewNodeProposed (string _enodeId); + event NodeApproved(string _enodeId, string _ipAddrPort, string _discPort, string _raftPort); event NodePendingDeactivation (string _enodeId); - event NodeDeactivated (string _enodeId); + event NodeDeactivated(string _enodeId, string _ipAddrPort, string _discPort, string _raftPort); event AcctAccessModified (address acctId, AccountAccess access); // Checks if the Node is already added. If yes then returns true function updateAcctAccess (address _acctId, AccountAccess access) public { - acctAccessList[_acctId] = acctAccess (_acctId, access); + acctAccessList[_acctId] = acctAccess(_acctId, access); emit AcctAccessModified(_acctId, access); } // Checks if the Node is already added. If yes then returns true @@ -39,14 +43,17 @@ contract Permissions { // Adds a node to the nodeList mapping and emits node added event if successfully and node exists event of node is already present function ApproveNode(string _enodeId) public { require(getNodeStatus(_enodeId) != NodeStatus.NotInList, "Node is already in the list"); - nodeList[keccak256(_enodeId)].status = NodeStatus.Approved; - emit NodeApproved(_enodeId); + + bytes32 i; + i = keccak256(_enodeId); + nodeList[i].status = NodeStatus.Approved; + emit NodeApproved(nodeList[i].enodeId, nodeList[i].ipAddrPort, nodeList[i].discPort, nodeList[i].raftPort); } - function ProposeNode(string _enodeId, bool _canWrite, bool _canLead) public { + function ProposeNode(string _enodeId, bool _canWrite, bool _canLead, string _ipAddrPort, string _discPort, string _raftPort) public { require(getNodeStatus(_enodeId) == NodeStatus.NotInList, "New node cannot be in the list"); - nodeList[keccak256(_enodeId)] = nodeDetails(_enodeId, _canWrite, _canLead, NodeStatus.PendingApproval); - emit NewNodeProposed (_enodeId, _canWrite, _canLead); + nodeList[keccak256(_enodeId)] = nodeDetails(_enodeId, _ipAddrPort,_discPort, _raftPort, _canWrite, _canLead, NodeStatus.PendingApproval); + emit NewNodeProposed (_enodeId); } function ProposeDeactivation(string _enodeId) public { @@ -58,8 +65,11 @@ contract Permissions { //deactivates a given Enode and emits the decativation event function DeactivateNode (string _enodeId) public { require(getNodeStatus(_enodeId) == NodeStatus.PendingDeactivation, "Node need to be in PendingDeactivation status"); - nodeList[keccak256(_enodeId)].status = NodeStatus.Deactivated; - emit NodeDeactivated(_enodeId); + + bytes32 i; + i = keccak256(_enodeId); + nodeList[i].status = NodeStatus.Deactivated; + emit NodeDeactivated(nodeList[i].enodeId, nodeList[i].ipAddrPort, nodeList[i].discPort, nodeList[i].raftPort); } } diff --git a/permissions/node_permissions.go b/permissions/node_permissions.go index 5a31e2029..823b3dd29 100644 --- a/permissions/node_permissions.go +++ b/permissions/node_permissions.go @@ -5,8 +5,9 @@ import ( "io/ioutil" "path/filepath" "os" + // "sync" - "github.com/ethereum/go-ethereum/common" + // "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/params" @@ -20,113 +21,95 @@ const ( PERMISSIONED_CONFIG = "permissioned-nodes.json" ) -//This function first adds the node list from permissioned-nodes.json to -//the permissiones contract deployed as a precompile via genesis.json +type NodeOperation uint8 + +const ( + NodeAdd NodeOperation = iota + NodeDelete +) + +// This function first adds the node list from permissioned-nodes.json to +// the permissiones contract deployed as a precompile via genesis.json func QuorumPermissioning(ctx *cli.Context, stack *node.Node ) error { + // Create a new ethclient to for interfacing with the contract stateReader, err := createEthClient(stack) if err != nil { + log.Error ("Unable to create ethereum client for permissions check : ", "err" , err) return err } - // //call populate nodes to populate the nodes into contract - // if err := populateNodesToContract (ctx, stack, e, stateReader); err != nil { - // return err; - // } + // check if permissioning contract is there at address. If not return from here + if _ , err = NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader); err != nil { + log.Error ("Permissions not enabled for the network : ", "err" , err) + return nil + } - //monitor for new nodes addition via smart contract - go monitorNewNodeAdd(stack, stateReader) + // Monitors node addition and decativation from network + manageNodePermissions(stack, stateReader); - //monitor for nodes deletiin via smart contract - go monitorNodeDelete(stack, stateReader) - - //monitor for nodes deletiin via smart contract - go monitorAccountPermissions(stack, stateReader) + // Monitors account level persmissions update from smart contarct + manageAccountPermissions(stack, stateReader); return nil } -//populates the nodes list from permissioned-nodes.json into the permissions -//smart contract -// func populateNodesToContract(ctx *cli.Context, stack *node.Node, e *eth.Ethereum, stateReader *ethclient.Client) error{ +// Create an RPC client for the contract interface +func createEthClient(stack *node.Node ) (*ethclient.Client, error){ + var e *eth.Ethereum + if err := stack.Service(&e); err != nil { + return nil, err + } -// // datadir := ctx.GlobalString(utils.DataDirFlag.Name) -// datadir := stack.DataDir() + rpcClient, err := stack.Attach() + if err != nil { + return nil, err + } -// //Read the key file from key store. SHOULD WE MAKE IT CONFIG value -// key, err := getKeyFromKeyStore(ctx, datadir) + return ethclient.NewClient(rpcClient), nil +} -// permissionsContract, err := NewPermissions(params.QuorumPermissionsContract, stateReader) -// if err != nil { -// return err -// } +// Manages node addition and decavtivation from network +func manageNodePermissions(stack *node.Node, stateReader *ethclient.Client) { + //monitor for new nodes addition via smart contract + go monitorNewNodeAdd(stack) -// auth, err := bind.NewTransactor(strings.NewReader(key), "") -// if err != nil { -// return err -// } + //monitor for nodes deletiin via smart contract + go monitorNodeDelete(stack, stateReader) +} -// permissionsSession := &PermissionsSession{ -// Contract: permissionsContract, -// CallOpts: bind.CallOpts{ -// Pending: true, -// }, -// TransactOpts: bind.TransactOpts{ -// From: auth.From, -// Signer: auth.Signer, -// GasLimit: 3558096384, -// GasPrice: big.NewInt(0), -// }, -// } - - -// nodes := p2p.ParsePermissionedNodes(datadir) -// for _, node := range nodes { -// enodeID := fmt.Sprintf("%x", node.ID[:]) -// log.Trace("Adding node to permissions contract", "enodeID", enodeID) - -// nonce := e.TxPool().Nonce(permissionsSession.TransactOpts.From) -// permissionsSession.TransactOpts.Nonce = new(big.Int).SetUint64(nonce) - -// tx, err := permissionsSession.ProposeNode(enodeID, true, true) -// if err != nil { -// log.Warn("Failed to propose node", "err", err) -// return err -// } -// log.Debug("Transaction pending", "tx hash", tx.Hash()) -// } -// return nil -// } - -//This functions listens on the channel for new node approval via smart contract and +// This functions listens on the channel for new node approval via smart contract and // adds the same into permissioned-nodes.json -func monitorNewNodeAdd(stack *node.Node, stateReader *ethclient.Client) { +func monitorNewNodeAdd(stack *node.Node) { + + stateReader, err := createEthClient(stack) permissions, err := NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader) if err != nil { - log.Error ("Failed to monitor new node add : ", "err" , err) + log.Error ("failed to monitor new node add : ", "err" , err) } datadir := stack.DataDir() - ch := make(chan *PermissionsNewNodeProposed) + ch := make(chan *PermissionsNodeApproved) opts := &bind.WatchOpts{} var blockNumber uint64 = 1 opts.Start = &blockNumber - var operation string = "ADD" - for { - _, err = permissions.WatchNewNodeProposed(opts, ch) + _, err = permissions.WatchNodeApproved(opts, ch) if err != nil { log.Info("Failed NewNodeProposed: %v", err) } - var newEvent *PermissionsNewNodeProposed = <-ch - updatePermissionedNodes(newEvent.EnodeId, datadir, operation) + var nodeAddEvent *PermissionsNodeApproved = <-ch + + log.Info("calling update permissions, length is", "event", nodeAddEvent) + + updatePermissionedNodes(nodeAddEvent.EnodeId, nodeAddEvent.IpAddrPort, nodeAddEvent.DiscPort, nodeAddEvent.RaftPort, datadir, NodeAdd) } } -//This functions listens on the channel for new node approval via smart contract and +// This functions listens on the channel for new node approval via smart contract and // adds the same into permissioned-nodes.json func monitorNodeDelete(stack *node.Node, stateReader *ethclient.Client) { @@ -142,8 +125,6 @@ func monitorNodeDelete(stack *node.Node, stateReader *ethclient.Client) { var blockNumber uint64 = 1 opts.Start = &blockNumber - var operation string = "DEL" - for { _, err = permissions.WatchNodeDeactivated(opts, ch) if err != nil { @@ -151,87 +132,12 @@ func monitorNodeDelete(stack *node.Node, stateReader *ethclient.Client) { } var newEvent *PermissionsNodeDeactivated = <-ch - updatePermissionedNodes(newEvent.EnodeId, datadir, operation) + updatePermissionedNodes(newEvent.EnodeId, newEvent.IpAddrPort, newEvent.DiscPort, newEvent.RaftPort, datadir, NodeDelete) } } -// Monitors permissions changes at acount level and uodate the global permissions -// map with the same -func monitorAccountPermissions(stack *node.Node, stateReader *ethclient.Client) { - - log.Info("Inside monotorAccountPermissions") - - permissions, err := NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader) - if err != nil { - log.Error ("Failed to monitor Account permissions : ", "err" , err) - } - ch := make(chan *PermissionsAcctAccessModified) - - opts := &bind.WatchOpts{} - var blockNumber uint64 = 1 - opts.Start = &blockNumber - - const addr = "ca843569e3427144cead5e4d5999a3d0ccf92b8e" - - var acctAddr = common.HexToAddress(addr) - - types.AddAccountAccess(acctAddr, 0) - - for { - _, err = permissions.WatchAcctAccessModified(opts, ch) - if err != nil { - log.Info("Failed NewNodeProposed: %v", err) - } - var newEvent *PermissionsAcctAccessModified = <-ch - log.Info("caught the event and calling PutAcctMap") - types.AddAccountAccess(newEvent.AcctId, newEvent.Access) - } -} -//Create an RPC client for the contract interface -// func createEthClient(stack *node.Node ) (*eth.Ethereum, *ethclient.Client, error){ -func createEthClient(stack *node.Node ) (*ethclient.Client, error){ - var e *eth.Ethereum - if err := stack.Service(&e); err != nil { - return nil, err - } - - rpcClient, err := stack.Attach() - if err != nil { - return nil, err - } - - return ethclient.NewClient(rpcClient), nil -} - -//This functions reads the first file in key store directory, reads the key -//value and returns the same -// func getKeyFromKeyStore(ctx *cli.Context, datadir string) (string, error) { -// // datadir := ctx.GlobalString(utils.DataDirFlag.Name) - -// files, err := ioutil.ReadDir(filepath.Join(datadir, "keystore")) -// if err != nil { -// return "", err -// } - -// // HACK: here we always use the first key as transactor -// var keyPath string -// for _, f := range files { -// keyPath = filepath.Join(datadir, "keystore", f.Name()) -// break -// } - -// keyBlob, err := ioutil.ReadFile(keyPath) -// if err != nil { -// return "", err -// } -// n := len(keyBlob) - -// return string(keyBlob[:n]), nil - -// } - //this function populates the new node information into the permissioned-nodes.json file -func updatePermissionedNodes(enodeId string, dataDir string, operation string){ +func updatePermissionedNodes(enodeId , ipAddrPort, discPort, raftPort, dataDir string, operation NodeOperation){ log.Debug("updatePermissionedNodes", "DataDir", dataDir, "file", PERMISSIONED_CONFIG) path := filepath.Join(dataDir, PERMISSIONED_CONFIG) @@ -254,9 +160,11 @@ func updatePermissionedNodes(enodeId string, dataDir string, operation string){ // HACK: currently the ip, discpot and raft port are hard coded. Need to enhance the //contract to pass these variables as part of the event and change this - newEnodeId := "enode://" + enodeId + "@127.0.0.1:21005?discport=0&raftport=50406" + // newEnodeId := "enode://" + enodeId + "@127.0.0.1:21005?discport=0&raftport=50406" + newEnodeId := "enode://" + enodeId + "@" + ipAddrPort + "?discPort=" + discPort + "&raftport=" + raftPort + log.Info("Enode id is : " , "newEnodeId", newEnodeId) - if (operation == "ADD"){ + if (operation == NodeAdd){ nodelist = append(nodelist, newEnodeId) } else { index := 0 @@ -269,9 +177,93 @@ func updatePermissionedNodes(enodeId string, dataDir string, operation string){ nodelist = append(nodelist[:index], nodelist[index+1:]...) } + // mu := sync.RWMutex{} blob, _ = json.Marshal(nodelist) + + // mu.Lock() if err:= ioutil.WriteFile(path, blob, 0644); err!= nil{ log.Error("updatePermissionedNodes: Error writing new node info to file", "err", err) } + // mu.Unlock() } +// Manages account level permissions update +func manageAccountPermissions(stack *node.Node, stateReader *ethclient.Client) error { + + //call populate nodes to populate the nodes into contract + if err := populateAcctPermissions (stack, stateReader); err != nil { + return err; + } + + //monitor for nodes deletiin via smart contract + go monitorAccountPermissions(stack, stateReader) + return nil +} + +// populates the nodes list from permissioned-nodes.json into the permissions +// smart contract +func populateAcctPermissions(stack *node.Node, stateReader *ethclient.Client) error{ + + permissions, err := NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader) + if err != nil { + log.Error ("Failed to monitor node delete: ", "err" , err) + return err + } + + opts := &bind.FilterOpts{} + + pastEvents, err := permissions.FilterAcctAccessModified(opts) + + recExists := true + for recExists { + recExists = pastEvents.Next() + if recExists { + types.AddAccountAccess(pastEvents.Event.AcctId, pastEvents.Event.Access) + } + } + return nil +} + + +// Monitors permissions changes at acount level and uodate the global permissions +// map with the same +func monitorAccountPermissions(stack *node.Node, stateReader *ethclient.Client) { + + log.Info("Inside monotorAccountPermissions") + + permissions, err := NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader) + if err != nil { + log.Error ("Failed to monitor Account permissions : ", "err" , err) + } + ch := make(chan *PermissionsAcctAccessModified) + + opts := &bind.WatchOpts{} + var blockNumber uint64 = 1 + opts.Start = &blockNumber + + // const addr1 = "ed9d02e382b34818e88b88a309c7fe71e65f419d" + // var acctAddr1 = common.HexToAddress(addr1) + // types.AddAccountAccess(acctAddr1, 0) + + // const addr2 = "ca843569e3427144cead5e4d5999a3d0ccf92b8e" + // var acctAddr2 = common.HexToAddress(addr2) + // types.AddAccountAccess(acctAddr2, 1) + + // const addr3 = "0fbdc686b912d7722dc86510934589e0aaf3b55a" + // var acctAddr3= common.HexToAddress(addr3) + // types.AddAccountAccess(acctAddr3, 2) + + // const addr4 = "9186eb3d20cbd1f5f992a950d808c4495153abd5" + // var acctAddr4= common.HexToAddress(addr4) + // types.AddAccountAccess(acctAddr4, 3) + + for { + _, err = permissions.WatchAcctAccessModified(opts, ch) + if err != nil { + log.Info("Failed NewNodeProposed: %v", err) + } + var newEvent *PermissionsAcctAccessModified = <-ch + log.Info("caught the event and calling PutAcctMap") + types.AddAccountAccess(newEvent.AcctId, newEvent.Access) + } +} diff --git a/permissions/permissions_binding.go b/permissions/permissions_binding.go index 5b0319fe7..0d6af1dc8 100644 --- a/permissions/permissions_binding.go +++ b/permissions/permissions_binding.go @@ -15,7 +15,7 @@ import ( ) // PermissionsABI is the input ABI used to generate the binding from. -const PermissionsABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"getNodeStatus\",\"outputs\":[{\"name\":\"_status\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"ProposeDeactivation\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_acctId\",\"type\":\"address\"},{\"name\":\"access\",\"type\":\"uint8\"}],\"name\":\"updateAcctAccess\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_canWrite\",\"type\":\"bool\"},{\"name\":\"_canLead\",\"type\":\"bool\"}],\"name\":\"ProposeNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"DeactivateNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"ApproveNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_canWrite\",\"type\":\"bool\"},{\"indexed\":false,\"name\":\"_canLead\",\"type\":\"bool\"}],\"name\":\"NewNodeProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"NodeApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"NodePendingDeactivation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"NodeDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"acctId\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"access\",\"type\":\"uint8\"}],\"name\":\"AcctAccessModified\",\"type\":\"event\"}]" +const PermissionsABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"getNodeStatus\",\"outputs\":[{\"name\":\"_status\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_canWrite\",\"type\":\"bool\"},{\"name\":\"_canLead\",\"type\":\"bool\"},{\"name\":\"_ipAddrPort\",\"type\":\"string\"},{\"name\":\"_discPort\",\"type\":\"string\"},{\"name\":\"_raftPort\",\"type\":\"string\"}],\"name\":\"ProposeNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"ProposeDeactivation\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_acctId\",\"type\":\"address\"},{\"name\":\"access\",\"type\":\"uint8\"}],\"name\":\"updateAcctAccess\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"DeactivateNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"ApproveNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"NewNodeProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_ipAddrPort\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_discPort\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_raftPort\",\"type\":\"string\"}],\"name\":\"NodeApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"NodePendingDeactivation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_ipAddrPort\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_discPort\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_raftPort\",\"type\":\"string\"}],\"name\":\"NodeDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"acctId\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"access\",\"type\":\"uint8\"}],\"name\":\"AcctAccessModified\",\"type\":\"event\"}]" // Permissions is an auto generated Go binding around an Ethereum contract. type Permissions struct { @@ -248,25 +248,25 @@ func (_Permissions *PermissionsTransactorSession) ProposeDeactivation(_enodeId s return _Permissions.Contract.ProposeDeactivation(&_Permissions.TransactOpts, _enodeId) } -// ProposeNode is a paid mutator transaction binding the contract method 0x9e1ebc14. +// ProposeNode is a paid mutator transaction binding the contract method 0x6b4b4867. // -// Solidity: function ProposeNode(_enodeId string, _canWrite bool, _canLead bool) returns() -func (_Permissions *PermissionsTransactor) ProposeNode(opts *bind.TransactOpts, _enodeId string, _canWrite bool, _canLead bool) (*types.Transaction, error) { - return _Permissions.contract.Transact(opts, "ProposeNode", _enodeId, _canWrite, _canLead) +// Solidity: function ProposeNode(_enodeId string, _canWrite bool, _canLead bool, _ipAddrPort string, _discPort string, _raftPort string) returns() +func (_Permissions *PermissionsTransactor) ProposeNode(opts *bind.TransactOpts, _enodeId string, _canWrite bool, _canLead bool, _ipAddrPort string, _discPort string, _raftPort string) (*types.Transaction, error) { + return _Permissions.contract.Transact(opts, "ProposeNode", _enodeId, _canWrite, _canLead, _ipAddrPort, _discPort, _raftPort) } -// ProposeNode is a paid mutator transaction binding the contract method 0x9e1ebc14. +// ProposeNode is a paid mutator transaction binding the contract method 0x6b4b4867. // -// Solidity: function ProposeNode(_enodeId string, _canWrite bool, _canLead bool) returns() -func (_Permissions *PermissionsSession) ProposeNode(_enodeId string, _canWrite bool, _canLead bool) (*types.Transaction, error) { - return _Permissions.Contract.ProposeNode(&_Permissions.TransactOpts, _enodeId, _canWrite, _canLead) +// Solidity: function ProposeNode(_enodeId string, _canWrite bool, _canLead bool, _ipAddrPort string, _discPort string, _raftPort string) returns() +func (_Permissions *PermissionsSession) ProposeNode(_enodeId string, _canWrite bool, _canLead bool, _ipAddrPort string, _discPort string, _raftPort string) (*types.Transaction, error) { + return _Permissions.Contract.ProposeNode(&_Permissions.TransactOpts, _enodeId, _canWrite, _canLead, _ipAddrPort, _discPort, _raftPort) } -// ProposeNode is a paid mutator transaction binding the contract method 0x9e1ebc14. +// ProposeNode is a paid mutator transaction binding the contract method 0x6b4b4867. // -// Solidity: function ProposeNode(_enodeId string, _canWrite bool, _canLead bool) returns() -func (_Permissions *PermissionsTransactorSession) ProposeNode(_enodeId string, _canWrite bool, _canLead bool) (*types.Transaction, error) { - return _Permissions.Contract.ProposeNode(&_Permissions.TransactOpts, _enodeId, _canWrite, _canLead) +// Solidity: function ProposeNode(_enodeId string, _canWrite bool, _canLead bool, _ipAddrPort string, _discPort string, _raftPort string) returns() +func (_Permissions *PermissionsTransactorSession) ProposeNode(_enodeId string, _canWrite bool, _canLead bool, _ipAddrPort string, _discPort string, _raftPort string) (*types.Transaction, error) { + return _Permissions.Contract.ProposeNode(&_Permissions.TransactOpts, _enodeId, _canWrite, _canLead, _ipAddrPort, _discPort, _raftPort) } // UpdateAcctAccess is a paid mutator transaction binding the contract method 0x913fc7d7. @@ -482,15 +482,13 @@ func (it *PermissionsNewNodeProposedIterator) Close() error { // PermissionsNewNodeProposed represents a NewNodeProposed event raised by the Permissions contract. type PermissionsNewNodeProposed struct { - EnodeId string - CanWrite bool - CanLead bool - Raw types.Log // Blockchain specific contextual infos + EnodeId string + Raw types.Log // Blockchain specific contextual infos } -// FilterNewNodeProposed is a free log retrieval operation binding the contract event 0xd630d8689250dadadf783ef2b5c310617046e2f16f9cddbb44e8d96801e3a347. +// FilterNewNodeProposed is a free log retrieval operation binding the contract event 0xe370df14cec622d932b6c03454042c48c2815c9f96d22ab2bdb2e7171d96eb00. // -// Solidity: e NewNodeProposed(_enodeId string, _canWrite bool, _canLead bool) +// Solidity: e NewNodeProposed(_enodeId string) func (_Permissions *PermissionsFilterer) FilterNewNodeProposed(opts *bind.FilterOpts) (*PermissionsNewNodeProposedIterator, error) { logs, sub, err := _Permissions.contract.FilterLogs(opts, "NewNodeProposed") @@ -500,9 +498,9 @@ func (_Permissions *PermissionsFilterer) FilterNewNodeProposed(opts *bind.Filter return &PermissionsNewNodeProposedIterator{contract: _Permissions.contract, event: "NewNodeProposed", logs: logs, sub: sub}, nil } -// WatchNewNodeProposed is a free log subscription operation binding the contract event 0xd630d8689250dadadf783ef2b5c310617046e2f16f9cddbb44e8d96801e3a347. +// WatchNewNodeProposed is a free log subscription operation binding the contract event 0xe370df14cec622d932b6c03454042c48c2815c9f96d22ab2bdb2e7171d96eb00. // -// Solidity: e NewNodeProposed(_enodeId string, _canWrite bool, _canLead bool) +// Solidity: e NewNodeProposed(_enodeId string) func (_Permissions *PermissionsFilterer) WatchNewNodeProposed(opts *bind.WatchOpts, sink chan<- *PermissionsNewNodeProposed) (event.Subscription, error) { logs, sub, err := _Permissions.contract.WatchLogs(opts, "NewNodeProposed") @@ -606,13 +604,16 @@ func (it *PermissionsNodeApprovedIterator) Close() error { // PermissionsNodeApproved represents a NodeApproved event raised by the Permissions contract. type PermissionsNodeApproved struct { - EnodeId string - Raw types.Log // Blockchain specific contextual infos + EnodeId string + IpAddrPort string + DiscPort string + RaftPort string + Raw types.Log // Blockchain specific contextual infos } -// FilterNodeApproved is a free log retrieval operation binding the contract event 0xc8f0c6e7f31c7ba4e6e29615ae2ab658fdda704c49912bb6118db07a4c36d478. +// FilterNodeApproved is a free log retrieval operation binding the contract event 0xc6d86deaa3b3cf7c374cfd405aae9f08571fce2bf6ccfe8f98a399cda8960a98. // -// Solidity: e NodeApproved(_enodeId string) +// Solidity: e NodeApproved(_enodeId string, _ipAddrPort string, _discPort string, _raftPort string) func (_Permissions *PermissionsFilterer) FilterNodeApproved(opts *bind.FilterOpts) (*PermissionsNodeApprovedIterator, error) { logs, sub, err := _Permissions.contract.FilterLogs(opts, "NodeApproved") @@ -622,9 +623,9 @@ func (_Permissions *PermissionsFilterer) FilterNodeApproved(opts *bind.FilterOpt return &PermissionsNodeApprovedIterator{contract: _Permissions.contract, event: "NodeApproved", logs: logs, sub: sub}, nil } -// WatchNodeApproved is a free log subscription operation binding the contract event 0xc8f0c6e7f31c7ba4e6e29615ae2ab658fdda704c49912bb6118db07a4c36d478. +// WatchNodeApproved is a free log subscription operation binding the contract event 0xc6d86deaa3b3cf7c374cfd405aae9f08571fce2bf6ccfe8f98a399cda8960a98. // -// Solidity: e NodeApproved(_enodeId string) +// Solidity: e NodeApproved(_enodeId string, _ipAddrPort string, _discPort string, _raftPort string) func (_Permissions *PermissionsFilterer) WatchNodeApproved(opts *bind.WatchOpts, sink chan<- *PermissionsNodeApproved) (event.Subscription, error) { logs, sub, err := _Permissions.contract.WatchLogs(opts, "NodeApproved") @@ -728,13 +729,16 @@ func (it *PermissionsNodeDeactivatedIterator) Close() error { // PermissionsNodeDeactivated represents a NodeDeactivated event raised by the Permissions contract. type PermissionsNodeDeactivated struct { - EnodeId string - Raw types.Log // Blockchain specific contextual infos + EnodeId string + IpAddrPort string + DiscPort string + RaftPort string + Raw types.Log // Blockchain specific contextual infos } -// FilterNodeDeactivated is a free log retrieval operation binding the contract event 0xb4551525dafbacbcbad53f3a1ad477e2de2428dcd5832ae46d8edacf8c2959d5. +// FilterNodeDeactivated is a free log retrieval operation binding the contract event 0xd5fa0ecdea15b332dd0a270c65234bc4aee212edf2ed62eb2fd182ef55ca98a1. // -// Solidity: e NodeDeactivated(_enodeId string) +// Solidity: e NodeDeactivated(_enodeId string, _ipAddrPort string, _discPort string, _raftPort string) func (_Permissions *PermissionsFilterer) FilterNodeDeactivated(opts *bind.FilterOpts) (*PermissionsNodeDeactivatedIterator, error) { logs, sub, err := _Permissions.contract.FilterLogs(opts, "NodeDeactivated") @@ -744,9 +748,9 @@ func (_Permissions *PermissionsFilterer) FilterNodeDeactivated(opts *bind.Filter return &PermissionsNodeDeactivatedIterator{contract: _Permissions.contract, event: "NodeDeactivated", logs: logs, sub: sub}, nil } -// WatchNodeDeactivated is a free log subscription operation binding the contract event 0xb4551525dafbacbcbad53f3a1ad477e2de2428dcd5832ae46d8edacf8c2959d5. +// WatchNodeDeactivated is a free log subscription operation binding the contract event 0xd5fa0ecdea15b332dd0a270c65234bc4aee212edf2ed62eb2fd182ef55ca98a1. // -// Solidity: e NodeDeactivated(_enodeId string) +// Solidity: e NodeDeactivated(_enodeId string, _ipAddrPort string, _discPort string, _raftPort string) func (_Permissions *PermissionsFilterer) WatchNodeDeactivated(opts *bind.WatchOpts, sink chan<- *PermissionsNodeDeactivated) (event.Subscription, error) { logs, sub, err := _Permissions.contract.WatchLogs(opts, "NodeDeactivated")