permissions: added functions for blacklisted node recovery.

This commit is contained in:
vsmk98 2019-08-01 11:10:50 +08:00
parent bce6c1566d
commit b74fc4d0c2
14 changed files with 366 additions and 7 deletions

View File

@ -44,6 +44,7 @@ const (
NodeApproved NodeApproved
NodeDeactivated NodeDeactivated
NodeBlackListed NodeBlackListed
NodeRecoveryInitiated
) )
type AcctStatus uint8 type AcctStatus uint8

View File

@ -830,6 +830,30 @@ web3._extend({
call: 'quorumPermission_updateAccountStatus', call: 'quorumPermission_updateAccountStatus',
params: 4, params: 4,
inputFormatter: [null, web3._extend.formatters.inputAddressFormatter,null,web3._extend.formatters.inputTransactionFormatter] inputFormatter: [null, web3._extend.formatters.inputAddressFormatter,null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'recoverBlackListedNode',
call: 'quorumPermission_recoverBlackListedNode',
params: 3,
inputFormatter: [null, null, web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'approveBlackListedNodeRecovery',
call: 'quorumPermission_approveBlackListedNodeRecovery',
params: 3,
inputFormatter: [null, null, web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'recoverBlackListedAccount',
call: 'quorumPermission_recoverBlackListedAccount',
params: 3,
inputFormatter: [null, web3._extend.formatters.inputAddressFormatter, web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'approveBlackListedAccountRecovery',
call: 'quorumPermission_approveBlackListedAccountRecovery',
params: 3,
inputFormatter: [null, web3._extend.formatters.inputAddressFormatter, web3._extend.formatters.inputTransactionFormatter]
}), }),
new web3._extend.Method({ new web3._extend.Method({
name: 'getOrgDetails', name: 'getOrgDetails',

View File

@ -42,6 +42,10 @@ const (
AddAccountToOrg AddAccountToOrg
ChangeAccountRole ChangeAccountRole
UpdateAccountStatus UpdateAccountStatus
InitiateNodeRecovery
InitiateAccountRecovery
ApproveNodeRecovery
ApproveAccountRecovery
) )
// OrgKeyAction represents an action in cluster contract // OrgKeyAction represents an action in cluster contract
@ -474,6 +478,86 @@ func (q *QuorumControlsAPI) UpdateAccountStatus(orgId string, acct common.Addres
return ExecSuccess.OpStatus() return ExecSuccess.OpStatus()
} }
func (q *QuorumControlsAPI) RecoverBlackListedNode(orgId string, enodeId string, txa ethapi.SendTxArgs) (string, error) {
pinterf, execStatus := q.initOp(txa)
if execStatus != ExecSuccess {
return execStatus.OpStatus()
}
args := txArgs{orgId: orgId, url: enodeId, txa: txa}
if execStatus := q.valRecoverNode(args, pinterf); execStatus != ExecSuccess {
return execStatus.OpStatus()
}
tx, err := pinterf.StartBlacklistedNodeRecovery(args.orgId, args.url)
if err != nil {
log.Error("Failed to execute permission action", "action", InitiateNodeRecovery, "err", err)
msg := fmt.Sprintf("failed to execute permissions action: %v", err)
return ExecStatus{false, msg}.OpStatus()
}
log.Debug("executed permission action", "action", InitiateNodeRecovery, "tx", tx)
return ExecSuccess.OpStatus()
}
func (q *QuorumControlsAPI) ApproveBlackListedNodeRecovery(orgId string, enodeId string, txa ethapi.SendTxArgs) (string, error) {
pinterf, execStatus := q.initOp(txa)
if execStatus != ExecSuccess {
return execStatus.OpStatus()
}
args := txArgs{orgId: orgId, url: enodeId, txa: txa}
if execStatus := q.valRecoverNode(args, pinterf); execStatus != ExecSuccess {
return execStatus.OpStatus()
}
//tx, err := pinterf.ApproveNodeRecovery(args.orgId, args.url)
//if err != nil {
// log.Error("Failed to execute permission action", "action", ApproveNodeRecovery, "err", err)
// msg := fmt.Sprintf("failed to execute permissions action: %v", err)
// return ExecStatus{false, msg}.OpStatus()
//}
//log.Debug("executed permission action", "action", ApproveNodeRecovery, "tx", tx)
return ExecSuccess.OpStatus()
}
func (q *QuorumControlsAPI) RecoverBlackListedAccount(orgId string, acctId common.Address, txa ethapi.SendTxArgs) (string, error) {
pinterf, execStatus := q.initOp(txa)
if execStatus != ExecSuccess {
return execStatus.OpStatus()
}
args := txArgs{orgId: orgId, acctId: acctId, txa: txa}
if execStatus := q.valRecoverAccount(args, pinterf); execStatus != ExecSuccess {
return execStatus.OpStatus()
}
//tx, err := pinterf.RecoverBlacklistedAccount(args.orgId, args.acctId)
//if err != nil {
// log.Error("Failed to execute permission action", "action", InitiateAccountRecovery, "err", err)
// msg := fmt.Sprintf("failed to execute permissions action: %v", err)
// return ExecStatus{false, msg}.OpStatus()
//}
//log.Debug("executed permission action", "action", InitiateAccountRecovery, "tx", tx)
return ExecSuccess.OpStatus()
}
func (q *QuorumControlsAPI) ApproveBlackListedAccountRecovery(orgId string, acctId common.Address, txa ethapi.SendTxArgs) (string, error) {
pinterf, execStatus := q.initOp(txa)
if execStatus != ExecSuccess {
return execStatus.OpStatus()
}
args := txArgs{orgId: orgId, acctId: acctId, txa: txa}
if execStatus := q.valRecoverAccount(args, pinterf); execStatus != ExecSuccess {
return execStatus.OpStatus()
}
//tx, err := pinterf.ApproveAccountRecovery(args.orgId, args.acctId)
//if err != nil {
// log.Error("Failed to execute permission action", "action", ApproveAccountRecovery, "err", err)
// msg := fmt.Sprintf("failed to execute permissions action: %v", err)
// return ExecStatus{false, msg}.OpStatus()
//}
//log.Debug("executed permission action", "action", ApproveAccountRecovery, "tx", tx)
return ExecSuccess.OpStatus()
}
// check if the account is network admin // check if the account is network admin
func (q *QuorumControlsAPI) isNetworkAdmin(account common.Address) bool { func (q *QuorumControlsAPI) isNetworkAdmin(account common.Address) bool {
ac := types.AcctInfoMap.GetAccount(account) ac := types.AcctInfoMap.GetAccount(account)
@ -943,6 +1027,32 @@ func (q *QuorumControlsAPI) valUpdateAccountStatus(args txArgs, pinterf *pbind.P
return ExecSuccess return ExecSuccess
} }
func (q *QuorumControlsAPI) valRecoverNode(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus {
// check if the caller is org admin
if !q.isNetworkAdmin(args.txa.From) {
return ErrNotNetworkAdmin
}
if q.checkPendingOp(q.permCtrl.permConfig.NwAdminOrg, pinterf) {
return ErrPendingApprovals
}
return ExecSuccess
}
func (q *QuorumControlsAPI) valRecoverAccount(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus {
// check if the caller is org admin
if !q.isNetworkAdmin(args.txa.From) {
return ErrNotNetworkAdmin
}
if q.checkPendingOp(q.permCtrl.permConfig.NwAdminOrg, pinterf) {
return ErrPendingApprovals
}
return ExecSuccess
}
// validateAccount validates the account and returns the wallet associated with that for signing the transaction // validateAccount validates the account and returns the wallet associated with that for signing the transaction
func (q *QuorumControlsAPI) validateAccount(from common.Address) (accounts.Wallet, error) { func (q *QuorumControlsAPI) validateAccount(from common.Address) (accounts.Wallet, error) {
acct := accounts.Account{Address: from} acct := accounts.Account{Address: from}

View File

@ -28,7 +28,7 @@ var (
) )
// NodeManagerABI is the input ABI used to generate the binding from. // NodeManagerABI is the input ABI used to generate the binding from.
const NodeManagerABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_action\",\"type\":\"uint256\"}],\"name\":\"updateNodeStatus\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"enodeId\",\"type\":\"string\"}],\"name\":\"getNodeDetails\",\"outputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_nodeStatus\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"addOrgNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"approveNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_nodeIndex\",\"type\":\"uint256\"}],\"name\":\"getNodeDetailsFromIndex\",\"outputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_nodeStatus\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"addNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getNumberOfNodes\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"addAdminNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_permUpgradable\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeBlacklisted\",\"type\":\"event\"}]" const NodeManagerABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_action\",\"type\":\"uint256\"}],\"name\":\"updateNodeStatus\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"enodeId\",\"type\":\"string\"}],\"name\":\"getNodeDetails\",\"outputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_nodeStatus\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"addOrgNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"approveNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_nodeIndex\",\"type\":\"uint256\"}],\"name\":\"getNodeDetailsFromIndex\",\"outputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_nodeStatus\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"addNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getNumberOfNodes\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"addAdminNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_permUpgradable\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeBlacklisted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeRecoveryInitiated\",\"type\":\"event\"}]"
// NodeManager is an auto generated Go binding around an Ethereum contract. // NodeManager is an auto generated Go binding around an Ethereum contract.
type NodeManager struct { type NodeManager struct {
@ -997,3 +997,126 @@ func (_NodeManager *NodeManagerFilterer) WatchNodeProposed(opts *bind.WatchOpts,
} }
}), nil }), nil
} }
// NodeManagerNodeRecoveryInitiatedIterator is returned from FilterNodeRecoveryInitiated and is used to iterate over the raw logs and unpacked data for NodeRecoveryInitiated events raised by the NodeManager contract.
type NodeManagerNodeRecoveryInitiatedIterator struct {
Event *NodeManagerNodeRecoveryInitiated // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *NodeManagerNodeRecoveryInitiatedIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(NodeManagerNodeRecoveryInitiated)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(NodeManagerNodeRecoveryInitiated)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *NodeManagerNodeRecoveryInitiatedIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *NodeManagerNodeRecoveryInitiatedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// NodeManagerNodeRecoveryInitiated represents a NodeRecoveryInitiated event raised by the NodeManager contract.
type NodeManagerNodeRecoveryInitiated struct {
EnodeId string
OrgId string
Raw types.Log // Blockchain specific contextual infos
}
// FilterNodeRecoveryInitiated is a free log retrieval operation binding the contract event 0xfd385c618a1e89d01fb9a21780846793e282e8bc0b60caf6ccb3e422d543fbfb.
//
// Solidity: e NodeRecoveryInitiated(_enodeId string, _orgId string)
func (_NodeManager *NodeManagerFilterer) FilterNodeRecoveryInitiated(opts *bind.FilterOpts) (*NodeManagerNodeRecoveryInitiatedIterator, error) {
logs, sub, err := _NodeManager.contract.FilterLogs(opts, "NodeRecoveryInitiated")
if err != nil {
return nil, err
}
return &NodeManagerNodeRecoveryInitiatedIterator{contract: _NodeManager.contract, event: "NodeRecoveryInitiated", logs: logs, sub: sub}, nil
}
// WatchNodeRecoveryInitiated is a free log subscription operation binding the contract event 0xfd385c618a1e89d01fb9a21780846793e282e8bc0b60caf6ccb3e422d543fbfb.
//
// Solidity: e NodeRecoveryInitiated(_enodeId string, _orgId string)
func (_NodeManager *NodeManagerFilterer) WatchNodeRecoveryInitiated(opts *bind.WatchOpts, sink chan<- *NodeManagerNodeRecoveryInitiated) (event.Subscription, error) {
logs, sub, err := _NodeManager.contract.WatchLogs(opts, "NodeRecoveryInitiated")
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(NodeManagerNodeRecoveryInitiated)
if err := _NodeManager.contract.UnpackLog(event, "NodeRecoveryInitiated", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}

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,8 @@ import "./PermissionsUpgradable.sol";
2 - Active 2 - Active
3 - Deactivated 3 - Deactivated
4 - Blacklisted 4 - Blacklisted
5 - Blacklisted node recovery initiated. Once approved the node
status will be updated to Active (2)
Once the node is blacklisted no further activity on the node is Once the node is blacklisted no further activity on the node is
possible. possible.
*/ */
@ -45,6 +47,10 @@ contract NodeManager {
// node permission events for node blacklist // node permission events for node blacklist
event NodeBlacklisted(string _enodeId, string _orgId); event NodeBlacklisted(string _enodeId, string _orgId);
// node permission events for initiating the recovery of blacklisted
// node
event NodeRecoveryInitiated(string _enodeId, string _orgId);
/** @notice confirms that the caller is the address of implementation /** @notice confirms that the caller is the address of implementation
contract contract
*/ */
@ -174,6 +180,8 @@ contract NodeManager {
1 - Suspend the node 1 - Suspend the node
2 - Revoke suspension of a suspended node 2 - Revoke suspension of a suspended node
3 - blacklist a node 3 - blacklist a node
4 - initiate the recovery of a blacklisted node
5 - blacklisted node recovery fully approved. mark to active
*/ */
function updateNodeStatus(string calldata _enodeId, string calldata _orgId, uint256 _action) external function updateNodeStatus(string calldata _enodeId, string calldata _orgId, uint256 _action) external
onlyImplementation onlyImplementation
@ -193,9 +201,14 @@ contract NodeManager {
nodeList[_getNodeIndex(_enodeId)].status = 2; nodeList[_getNodeIndex(_enodeId)].status = 2;
emit NodeActivated(_enodeId, _orgId); emit NodeActivated(_enodeId, _orgId);
} }
else { else if (_action == 3) {
nodeList[_getNodeIndex(_enodeId)].status = 4; nodeList[_getNodeIndex(_enodeId)].status = 4;
emit NodeBlacklisted(_enodeId, _orgId); emit NodeBlacklisted(_enodeId, _orgId);
} else if (_action == 4) {
// node should be in blacklisted state
require(_getNodeStatus(_enodeId) == 4, "operation cannot be performed");
nodeList[_getNodeIndex(_enodeId)].status = 5;
emit NodeRecoveryInitiated(_enodeId, _orgId);
} }
} }

View File

@ -409,6 +409,23 @@ contract PermissionsImplementation {
nodeManager.updateNodeStatus(_enodeId, _orgId, _action); nodeManager.updateNodeStatus(_enodeId, _orgId, _action);
} }
/** @notice function to initaite blacklisted nodes recovery. this can be
invoked by an network admin account only
* @param _orgId unique id of the organization to which the account belongs
* @param _enodeId full enode id being dded to the org
* @dev this function creates a voting record for other network admins to
approve the operation. The recovery is complete only after majority voting
*/
function startBlacklistedNodeRecovery(string calldata _orgId, string calldata _enodeId,
address _caller) external onlyInterface networkAdmin(_caller) {
// update the node status as recovery initiated. action for this is 4
nodeManager.updateNodeStatus(_enodeId, _orgId, 4);
// add a voting record with pending op of 5 which corresponds to blacklisted node
// recovery
voterManager.addVotingItem(adminOrg, _orgId, _enodeId, address(0), 5);
}
/** @notice function to fetch network boot status /** @notice function to fetch network boot status
* @return bool network boot status * @return bool network boot status
*/ */

View File

@ -199,6 +199,24 @@ contract PermissionsInterface {
permImplementation.updateNodeStatus(_orgId, _enodeId, _action, msg.sender); permImplementation.updateNodeStatus(_orgId, _enodeId, _action, msg.sender);
} }
/** @notice interface to initiate blacklisted node recovery
* @param _orgId unique id of the organization to which the account belongs
* @param _enodeId full enode id being dded to the org
*/
function startBlacklistedNodeRecovery(string calldata _orgId, string calldata _enodeId)
external {
permImplementation.startBlacklistedNodeRecovery(_orgId, _enodeId, msg.sender);
}
/** @notice interface to approve blacklisted node recoevry
* @param _orgId unique id of the organization to which the account belongs
* @param _enodeId full enode id being dded to the org
*/
// function approveBlacklistedNodeRecovery(string calldata _orgId, string calldata _enodeId)
// external {
// permImplementation.approveBlacklistedNodeRecovery(_orgId, _enodeId, msg.sender);
// }
/** @notice interface to fetch detail of any pending approval activities /** @notice interface to fetch detail of any pending approval activities
for network admin organization for network admin organization
* @param _orgId unique id of the organization to which the account belongs * @param _orgId unique id of the organization to which the account belongs

View File

@ -16,6 +16,7 @@ import "./PermissionsUpgradable.sol";
2 - Org suspension activity 2 - Org suspension activity
3 - Revoke of org suspension 3 - Revoke of org suspension
4 - Assigning admin role for a new account 4 - Assigning admin role for a new account
5 - Blacklisted node recovery
*/ */
contract VoterManager { contract VoterManager {
PermissionsUpgradable private permUpgradable; PermissionsUpgradable private permUpgradable;

View File

@ -1 +1 @@
[{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"},{"name":"_action","type":"uint256"}],"name":"updateNodeStatus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"enodeId","type":"string"}],"name":"getNodeDetails","outputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_nodeStatus","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"}],"name":"addOrgNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"}],"name":"approveNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeIndex","type":"uint256"}],"name":"getNodeDetailsFromIndex","outputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_nodeStatus","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"}],"name":"addNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getNumberOfNodes","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"}],"name":"addAdminNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_permUpgradable","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeDeactivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeBlacklisted","type":"event"}] [{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"},{"name":"_action","type":"uint256"}],"name":"updateNodeStatus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"enodeId","type":"string"}],"name":"getNodeDetails","outputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_nodeStatus","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"}],"name":"addOrgNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"}],"name":"approveNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeIndex","type":"uint256"}],"name":"getNodeDetailsFromIndex","outputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_nodeStatus","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"}],"name":"addNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getNumberOfNodes","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"}],"name":"addAdminNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_permUpgradable","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeDeactivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeBlacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeRecoveryInitiated","type":"event"}]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -366,12 +366,14 @@ func (p *PermissionCtrl) manageNodePermissions() {
chNodeDeactivated := make(chan *pbind.NodeManagerNodeDeactivated, 1) chNodeDeactivated := make(chan *pbind.NodeManagerNodeDeactivated, 1)
chNodeActivated := make(chan *pbind.NodeManagerNodeActivated, 1) chNodeActivated := make(chan *pbind.NodeManagerNodeActivated, 1)
chNodeBlacklisted := make(chan *pbind.NodeManagerNodeBlacklisted) chNodeBlacklisted := make(chan *pbind.NodeManagerNodeBlacklisted)
chNodeRecovery := make(chan *pbind.NodeManagerNodeRecoveryInitiated, 1)
var evtNodeApproved *pbind.NodeManagerNodeApproved var evtNodeApproved *pbind.NodeManagerNodeApproved
var evtNodeProposed *pbind.NodeManagerNodeProposed var evtNodeProposed *pbind.NodeManagerNodeProposed
var evtNodeDeactivated *pbind.NodeManagerNodeDeactivated var evtNodeDeactivated *pbind.NodeManagerNodeDeactivated
var evtNodeActivated *pbind.NodeManagerNodeActivated var evtNodeActivated *pbind.NodeManagerNodeActivated
var evtNodeBlacklisted *pbind.NodeManagerNodeBlacklisted var evtNodeBlacklisted *pbind.NodeManagerNodeBlacklisted
var evtNodeRecovery *pbind.NodeManagerNodeRecoveryInitiated
opts := &bind.WatchOpts{} opts := &bind.WatchOpts{}
var blockNumber uint64 = 1 var blockNumber uint64 = 1
@ -396,6 +398,10 @@ func (p *PermissionCtrl) manageNodePermissions() {
log.Info("Failed NodeBlacklisting", "error", err) log.Info("Failed NodeBlacklisting", "error", err)
} }
if _, err := p.permNode.NodeManagerFilterer.WatchNodeRecoveryInitiated(opts, chNodeRecovery); err != nil {
log.Info("Failed NodeBlacklisting", "error", err)
}
for { for {
select { select {
case evtNodeApproved = <-chNodeApproved: case evtNodeApproved = <-chNodeApproved:
@ -417,6 +423,10 @@ func (p *PermissionCtrl) manageNodePermissions() {
p.updatePermissionedNodes(evtNodeBlacklisted.EnodeId, NodeDelete) p.updatePermissionedNodes(evtNodeBlacklisted.EnodeId, NodeDelete)
p.updateDisallowedNodes(evtNodeBlacklisted.EnodeId) p.updateDisallowedNodes(evtNodeBlacklisted.EnodeId)
types.NodeInfoMap.UpsertNode(evtNodeBlacklisted.OrgId, evtNodeBlacklisted.EnodeId, types.NodeBlackListed) types.NodeInfoMap.UpsertNode(evtNodeBlacklisted.OrgId, evtNodeBlacklisted.EnodeId, types.NodeBlackListed)
case evtNodeRecovery = <-chNodeRecovery:
types.NodeInfoMap.UpsertNode(evtNodeRecovery.OrgId, evtNodeRecovery.EnodeId, types.NodeRecoveryInitiated)
case <-p.nodeChan: case <-p.nodeChan:
log.Info("quit node contract watch") log.Info("quit node contract watch")
return return