-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathnodes.ts
More file actions
237 lines (226 loc) · 9.61 KB
/
nodes.ts
File metadata and controls
237 lines (226 loc) · 9.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
import { TFChainError } from "@threefold/tfchain_client";
import { Contract, Node as TFChainNode } from "@threefold/tfchain_client";
import { BaseError, GridClientErrors } from "@threefold/types";
import { TFClient } from "../clients";
import { GridClientConfig } from "../config";
import { events, validateInput } from "../helpers";
import { expose } from "../helpers/expose";
import { NodeInfo } from "../primitives";
import { capacity } from "./capacity";
import {
AddPublicConfig,
FilterOptions,
NodeGetModel,
NodePowerModel,
RentContractCreateModel,
RentContractDeleteModel,
RentContractGetModel,
} from "./models";
import { checkBalance } from "./utils";
class Nodes {
client: TFClient;
capacity: capacity;
/**
* Class representing operations related to `nodes` management.
*
* This class provides methods to interact with `nodes`, including `reserving`, `unreserving`, `getting` `rent contract ID`,
* `getting node information`, `setting node power`, `adding public configuration` to a node, `listing all nodes`, and `filtering nodes`.
* It utilizes the `TFClient` and capacity classes for performing these operations.
*
* @class Nodes
* @param {GridClientConfig} config - The configuration object for initializing the client.
*/
constructor(public config: GridClientConfig) {
this.client = config.tfclient;
this.capacity = new capacity(config);
}
/**
* Reserves a node by creating a `rent contract`.
*
* This method first checks if the node is already rented by calling the `getRentContractId` method.
* If the node is `available`, it creates a `rent contract` using the provided options.
*
* @param {RentContractCreateModel} options - The options for creating the `rent contract`, including the nodeId and optional solutionProviderId.
* @returns {Promise<Contract>} - A promise that resolves with the created `rent contract` details.
* @throws {`GridClientErrors.Nodes.UnavailableNodeError`} - If the node is already rented.
* @throws {`BaseError`} - If an error occurs during the `rent contract` creation process.
* @throws {`TFChainError`} - If a TFChain error occurs during the `rent contract` creation process.
* @decorators
* - `@expose`: Exposes the method for external use.
* - `@validateInput`: Validates the input options.
* - `@checkBalance`: Checks the balance to ensure there are enough funds available.
*/
@expose
@validateInput
@checkBalance
async reserve(options: RentContractCreateModel): Promise<Contract> {
const rentContractId = await this.getRentContractId({ nodeId: options.nodeId });
if (rentContractId) {
throw new GridClientErrors.Nodes.UnavailableNodeError(`Node is already rented.`);
}
try {
const res = await (await this.client.contracts.createRent(options)).apply();
events.emit("logs", `Rent contract with id: ${res.contractId} has been created.`);
return res;
} catch (e) {
//TODO Errors should be handled in tfchain
if (e instanceof BaseError) {
e.message = `Failed to create rent contract on node ${options.nodeId} due to ${e.message}`;
throw e;
}
throw new TFChainError({
message: `Failed to create rent contract on node ${options.nodeId} due to ${e}`,
});
}
}
/**
* Unreserves a node by deleting its `rent contract`.
*
* This method first retrieves the `rent contract ID` for the specified node by calling the `getRentContractId` method.
* If a `rent contract` exists, it deletes the `rent contract` associated with the node.
* If no `rent contract` is found, it emits a log message and returns null.
*
* @param {RentContractDeleteModel} options - The options for deleting the `rent contract`, including the nodeId.
* @returns {Promise<number>} - A promise that resolves with the result of deleting the `rent contract ID`.
* @decorators
* - `@expose`: Exposes the method for external use.
* - `@validateInput`: Validates the input options.
* - `@checkBalance`: Checks the balance to ensure there are enough funds available.
* @throws {`BaseError`} - If an error occurs during the `rent contract` deletion process.
* @throws {`TFChainError`} - If a TFChain error occurs during the `rent contract` deletion process.
*/
@expose
@validateInput
@checkBalance
async unreserve(options: RentContractDeleteModel): Promise<number> {
const rentContractId = await this.getRentContractId({ nodeId: options.nodeId });
if (!rentContractId) {
events.emit("logs", `No rent contract found for node ${options.nodeId}`);
return rentContractId;
}
try {
const cancel = await this.client.contracts.cancel({ id: rentContractId });
const res = await cancel!.apply();
events.emit("logs", `Rent contract for node ${options.nodeId} has been deleted`);
return res;
} catch (e) {
if (e instanceof BaseError) {
e.message = `Failed to delete rent contract on node ${options.nodeId} due to ${e.message}`;
throw e;
}
throw new TFChainError({
message: `Failed to delete rent contract on node ${options.nodeId} due to ${e}`,
});
}
}
/**
* Retrieves the `rent contract ID` for a specific node.
*
* This method calls the `TFChain client` to get the `contract ID` for an active rent associated with the specified node.
*
* @param {RentContractGetModel} options - The options containing the nodeId for which to retrieve the `rent contract ID`.
* @returns {Promise<number>} - A promise that resolves with the `rent contract ID`.
* @throws {`TFChainError`} - If an error occurs while retrieving the `rent contract ID`.
* @decorators
* - `@expose`: Exposes the method for external use.
* - `@validateInput`: Validates the input options.
*/
@expose
@validateInput
async getRentContractId(options: RentContractGetModel): Promise<number> {
return this.client.contracts
.getContractIdByActiveRentForNode(options)
.then(res => {
return res;
})
.catch(err => {
throw new TFChainError({
message: `Error getting rent for node ${options.nodeId}: ${err}`,
});
});
}
/**
* Retrieves information about a specific node.
*
* This method calls the `TFChain client` to get detailed information about a node based on the provided options.
*
* @param {NodeGetModel} options - The options specifying the node ID for which to retrieve information.
* @returns {Promise<TFChainNode>} - A promise that resolves with the detailed information about the `TFChainNode`.
* @decorators
* - `@expose`: Exposes the method for external use.
* - `@validateInput`: Validates the input options.
*/
@expose
@validateInput
async get(options: NodeGetModel): Promise<TFChainNode> {
return await this.client.nodes.get(options);
}
/**
* Sets the power status of a specific node.
*
* This method calls the `TFChain client` to set the power status of a node based on the provided options.
*
* @param {NodePowerModel} options - The options specifying the node ID and the desired power status.
* @returns {Promise<void>} - A promise that resolves once the power status of the node is set.
* @throws {ValidationError} - If the balance is not enough to apply the power status change.
* @decorators
* - `@expose`: Exposes the method for external use.
* - `@validateInput`: Validates the input options.
* - `@checkBalance`: Checks the balance to ensure there are enough funds available.
*/
@expose
@validateInput
@checkBalance
async setNodePower(options: NodePowerModel): Promise<void> {
return (await this.client.nodes.setPower(options)).apply();
}
/**
* Adds a public configuration to a node.
*
* This method calls the `TFChain client` to add a public configuration to a node based on the provided options.
*
* @param {AddPublicConfig} options - The options specifying the farmId, nodeId, and publicConfig to be added.
* @returns {Promise<void>} - A promise that resolves once the public configuration is added to the node.
* @throws {ValidationError} - If the balance is not enough to apply the public configuration.
* @decorators
* - `@expose`: Exposes the method for external use.
* - `@validateInput`: Validates the input options.
* - `@checkBalance`: Checks the balance to ensure there are enough funds available.
*/
@expose
@validateInput
@checkBalance
async addNodePublicConfig(options: AddPublicConfig): Promise<void> {
return (await this.client.nodes.addNodePublicConfig(options)).apply();
}
/**
* Retrieves all nodes.
*
* This method calls the `getAllNodes` method from the `capacity` class to retrieve all nodes.
*
* @returns {Promise<NodeInfo[]>} - A promise that resolves with all nodes.
* @decorators
* - `@expose`: Exposes the method for external use.
*/
@expose
async all(): Promise<NodeInfo[]> {
return await this.capacity.getAllNodes();
}
/**
* Filters nodes based on the provided options.
*
* This method calls the `filterNodes` method from the `capacity` class to filter nodes based on the specified options.
*
* @param {FilterOptions} [options] - The options to filter nodes, including criteria like capacity, location, status, etc.
* @returns {Promise<NodeInfo[]>} - A promise that resolves with the filtered nodes based on the provided options.
* @decorators
* - `@expose`: Exposes the method for external use.
* - `@validateInput`: Validates the input options.
*/
@expose
@validateInput
async filter(options?: FilterOptions): Promise<NodeInfo[]> {
return await this.capacity.filterNodes(options);
}
}
export { Nodes as nodes };