permissions: added function to approve recovery of blacklisted node. changes to deleted record from disallowed-nodes.json once recovery is complete

This commit is contained in:
vsmk98 2019-08-01 15:19:40 +08:00
parent b74fc4d0c2
commit 755b586428
11 changed files with 288 additions and 95 deletions

View File

@ -485,7 +485,7 @@ func (q *QuorumControlsAPI) RecoverBlackListedNode(orgId string, enodeId string,
}
args := txArgs{orgId: orgId, url: enodeId, txa: txa}
if execStatus := q.valRecoverNode(args, pinterf); execStatus != ExecSuccess {
if execStatus := q.valRecoverNode(args, pinterf, InitiateNodeRecovery); execStatus != ExecSuccess {
return execStatus.OpStatus()
}
tx, err := pinterf.StartBlacklistedNodeRecovery(args.orgId, args.url)
@ -505,16 +505,16 @@ func (q *QuorumControlsAPI) ApproveBlackListedNodeRecovery(orgId string, enodeId
}
args := txArgs{orgId: orgId, url: enodeId, txa: txa}
if execStatus := q.valRecoverNode(args, pinterf); execStatus != ExecSuccess {
if execStatus := q.valRecoverNode(args, pinterf, ApproveNodeRecovery); 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)
tx, err := pinterf.ApproveBlacklistedNodeRecovery(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()
}
@ -1027,13 +1027,13 @@ func (q *QuorumControlsAPI) valUpdateAccountStatus(args txArgs, pinterf *pbind.P
return ExecSuccess
}
func (q *QuorumControlsAPI) valRecoverNode(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus {
func (q *QuorumControlsAPI) valRecoverNode(args txArgs, pinterf *pbind.PermInterfaceSession, action PermAction) ExecStatus {
// check if the caller is org admin
if !q.isNetworkAdmin(args.txa.From) {
return ErrNotNetworkAdmin
}
if q.checkPendingOp(q.permCtrl.permConfig.NwAdminOrg, pinterf) {
if action == InitiateNodeRecovery && q.checkPendingOp(q.permCtrl.permConfig.NwAdminOrg, pinterf) {
return ErrPendingApprovals
}

View File

@ -28,7 +28,7 @@ var (
)
// 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\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeRecoveryInitiated\",\"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\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeRecoveryCompleted\",\"type\":\"event\"}]"
// NodeManager is an auto generated Go binding around an Ethereum contract.
type NodeManager struct {
@ -998,6 +998,129 @@ func (_NodeManager *NodeManagerFilterer) WatchNodeProposed(opts *bind.WatchOpts,
}), nil
}
// NodeManagerNodeRecoveryCompletedIterator is returned from FilterNodeRecoveryCompleted and is used to iterate over the raw logs and unpacked data for NodeRecoveryCompleted events raised by the NodeManager contract.
type NodeManagerNodeRecoveryCompletedIterator struct {
Event *NodeManagerNodeRecoveryCompleted // 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 *NodeManagerNodeRecoveryCompletedIterator) 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(NodeManagerNodeRecoveryCompleted)
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(NodeManagerNodeRecoveryCompleted)
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 *NodeManagerNodeRecoveryCompletedIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *NodeManagerNodeRecoveryCompletedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// NodeManagerNodeRecoveryCompleted represents a NodeRecoveryCompleted event raised by the NodeManager contract.
type NodeManagerNodeRecoveryCompleted struct {
EnodeId string
OrgId string
Raw types.Log // Blockchain specific contextual infos
}
// FilterNodeRecoveryCompleted is a free log retrieval operation binding the contract event 0x787d7bc525e7c4658c64e3e456d974a1be21cc196e8162a4bf1337a12cb38dac.
//
// Solidity: e NodeRecoveryCompleted(_enodeId string, _orgId string)
func (_NodeManager *NodeManagerFilterer) FilterNodeRecoveryCompleted(opts *bind.FilterOpts) (*NodeManagerNodeRecoveryCompletedIterator, error) {
logs, sub, err := _NodeManager.contract.FilterLogs(opts, "NodeRecoveryCompleted")
if err != nil {
return nil, err
}
return &NodeManagerNodeRecoveryCompletedIterator{contract: _NodeManager.contract, event: "NodeRecoveryCompleted", logs: logs, sub: sub}, nil
}
// WatchNodeRecoveryCompleted is a free log subscription operation binding the contract event 0x787d7bc525e7c4658c64e3e456d974a1be21cc196e8162a4bf1337a12cb38dac.
//
// Solidity: e NodeRecoveryCompleted(_enodeId string, _orgId string)
func (_NodeManager *NodeManagerFilterer) WatchNodeRecoveryCompleted(opts *bind.WatchOpts, sink chan<- *NodeManagerNodeRecoveryCompleted) (event.Subscription, error) {
logs, sub, err := _NodeManager.contract.WatchLogs(opts, "NodeRecoveryCompleted")
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(NodeManagerNodeRecoveryCompleted)
if err := _NodeManager.contract.UnpackLog(event, "NodeRecoveryCompleted", 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
}
// 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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -51,6 +51,10 @@ contract NodeManager {
// node
event NodeRecoveryInitiated(string _enodeId, string _orgId);
// node permission events for completing the recovery of blacklisted
// node
event NodeRecoveryCompleted(string _enodeId, string _orgId);
/** @notice confirms that the caller is the address of implementation
contract
*/
@ -188,7 +192,7 @@ contract NodeManager {
enodeExists(_enodeId) {
// node should belong to the org
require(_checkOrg(_enodeId, _orgId), "enode id does not belong to the passed org");
require((_action == 1 || _action == 2 || _action == 3),
require((_action == 1 || _action == 2 || _action == 3 || _action == 4 || _action == 5),
"invalid operation. wrong action passed");
if (_action == 1) {
@ -209,6 +213,11 @@ contract NodeManager {
require(_getNodeStatus(_enodeId) == 4, "operation cannot be performed");
nodeList[_getNodeIndex(_enodeId)].status = 5;
emit NodeRecoveryInitiated(_enodeId, _orgId);
} else {
// node should be in initiated recovery state
require(_getNodeStatus(_enodeId) == 5, "operation cannot be performed");
nodeList[_getNodeIndex(_enodeId)].status = 2;
emit NodeRecoveryCompleted(_enodeId, _orgId);
}
}

View File

@ -199,7 +199,7 @@ contract PermissionsImplementation {
networkBootStatus(false)
returns (bool){
networkBoot = true;
emit PermissionsInitialized(networkBoot);
// emit PermissionsInitialized(networkBoot);
return networkBoot;
}
@ -426,6 +426,23 @@ contract PermissionsImplementation {
voterManager.addVotingItem(adminOrg, _orgId, _enodeId, address(0), 5);
}
/** @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 approveBlacklistedNodeRecovery(string calldata _orgId, string calldata _enodeId,
address _caller) external onlyInterface networkAdmin(_caller) {
// check if majority votes are received. pending op type is passed as 5
// which stands for black listed node recovery
if ((processVote(adminOrg, _caller, 5))) {
// update the node back to active
nodeManager.updateNodeStatus(_enodeId, _orgId, 5);
}
}
/** @notice function to fetch network boot status
* @return bool network boot status
*/

View File

@ -212,10 +212,10 @@ contract PermissionsInterface {
* @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);
// }
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
for network admin organization

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"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeRecoveryInitiated","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"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeRecoveryCompleted","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,14 +366,16 @@ func (p *PermissionCtrl) manageNodePermissions() {
chNodeDeactivated := make(chan *pbind.NodeManagerNodeDeactivated, 1)
chNodeActivated := make(chan *pbind.NodeManagerNodeActivated, 1)
chNodeBlacklisted := make(chan *pbind.NodeManagerNodeBlacklisted)
chNodeRecovery := make(chan *pbind.NodeManagerNodeRecoveryInitiated, 1)
chNodeRecoveryInit := make(chan *pbind.NodeManagerNodeRecoveryInitiated, 1)
chNodeRecoveryDone := make(chan *pbind.NodeManagerNodeRecoveryCompleted, 1)
var evtNodeApproved *pbind.NodeManagerNodeApproved
var evtNodeProposed *pbind.NodeManagerNodeProposed
var evtNodeDeactivated *pbind.NodeManagerNodeDeactivated
var evtNodeActivated *pbind.NodeManagerNodeActivated
var evtNodeBlacklisted *pbind.NodeManagerNodeBlacklisted
var evtNodeRecovery *pbind.NodeManagerNodeRecoveryInitiated
var evtNodeRecoveryInit *pbind.NodeManagerNodeRecoveryInitiated
var evtNodeRecoveryDone *pbind.NodeManagerNodeRecoveryCompleted
opts := &bind.WatchOpts{}
var blockNumber uint64 = 1
@ -398,8 +400,12 @@ func (p *PermissionCtrl) manageNodePermissions() {
log.Info("Failed NodeBlacklisting", "error", err)
}
if _, err := p.permNode.NodeManagerFilterer.WatchNodeRecoveryInitiated(opts, chNodeRecovery); err != nil {
log.Info("Failed NodeBlacklisting", "error", err)
if _, err := p.permNode.NodeManagerFilterer.WatchNodeRecoveryInitiated(opts, chNodeRecoveryInit); err != nil {
log.Info("Failed NodeRecoveryInitiated", "error", err)
}
if _, err := p.permNode.NodeManagerFilterer.WatchNodeRecoveryCompleted(opts, chNodeRecoveryDone); err != nil {
log.Info("Failed NodeRecoveryCompleted", "error", err)
}
for {
@ -421,11 +427,16 @@ func (p *PermissionCtrl) manageNodePermissions() {
case evtNodeBlacklisted = <-chNodeBlacklisted:
p.updatePermissionedNodes(evtNodeBlacklisted.EnodeId, NodeDelete)
p.updateDisallowedNodes(evtNodeBlacklisted.EnodeId)
p.updateDisallowedNodes(evtNodeBlacklisted.EnodeId, NodeAdd)
types.NodeInfoMap.UpsertNode(evtNodeBlacklisted.OrgId, evtNodeBlacklisted.EnodeId, types.NodeBlackListed)
case evtNodeRecovery = <-chNodeRecovery:
types.NodeInfoMap.UpsertNode(evtNodeRecovery.OrgId, evtNodeRecovery.EnodeId, types.NodeRecoveryInitiated)
case evtNodeRecoveryInit = <-chNodeRecoveryInit:
types.NodeInfoMap.UpsertNode(evtNodeRecoveryInit.OrgId, evtNodeRecoveryInit.EnodeId, types.NodeRecoveryInitiated)
case evtNodeRecoveryDone = <-chNodeRecoveryDone:
types.NodeInfoMap.UpsertNode(evtNodeRecoveryDone.OrgId, evtNodeRecoveryDone.EnodeId, types.NodeApproved)
p.updateDisallowedNodes(evtNodeRecoveryDone.EnodeId, NodeDelete)
p.updatePermissionedNodes(evtNodeRecoveryDone.EnodeId, NodeAdd)
case <-p.nodeChan:
log.Info("quit node contract watch")
@ -434,6 +445,54 @@ func (p *PermissionCtrl) manageNodePermissions() {
}
}
// adds or deletes and entry from a given file
func (p *PermissionCtrl) updateFile(fileName, enodeId string, operation NodeOperation, createFile bool) {
// Load the nodes from the config file
var nodeList []string
index := 0
// if createFile is false means the file is already existing. read the file
if !createFile {
blob, err := ioutil.ReadFile(fileName)
if err != nil && !createFile {
log.Error("Failed to access the file", "fileName", fileName, "err", err)
return
}
if err := json.Unmarshal(blob, &nodeList); err != nil {
log.Error("Failed to load nodes list from file", "fileName", fileName, "err", err)
return
}
// logic to update the permissioned-nodes.json file based on action
recExists := false
for i, eid := range nodeList {
if eid == enodeId {
index = i
recExists = true
break
}
}
if (operation == NodeAdd && recExists) || (operation == NodeDelete && !recExists) {
return
}
}
if operation == NodeAdd {
nodeList = append(nodeList, enodeId)
} else {
nodeList = append(nodeList[:index], nodeList[index+1:]...)
p.disconnectNode(enodeId)
}
blob, _ := json.Marshal(nodeList)
p.mux.Lock()
defer p.mux.Unlock()
if err := ioutil.WriteFile(fileName, blob, 0644); err != nil {
log.Error("Error writing new node info to file", "fileName", fileName, "err", err)
}
}
// updates node information in the permissioned-nodes.json file based on node
// management activities in smart contract
func (p *PermissionCtrl) updatePermissionedNodes(enodeId string, operation NodeOperation) {
@ -444,53 +503,15 @@ func (p *PermissionCtrl) updatePermissionedNodes(enodeId string, operation NodeO
log.Error("Read Error for permissioned-nodes.json file. This is because 'permissioned' flag is specified but no permissioned-nodes.json file is present", "err", err)
return
}
// Load the nodes from the config file
blob, err := ioutil.ReadFile(path)
if err != nil {
log.Error("updatePermissionedNodes: Failed to access permissioned-nodes.json", "err", err)
return
}
var nodeList []string
if err := json.Unmarshal(blob, &nodeList); err != nil {
log.Error("updatePermissionedNodes: Failed to load nodes list", "err", err)
return
}
// logic to update the permissioned-nodes.json file based on action
index := 0
recExists := false
for i, eid := range nodeList {
if eid == enodeId {
index = i
recExists = true
break
}
}
if (operation == NodeAdd && recExists) || (operation == NodeDelete && !recExists) {
return
}
if operation == NodeAdd {
nodeList = append(nodeList, enodeId)
} else {
nodeList = append(nodeList[:index], nodeList[index+1:]...)
p.disconnectNode(enodeId)
}
blob, _ = json.Marshal(nodeList)
p.mux.Lock()
defer p.mux.Unlock()
if err := ioutil.WriteFile(path, blob, 0644); err != nil {
log.Error("updatePermissionedNodes: Error writing new node info to file", "err", err)
}
p.updateFile(path, enodeId, operation, false)
}
//this function populates the black listed node information into the disallowed-nodes.json file
func (p *PermissionCtrl) updateDisallowedNodes(url string) {
func (p *PermissionCtrl) updateDisallowedNodes(url string, operation NodeOperation) {
log.Debug("updateDisallowedNodes", "DataDir", p.dataDir, "file", params.BLACKLIST_CONFIG)
fileExisted := true
fileExists := true
path := filepath.Join(p.dataDir, params.BLACKLIST_CONFIG)
// Check if the file is existing. If the file is not existing create the file
if _, err := os.Stat(path); err != nil {
@ -499,34 +520,15 @@ func (p *PermissionCtrl) updateDisallowedNodes(url string) {
log.Error("Failed to create disallowed-nodes.json file", "err", err)
return
}
fileExisted = false
fileExists = false
}
nodelist := []string{}
// Load the nodes from the config file
if fileExisted == true {
blob, err := ioutil.ReadFile(path)
if err != nil {
log.Error("updateDisallowedNodes Failed to access disallowed-nodes.json", "err", err)
return
}
if blob != nil {
if err := json.Unmarshal(blob, &nodelist); err != nil {
log.Error("updateDisallowedNodes: Failed to load nodes list", "err", err)
return
}
}
if fileExists {
p.updateFile(path, url, operation, false)
} else {
p.updateFile(path, url, operation, true)
}
nodelist = append(nodelist, url)
blob, _ := json.Marshal(nodelist)
p.mux.Lock()
defer p.mux.Unlock()
if err := ioutil.WriteFile(path, blob, 0644); err != nil {
log.Error("updateDisallowedNodes: Error writing new node info to file", "err", err)
}
// Disconnect the peer if it is already connected
p.disconnectNode(url)
}