Skip to content

Commit 99098e9

Browse files
kouksdevops-talus
authored andcommitted
Update docs from nexus-next (commit: 8b09da19af9d2c831bddb094c934b23937ee5aaa)
1 parent 31951ce commit 99098e9

File tree

12 files changed

+1452
-16
lines changed

12 files changed

+1452
-16
lines changed

nexus-next/Gas-Service.md

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
# Gas Service
2+
3+
{% hint style="warning" %}
4+
The documentation provided here documents code that is currently implemented in the Nexus onchain packages but not yet in the offchain leader node.
5+
6+
Consequently, these concepts are not enforced as of yet and serve only as informational purpose for future reference.
7+
{% endhint %}
8+
9+
## Overview
10+
11+
The gas payment and settlement system in Nexus provides a flexible way to handle gas payments for tool invocations. It supports multiple modes of operation and allows for different payment strategies through gas extensions.
12+
13+
## Core Concepts
14+
15+
### Gas Service
16+
17+
The `GasService` is a shared object that manages all gas-related operations. It maintains:
18+
19+
* Gas tickets for tools.
20+
* Gas budgets for different scopes.
21+
* Execution gas settlement state.
22+
* Tool-specific gas settings.
23+
24+
### Gas Tickets
25+
26+
Gas tickets represent prepaid access to tool invocations. They can be configured with different modes of operation:
27+
28+
1. **Expiry Mode**: Allows unlimited invocations within a specific time period.
29+
2. **Limited Invocations Mode**: Allows a fixed number of invocations.
30+
3. **Upon Discretion of Tool Mode**: Tool owner has complete control over ticket validity.
31+
32+
### Scopes
33+
34+
Gas tickets and budgets can be associated with different scopes:
35+
36+
1. **Execution Scope**: Specific to a single DAG execution.
37+
2. **Worksheet Type Scope**: Applies to all executions of a specific worksheet type, i.e. the TAP.
38+
3. **Invoker Address Scope**: Applies to all executions initiated by a specific address.
39+
40+
{% hint style="warning" %}
41+
Gas is secured before the tool is invoked to ensure that the tool always gets paid for its usage according to the selected mode.
42+
43+
This does expose the tool owner to slashing risk, if they do not deliver the service according to the Nexus defined protocol.
44+
{% endhint %}
45+
46+
### Other Data Structures
47+
48+
#### ExecutionGas
49+
50+
Tracks gas settlement state for a specific DAG execution. This struct maintains a record of which vertices in the execution have had their gas settled. Once a vertex is marked as settled, it can be invoked once.
51+
52+
#### GasBudgets
53+
54+
Manages gas budgets for different scopes in the system. The inner Bag stores balances of SUI coins, with the key being a Scope. These budgets are used as a fallback payment method when no gas tickets are available. See [Default Gas Budget](Gas-Service.md#1-default-gas-budget).
55+
56+
#### ToolGas
57+
58+
Manages all gas-related state for a specific tool. This includes:
59+
60+
* Collected gas payments in the vault
61+
* Default cost per invocation
62+
* Tool-specific gas settings
63+
* Available gas tickets for different scopes
64+
65+
## Gas Payment Modes
66+
67+
### 1. Default Gas Budget
68+
69+
Tools can set a default cost per invocation. When no gas tickets are available, the system will attempt to charge from the gas budget in the following order:
70+
71+
1. Execution-specific budget
72+
2. Worksheet type budget
73+
3. Invoker address budget
74+
75+
### 2. Gas Extensions
76+
77+
Gas extensions provide alternative payment strategies. The default extension implements an expiry-based system where users can:
78+
79+
* Buy access for a specific duration (e.g., 10 minutes).
80+
* Pay a fixed rate per minute.
81+
* Get unlimited invocations during the purchased period.
82+
83+
## Gas Settlement Process
84+
85+
1. When a vertex (tool) is invoked, the system checks if gas has been settled.
86+
2. If not settled, it attempts to find a valid gas ticket for the different scopes in order.
87+
3. Gas tickets are validated against the execution's creation timestamp, not the current time.
88+
4. If no valid ticket is found, it attempts to charge from the gas budget.
89+
5. Once settled, the vertex can be invoked.
90+
6. Gas settlement is idempotent - subsequent checks won't charge again.
91+
92+
### Events
93+
94+
The system emits several types of events for gas-related operations:
95+
96+
1. `GasSettlementUpdateEvent` for each gas settlement attempt:
97+
98+
```rust
99+
public struct GasSettlementUpdateEvent has copy, drop {
100+
execution: ID,
101+
vertex: dag::Vertex,
102+
tool_fqn: AsciiString,
103+
/// Whether the gas ticket was stamped ok.
104+
///
105+
/// Multiple of these events can be emitted for the same execution/vertex/tool_fqn
106+
/// combination, but only one of them will have this field set to true.
107+
was_settled: bool,
108+
}
109+
```
110+
111+
2. `LeaderClaimedGasEvent` for tracking gas claims by leaders:
112+
113+
```rust
114+
public struct LeaderClaimedGasEvent has copy, drop {
115+
/// Who is the leader.
116+
network: ID,
117+
/// How much was claimed.
118+
amount: u64,
119+
}
120+
```
121+
122+
### Checking Gas Payment Status
123+
124+
There are several ways to check if gas has been paid for a tool invocation:
125+
126+
1. **Using GasService State**
127+
* Anyone can check if gas has been settled for a specific vertex in an execution using [`is_execution_vertex_settled`](Gas-Service.md#view-operations).
128+
* This is useful both for onchain and offchain actors.
129+
* This is the most direct way to verify gas payment status.
130+
* Returns a boolean indicating whether the vertex can be invoked.
131+
2. **Listening to Events**
132+
* The system emits `GasSettlementUpdateEvent` for each gas settlement attempt.
133+
* Anyone can listen to these events to track gas settlement status.
134+
3. **Checking Gas Tickets**
135+
* Tool owners can check their tool's gas tickets and settings.
136+
* Users can check their own gas budgets and tickets.
137+
* This is useful _before_ the invocation is requested to know whether it's possible to execute with given gas tickets.
138+
4. **Viewing Gas Budgets**
139+
* Users can check their remaining gas budgets for different scopes.
140+
* This is useful _before_ the invocation is requested to know whether it's possible to execute with given gas budgets.
141+
142+
## Security Considerations
143+
144+
1. Gas tickets with expiry or limited invocations cannot be revoked.
145+
2. Only tickets in "Upon Discretion of Tool" mode can be revoked.
146+
3. Tool owners can claim gas at any time.
147+
4. Gas budgets can be refunded if the execution is finished.
148+
5. Workflows that want to pay gas on behalf of the user must assert that they execute in a network with a trusted leader. See [current limitation below](Gas-Service.md#current-limitation)
149+
150+
### Current limitation
151+
152+
In the current implementation the Nexus leader can claim any amount of gas it wants from anybody who uploads gas budgets.\
153+
To hold the leader accountable we emit `LeaderClaimedGasEvent` event which can be read by 3rd parties that check that the amount claimed is not over the top.
154+
155+
However, this implies that as of right now, the leader is has to be trusted.
156+
157+
## Key Operations
158+
159+
<details>
160+
161+
<summary>Tool Owner Operations</summary>
162+
163+
#### Gas Cost Management
164+
165+
1. **Setting Default Cost**\
166+
Sets the default cost in MIST for a single tool invocation. Calling this function enables gas collection by the tool so it's imperative the tool owners calls it to collect fees for tool execution.
167+
168+
```rust
169+
public fun set_single_invocation_cost_mist(
170+
gas_service: &mut GasService,
171+
tool_registry: &ToolRegistry,
172+
owner_cap: &CloneableOwnerCap<OverGas>,
173+
fqn: AsciiString,
174+
single_invocation_cost_mist: u64,
175+
ctx: &mut TxContext,
176+
)
177+
```
178+
179+
> Set `single_invocation_cost_mist` to 2^64-1 to enable gas collection but require a gas extension to do it.
180+
2. **Claiming Gas**\
181+
Allows the tool owner to withdraw all collected gas payments for their tool.
182+
183+
```rust
184+
public fun claim_gas(
185+
gas_service: &mut GasService,
186+
tool_registry: &ToolRegistry,
187+
owner_cap: &CloneableOwnerCap<OverTool>,
188+
fqn: AsciiString,
189+
ctx: &mut TxContext,
190+
): Balance<SUI>
191+
```
192+
193+
#### Gas Ticket Management
194+
195+
1. **Adding Gas Tickets**\
196+
Creates a new gas ticket with specified scope and mode of operation.
197+
198+
```rust
199+
public fun add_gas_ticket(
200+
gas_service: &mut GasService,
201+
tool_registry: &ToolRegistry,
202+
owner_cap: &CloneableOwnerCap<OverGas>,
203+
fqn: AsciiString,
204+
scope: Scope,
205+
modus_operandi: ModusOperandi,
206+
clock: &Clock,
207+
ctx: &mut TxContext,
208+
)
209+
```
210+
211+
The tool owner can use "upon discretion of the tool" mode to be able to `revoke_gas_ticket` _at will_.
212+
213+
2. **Revoking Gas Tickets**\
214+
Revokes a gas ticket that was created with the "Upon Discretion of Tool" mode.
215+
216+
```rust
217+
public fun revoke_gas_ticket(
218+
gas_service: &mut GasService,
219+
tool_registry: &ToolRegistry,
220+
owner_cap: &CloneableOwnerCap<OverGas>,
221+
fqn: AsciiString,
222+
scope: Scope,
223+
ctx: &mut TxContext,
224+
)
225+
```
226+
3. **Managing Gas Settings**\
227+
The tool owner can set the gas settings for the tool.
228+
229+
```rust
230+
public fun get_tool_gas_setting_mut(
231+
gas_service: &mut GasService,
232+
tool_registry: &ToolRegistry,
233+
owner_cap: &CloneableOwnerCap<OverGas>,
234+
fqn: AsciiString,
235+
ctx: &mut TxContext,
236+
): &mut Bag
237+
```
238+
4. **De-escalating Permissions**\
239+
Converts a tool owner cap into a gas owner cap with reduced permissions.
240+
241+
```rust
242+
public fun deescalate(
243+
tool_registry: &ToolRegistry,
244+
owner_cap: &CloneableOwnerCap<OverTool>,
245+
fqn: AsciiString,
246+
ctx: &mut TxContext,
247+
): CloneableOwnerCap<OverGas>
248+
```
249+
250+
</details>
251+
252+
<details>
253+
254+
<summary>User Operations</summary>
255+
256+
#### Gas Budget Management
257+
258+
1. **Donating to Tool**\
259+
Donate given balance to the tool's gas total. This is used to charge the user from gas extensions and make it available to the tool.
260+
261+
```rust
262+
public fun donate_to_tool(
263+
self: &mut GasService, fqn: AsciiString, amount: Balance<SUI>,
264+
) {
265+
let tool_gas = self.tools_gas.borrow_mut(fqn);
266+
tool_gas.vault.join(amount);
267+
}
268+
```
269+
270+
1. **Adding Gas Budget**\
271+
Adds a gas budget for a specific scope (execution, worksheet type, or invoker address).
272+
273+
```rust
274+
public fun add_gas_budget(
275+
gas_service: &mut GasService,
276+
scope: Scope,
277+
budget: Balance<SUI>,
278+
)
279+
```
280+
2. **Refunding Execution Gas Budget**\
281+
Refunds any remaining gas budget for a completed execution to the invoker. This operation also cleans up storage by removing the execution gas state, helping to reduce storage costs.
282+
283+
```rust
284+
public fun refund_execution_gas_budget(
285+
gas_service: &mut GasService,
286+
execution: &dag::DAGExecution,
287+
ctx: &mut TxContext,
288+
)
289+
```
290+
3. **Refunding Invoker Gas Budget**\
291+
Refunds any remaining gas budget associated with the invoker's address.
292+
293+
```rust
294+
public fun refund_invoker_gas_budget(
295+
gas_service: &mut GasService,
296+
ctx: &mut TxContext,
297+
): Balance<SUI>
298+
```
299+
4. **Refunding Worksheet Gas Budget**\
300+
Refunds any remaining gas budget associated with a specific worksheet type.
301+
302+
```rust
303+
public fun refund_worksheet_gas_budget<T>(
304+
gas_service: &mut GasService,
305+
_witness: &T,
306+
): Balance<SUI>
307+
```
308+
309+
</details>
310+
311+
<details>
312+
313+
<summary>View Operations</summary>
314+
315+
#### View Operations
316+
317+
1. **Checking Vertex Settlement**\
318+
Verifies if gas has been settled for a specific vertex in an execution.
319+
320+
```rust
321+
public fun is_execution_vertex_settled(
322+
gas_service: &GasService,
323+
execution: &dag::DAGExecution,
324+
vertex: dag::Vertex,
325+
): bool
326+
```
327+
2. **Reading Tool Gas Settings**\
328+
Gets read-only access to a tool's gas settings.
329+
330+
```rust
331+
public fun get_tool_gas_setting(
332+
gas_service: &GasService,
333+
fqn: AsciiString,
334+
): &Bag
335+
```
336+
337+
</details>

nexus-next/Glossary.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Glossary
2+
3+
- **`Tool Registry`** - On-chain object that holds Tool definitions so that the Leader knows where and how to invoke them.
4+
- **`Tool`** - HTTP service or a smart contract with a predefined interface, executing a specific task. It is a Vertex in the Nexus DAG.
5+
- **`DAG`** - Directed acyclic graph describes how outputs from Tools flow into inputs of other Tools. This is a static definition.
6+
- **`JSON DAG`** - JSON representation of a DAG with a Nexus provided schema.
7+
- **`DAG Execution`** - When a static DAG is passed to the Workflow, a DAG Execution is instantiated.
8+
- **`Workflow`** - The on-chain Nexus package, that takes a DAG and its inputs to create and drive a DAG execution. It keeps all state related to the DAG execution and emits events to the off-chain world with instructions on how to proceed with the DAG execution.
9+
- **`Primitives`** - Exports types that allow two Sui packages, A and B, to communicate with each other in an authenticated way without using explicit Move dependencies.
10+
- **`TAP`** - Talus Agent Package is a smart contract that can accept a DAG, execute it and verify its execution. It also holds custom logic that can be hooked into the DAG execution process.
11+
- **`Default TAP`** - Nexus provided TAP that only executes a DAG and verifies its execution. It does not have any custom logic.
12+
- **`Leader`** - The off-chain service that listens to Sui events and executes Tools as instructed by Worflow.
13+
- **`Indexer`** - The off-chain database service as a job queue. All events emitted by the Workflow are stored here, along with their execution status.
14+
- **`Toolkit`** - Library that provides interfaces and boilerplate for Tool development. Currently implemented in Rust.
15+
- **`CLI`** - Nexus CLI that provides commands for Tool registration, JSON DAG static analysis, publishing and execution via the Default TAP.
16+
- **`SDK`** - Nexus Rust SDK that exposes various types, logic and transaction templates useful both internally and externally.
17+
18+
## `DAG` Related Terms
19+
20+
- **`Vertex`** - Abstraction of a Tool in the DAG.
21+
- **`Edge`** - Connection between one Tool's output and other Tool's input.
22+
- **`Input Port`** - A single input of a Tool. This can be one and only one of:
23+
1. Port that has an edge leading to it
24+
2. Port with a `Default Value` statically defined on the DAG
25+
3. Port as an `Entry Input Port` that accepts a value at execution time from the triggerer
26+
- **`Output Variant`** - Resulting _state_ of a Tool evaluation. A Tool can define N Output Variants but will always evaluate into exactly 1 at runtime.
27+
- **`Output Port`** - A single output of a Tool within an Output Variant.
28+
- **`Entry Group`** - A set of Vertices and their respective Entry Input Ports that need to be provided a value upon DAG execution.

0 commit comments

Comments
 (0)