Skip to content

Commit

Permalink
new view function added to get base operators (#280)
Browse files Browse the repository at this point in the history
gamma has a few token owners on the base NodeOperatorFacet, who are not
on ds.operators. This is no longer possible and omega has no such token
owners. this means that using the base NodeOperatorFacet token owners as
a proxy to base operators is prone to creating confusion. this is why
gamma is reporting a high number of base operators with status =
Exiting, since their status is set to 0 by default. this PR introduces
`INodeOperator.getOperators` to standardize how we obtain actual node
operator addresses on base.

Next steps:
 - ✅ Gamma proposal 
- Deploy to gamma
- ✅ Update BaseRegistry.getOperators() to use the interface directly,
instead of using the token owner workaround
- Update the `river_network.total_operators_on_base` metric to exclude
operators of status 0 = Exiting.
- Keep fetching nodes on base for all operators, regardless of their
status. This way we can be aware of nodes on base whose operators have
status = Exiting for real - instead of those who appear as Exiting just
because they are token owners who are not on ds.operators.
- Deploy to omega
  • Loading branch information
mechanical-turk authored Jun 26, 2024
1 parent a8a466a commit 082af0a
Show file tree
Hide file tree
Showing 23 changed files with 259 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ contract DeployNodeOperator is Deployer, FacetHelper {
addSelector(NodeOperatorFacet.getCommissionRate.selector);
addSelector(NodeOperatorFacet.setClaimAddressForOperator.selector);
addSelector(NodeOperatorFacet.getClaimAddressForOperator.selector);
addSelector(NodeOperatorFacet.getOperators.selector);
}

function initializer() public pure override returns (bytes4) {
Expand Down
2 changes: 2 additions & 0 deletions contracts/src/base/registry/facets/operator/INodeOperator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ interface INodeOperator is INodeOperatorBase {
address operator
) external view returns (address);

function getOperators() external view returns (address[] memory);

// =============================================================
// Commission
// =============================================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ contract NodeOperatorFacet is INodeOperator, OwnableBase, ERC721ABase, Facet {
return NodeOperatorStorage.layout().claimerByOperator[operator];
}

function getOperators() external view returns (address[] memory) {
NodeOperatorStorage.Layout storage ds = NodeOperatorStorage.layout();
return ds.operators.values();
}

// =============================================================
// Commission
// =============================================================
Expand Down
24 changes: 24 additions & 0 deletions contracts/test/base/registry/NodeOperator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,30 @@ contract NodeOperatorFacetTest is
);
}

function test_getOperatorsAfterRegisterOperator(
address randomOperator1,
address randomOperator2
) public {
vm.assume(randomOperator1 != address(0));
vm.assume(randomOperator2 != address(0));
vm.assume(randomOperator1 != randomOperator2);
vm.assume(!nodeOperator.isOperator(randomOperator1));
vm.assume(!nodeOperator.isOperator(randomOperator2));
address[] memory baseOperators = nodeOperator.getOperators();
assertEq(baseOperators.length, 0);
vm.prank(randomOperator1);
nodeOperator.registerOperator(randomOperator1);
baseOperators = nodeOperator.getOperators();
assertEq(baseOperators.length, 1);
assertEq(baseOperators[0], randomOperator1);
vm.prank(randomOperator2);
nodeOperator.registerOperator(randomOperator2);
baseOperators = nodeOperator.getOperators();
assertEq(baseOperators.length, 2);
assertEq(baseOperators[0], randomOperator1);
assertEq(baseOperators[1], randomOperator2);
}

// =============================================================
// isOperator
// =============================================================
Expand Down
35 changes: 33 additions & 2 deletions core/xchain/contracts/dev/mock_entitlement_checker.go

Large diffs are not rendered by default.

35 changes: 33 additions & 2 deletions core/xchain/contracts/v3/mock_entitlement_checker.go

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions packages/generated/dev/abis/INodeOperator.abi.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@
],
"stateMutability": "view"
},
{
"type": "function",
"name": "getOperators",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address[]",
"internalType": "address[]"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "isOperator",
Expand Down
13 changes: 13 additions & 0 deletions packages/generated/dev/abis/INodeOperator.abi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@ export default [
],
"stateMutability": "view"
},
{
"type": "function",
"name": "getOperators",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address[]",
"internalType": "address[]"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "isOperator",
Expand Down
2 changes: 1 addition & 1 deletion packages/generated/dev/abis/INodeOperator.json

Large diffs are not rendered by default.

19 changes: 16 additions & 3 deletions packages/generated/dev/abis/INodeOperator.metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,19 @@
}
]
},
{
"inputs": [],
"stateMutability": "view",
"type": "function",
"name": "getOperators",
"outputs": [
{
"internalType": "address[]",
"name": "",
"type": "address[]"
}
]
},
{
"inputs": [
{
Expand Down Expand Up @@ -324,10 +337,10 @@
},
"sources": {
"contracts/src/base/registry/facets/operator/INodeOperator.sol": {
"keccak256": "0x51fb272223040fd0ecf38e6ca021169fd6fe29dca4d4cf7bd65a209c236e6ab5",
"keccak256": "0x3a3bcc633851dc36fd914ce9ba3c7ecaecaba96ff9533c52444a5d466721cb56",
"urls": [
"bzz-raw://1107dd9cc7f0c9ad4ea64a8b3a9e7d362f13061b25943cf2fb7a8e4b3eac6024",
"dweb:/ipfs/QmTbfwqkMonebKZPXhZbCwssbo91A4SkDvmLVRapae4i8R"
"bzz-raw://a3d71ec4e6e14b5ed9f2a067c9ccde4d94efc72d90b02ef2f9d659a156576b74",
"dweb:/ipfs/QmXk7qqcE1poxX5yfkRJpcyqeiMdkwexYTKF96CCHwX9fs"
],
"license": "MIT"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/generated/dev/abis/INodeOperatorBase.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions packages/generated/dev/abis/INodeOperatorBase.metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,10 @@
},
"sources": {
"contracts/src/base/registry/facets/operator/INodeOperator.sol": {
"keccak256": "0x51fb272223040fd0ecf38e6ca021169fd6fe29dca4d4cf7bd65a209c236e6ab5",
"keccak256": "0x3a3bcc633851dc36fd914ce9ba3c7ecaecaba96ff9533c52444a5d466721cb56",
"urls": [
"bzz-raw://1107dd9cc7f0c9ad4ea64a8b3a9e7d362f13061b25943cf2fb7a8e4b3eac6024",
"dweb:/ipfs/QmTbfwqkMonebKZPXhZbCwssbo91A4SkDvmLVRapae4i8R"
"bzz-raw://a3d71ec4e6e14b5ed9f2a067c9ccde4d94efc72d90b02ef2f9d659a156576b74",
"dweb:/ipfs/QmXk7qqcE1poxX5yfkRJpcyqeiMdkwexYTKF96CCHwX9fs"
],
"license": "MIT"
},
Expand Down
20 changes: 20 additions & 0 deletions packages/generated/dev/typings/INodeOperator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export interface INodeOperatorInterface extends utils.Interface {
"getClaimAddressForOperator(address)": FunctionFragment;
"getCommissionRate(address)": FunctionFragment;
"getOperatorStatus(address)": FunctionFragment;
"getOperators()": FunctionFragment;
"isOperator(address)": FunctionFragment;
"registerOperator(address)": FunctionFragment;
"setClaimAddressForOperator(address,address)": FunctionFragment;
Expand All @@ -44,6 +45,7 @@ export interface INodeOperatorInterface extends utils.Interface {
| "getClaimAddressForOperator"
| "getCommissionRate"
| "getOperatorStatus"
| "getOperators"
| "isOperator"
| "registerOperator"
| "setClaimAddressForOperator"
Expand All @@ -63,6 +65,10 @@ export interface INodeOperatorInterface extends utils.Interface {
functionFragment: "getOperatorStatus",
values: [PromiseOrValue<string>]
): string;
encodeFunctionData(
functionFragment: "getOperators",
values?: undefined
): string;
encodeFunctionData(
functionFragment: "isOperator",
values: [PromiseOrValue<string>]
Expand Down Expand Up @@ -96,6 +102,10 @@ export interface INodeOperatorInterface extends utils.Interface {
functionFragment: "getOperatorStatus",
data: BytesLike
): Result;
decodeFunctionResult(
functionFragment: "getOperators",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "isOperator", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "registerOperator",
Expand Down Expand Up @@ -218,6 +228,8 @@ export interface INodeOperator extends BaseContract {
overrides?: CallOverrides
): Promise<[number]>;

getOperators(overrides?: CallOverrides): Promise<[string[]]>;

isOperator(
operator: PromiseOrValue<string>,
overrides?: CallOverrides
Expand Down Expand Up @@ -261,6 +273,8 @@ export interface INodeOperator extends BaseContract {
overrides?: CallOverrides
): Promise<number>;

getOperators(overrides?: CallOverrides): Promise<string[]>;

isOperator(
operator: PromiseOrValue<string>,
overrides?: CallOverrides
Expand Down Expand Up @@ -304,6 +318,8 @@ export interface INodeOperator extends BaseContract {
overrides?: CallOverrides
): Promise<number>;

getOperators(overrides?: CallOverrides): Promise<string[]>;

isOperator(
operator: PromiseOrValue<string>,
overrides?: CallOverrides
Expand Down Expand Up @@ -384,6 +400,8 @@ export interface INodeOperator extends BaseContract {
overrides?: CallOverrides
): Promise<BigNumber>;

getOperators(overrides?: CallOverrides): Promise<BigNumber>;

isOperator(
operator: PromiseOrValue<string>,
overrides?: CallOverrides
Expand Down Expand Up @@ -428,6 +446,8 @@ export interface INodeOperator extends BaseContract {
overrides?: CallOverrides
): Promise<PopulatedTransaction>;

getOperators(overrides?: CallOverrides): Promise<PopulatedTransaction>;

isOperator(
operator: PromiseOrValue<string>,
overrides?: CallOverrides
Expand Down
13 changes: 13 additions & 0 deletions packages/generated/dev/typings/factories/INodeOperator__factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ const _abi = [
],
stateMutability: "view",
},
{
type: "function",
name: "getOperators",
inputs: [],
outputs: [
{
name: "",
type: "address[]",
internalType: "address[]",
},
],
stateMutability: "view",
},
{
type: "function",
name: "isOperator",
Expand Down
13 changes: 13 additions & 0 deletions packages/generated/v3/abis/INodeOperator.abi.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@
],
"stateMutability": "view"
},
{
"type": "function",
"name": "getOperators",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address[]",
"internalType": "address[]"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "isOperator",
Expand Down
13 changes: 13 additions & 0 deletions packages/generated/v3/abis/INodeOperator.abi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@ export default [
],
"stateMutability": "view"
},
{
"type": "function",
"name": "getOperators",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address[]",
"internalType": "address[]"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "isOperator",
Expand Down
Loading

0 comments on commit 082af0a

Please sign in to comment.