Skip to content

Commit

Permalink
Implement update node operators in capability registry (#12991)
Browse files Browse the repository at this point in the history
* implement update node operators in capability registry

* address PR feedback

* cache owner call

* Validate config on NewApplication (#12997)

* validate config on new application spawn

* Add changeset

* Check config only in the rebroadcast-transactions command

* Configurable Mercury transmitter parameters (#12680)

* Configurable Mercury transmitter parameters

* Changeset

* Remove commented code

* add tag

* Rename

* LogPoller CLI command to resolve reorg greater than finality depth (#12867)

* find lca and remove block after CLI

* fix sort.Find typo

* make RemoveBlocks local cmd

* tests

* added changeset

* added tags to the changeset

* fixed tests

* make cmds, vars cases consistent

* Fix Node Migration Test Check For Versions (#12982)

* fix: prevent query syntax error if allowlist is empty (#12912)

Co-authored-by: Morgan Kuphal <[email protected]>

* Update wrappers

* Formatting

---------

Co-authored-by: george-dorin <[email protected]>
Co-authored-by: Sam <[email protected]>
Co-authored-by: Dmytro Haidashenko <[email protected]>
Co-authored-by: Tate <[email protected]>
Co-authored-by: Gabriel Paradiso <[email protected]>
Co-authored-by: Morgan Kuphal <[email protected]>
Co-authored-by: DeividasK <[email protected]>
  • Loading branch information
8 people authored Apr 29, 2024
1 parent 0a37c0e commit 9293126
Show file tree
Hide file tree
Showing 6 changed files with 268 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/early-paws-end.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

generate gethwrappers for updating node operators in capability registry #internal
5 changes: 5 additions & 0 deletions contracts/.changeset/lucky-bugs-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@chainlink/contracts": patch
---

Add function to update node operator'
40 changes: 40 additions & 0 deletions contracts/src/v0.8/keystone/CapabilityRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface {
address configurationContract;
}

/// @notice This error is thrown when a caller is not allowed
/// to execute the transaction
error AccessForbidden();

/// @notice This error is thrown when there is a mismatch between
/// array arguments
/// @param lengthOne The length of the first array argument
/// @param lengthTwo The length of the second array argument
error LengthMismatch(uint256 lengthOne, uint256 lengthTwo);

/// @notice This error is thrown when trying to set a node operator's
/// admin address to the zero address
error InvalidNodeOperatorAdmin();
Expand All @@ -81,6 +91,12 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface {
/// @param nodeOperatorId The ID of the node operator that was removed
event NodeOperatorRemoved(uint256 nodeOperatorId);

/// @notice This event is emitted when a node operator is updated
/// @param nodeOperatorId The ID of the node operator that was updated
/// @param admin The address of the node operator's admin
/// @param name The node operator's human readable name
event NodeOperatorUpdated(uint256 nodeOperatorId, address indexed admin, string name);

/// @notice This event is emitted when a new capability is added
/// @param capabilityId The ID of the newly added capability
event CapabilityAdded(bytes32 indexed capabilityId);
Expand Down Expand Up @@ -122,6 +138,30 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface {
}
}

/// @notice Updates a node operator
/// @param nodeOperatorIds The ID of the node operator being updated
function updateNodeOperators(uint256[] calldata nodeOperatorIds, NodeOperator[] calldata nodeOperators) external {
if (nodeOperatorIds.length != nodeOperators.length)
revert LengthMismatch(nodeOperatorIds.length, nodeOperators.length);

address owner = owner();
for (uint256 i; i < nodeOperatorIds.length; ++i) {
uint256 nodeOperatorId = nodeOperatorIds[i];
NodeOperator memory nodeOperator = nodeOperators[i];
if (nodeOperator.admin == address(0)) revert InvalidNodeOperatorAdmin();
if (msg.sender != nodeOperator.admin && msg.sender != owner) revert AccessForbidden();

if (
s_nodeOperators[nodeOperatorId].admin != nodeOperator.admin ||
keccak256(abi.encode(s_nodeOperators[nodeOperatorId].name)) != keccak256(abi.encode(nodeOperator.name))
) {
s_nodeOperators[nodeOperatorId].admin = nodeOperator.admin;
s_nodeOperators[nodeOperatorId].name = nodeOperator.name;
emit NodeOperatorUpdated(nodeOperatorId, nodeOperator.admin, nodeOperator.name);
}
}
}

/// @notice Gets a node operator's data
/// @param nodeOperatorId The ID of the node operator to query for
/// @return NodeOperator The node operator data
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {BaseTest} from "./BaseTest.t.sol";
import {CapabilityRegistry} from "../CapabilityRegistry.sol";

contract CapabilityRegistry_UpdateNodeOperatorTest is BaseTest {
event NodeOperatorUpdated(uint256 nodeOperatorId, address indexed admin, string name);

uint256 private constant TEST_NODE_OPERATOR_ID = 0;
address private constant NEW_NODE_OPERATOR_ADMIN = address(3);
string private constant NEW_NODE_OPERATOR_NAME = "new-node-operator";

function setUp() public override {
BaseTest.setUp();
changePrank(ADMIN);
s_capabilityRegistry.addNodeOperators(_getNodeOperators());
}

function test_RevertWhen_CalledByNonAdminAndNonOwner() public {
changePrank(STRANGER);
vm.expectRevert(CapabilityRegistry.AccessForbidden.selector);

CapabilityRegistry.NodeOperator[] memory nodeOperators = new CapabilityRegistry.NodeOperator[](1);
nodeOperators[0] = CapabilityRegistry.NodeOperator({admin: NEW_NODE_OPERATOR_ADMIN, name: NEW_NODE_OPERATOR_NAME});

uint256[] memory nodeOperatorIds = new uint256[](1);
nodeOperatorIds[0] = TEST_NODE_OPERATOR_ID;
s_capabilityRegistry.updateNodeOperators(nodeOperatorIds, nodeOperators);
}

function test_RevertWhen_NodeOperatorAdminIsZeroAddress() public {
changePrank(ADMIN);
vm.expectRevert(CapabilityRegistry.InvalidNodeOperatorAdmin.selector);
CapabilityRegistry.NodeOperator[] memory nodeOperators = new CapabilityRegistry.NodeOperator[](1);
nodeOperators[0] = CapabilityRegistry.NodeOperator({admin: address(0), name: NEW_NODE_OPERATOR_NAME});

uint256[] memory nodeOperatorIds = new uint256[](1);
nodeOperatorIds[0] = TEST_NODE_OPERATOR_ID;
s_capabilityRegistry.updateNodeOperators(nodeOperatorIds, nodeOperators);
}

function test_UpdatesNodeOperator() public {
changePrank(ADMIN);

CapabilityRegistry.NodeOperator[] memory nodeOperators = new CapabilityRegistry.NodeOperator[](1);
nodeOperators[0] = CapabilityRegistry.NodeOperator({admin: NEW_NODE_OPERATOR_ADMIN, name: NEW_NODE_OPERATOR_NAME});

uint256[] memory nodeOperatorIds = new uint256[](1);
nodeOperatorIds[0] = TEST_NODE_OPERATOR_ID;

vm.expectEmit(true, true, true, true, address(s_capabilityRegistry));
emit NodeOperatorUpdated(TEST_NODE_OPERATOR_ID, NEW_NODE_OPERATOR_ADMIN, NEW_NODE_OPERATOR_NAME);
s_capabilityRegistry.updateNodeOperators(nodeOperatorIds, nodeOperators);

CapabilityRegistry.NodeOperator memory nodeOperator = s_capabilityRegistry.getNodeOperator(0);
assertEq(nodeOperator.admin, NEW_NODE_OPERATOR_ADMIN);
assertEq(nodeOperator.name, NEW_NODE_OPERATOR_NAME);
}
}
Loading

0 comments on commit 9293126

Please sign in to comment.