mirror of https://github.com/poanetwork/quorum.git
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:
parent
b74fc4d0c2
commit
755b586428
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue