From 6043035a29852cc2b22b7908e25bf7e3b338aaae Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 5 May 2026 11:29:28 -0600 Subject: [PATCH] docs: align with unified approveService + expireServiceRequest tnt-core PR #119 collapsed five approveServiceWith* variants into one approveService(ApprovalParams). PR #122 declared expireServiceRequest on ITangleServices. Updates here: - ITangleServices reference (and generated mirror): replace approveService(uint64,uint8) + 4 approveServiceWith* blocks with the unified entrypoint; document expireServiceRequest, getTeeCommitmentRoot, teeNonceFor, blsPopMessage. - auth-surface: collapse the four approveServiceWith* table rows into one approveService(ApprovalParams) row with a note on opt-in fields. - slashing: rename the per-asset commitment narrative reference from approveServiceWithCommitments to approveService(ApprovalParams) with non-empty securityCommitments. - check-tnt-core-sync: stop tripwiring on the removed signatures; gate on the new unified entrypoint plus expireServiceRequest / getTeeCommitmentRoot / teeNonceFor. --- .../api/reference/ITangleServices.mdx | 40 +++++++++++++------ .../reference/generated/ITangleServices.mdx | 40 +++++++++++++------ pages/developers/auth-surface.mdx | 21 +++++----- pages/developers/slashing.mdx | 2 +- scripts/check-tnt-core-sync.mjs | 21 +++++++--- 5 files changed, 80 insertions(+), 44 deletions(-) diff --git a/pages/developers/api/reference/ITangleServices.mdx b/pages/developers/api/reference/ITangleServices.mdx index f7d5171..6ee10af 100644 --- a/pages/developers/api/reference/ITangleServices.mdx +++ b/pages/developers/api/reference/ITangleServices.mdx @@ -50,36 +50,40 @@ Get resource requirements for a service request #### approveService ```solidity -function approveService(uint64 requestId, uint8 stakingPercent) external +function approveService(struct Types.ApprovalParams params) external ``` -Approve a service request (as operator) - simple version +Approve a service request as one of its operators. -#### approveServiceWithCommitments +_Single entrypoint covering every approval mode. Pass empty/zero fields on `ApprovalParams` to opt out of the corresponding capability:_ + +- `securityCommitments == []` — no per-asset commitment supplied. Only valid when the request has no security requirements OR the only requirement is the protocol-default TNT requirement (auto-filled at min-exposure). +- `blsPubkey == [0,0,0,0]` — operator does NOT register a BLS pubkey for aggregated job-result signing. BLS is opt-in; the protocol accepts any operator. +- `teeCommitments == []` — operator does NOT bind to a TEE attestation profile. + +#### getTeeCommitmentRoot ```solidity -function approveServiceWithCommitments(uint64 requestId, struct Types.AssetSecurityCommitment[] commitments) external +function getTeeCommitmentRoot(uint64 serviceId, address operator) external view returns (bytes32) ``` -Approve a service request with multi-asset security commitments - -_Commitments must match the security requirements specified in the request_ +Returns `keccak256(abi.encode(commitments))` over an operator's `TeeAttestationCommitment[]` for a service, or `bytes32(0)` if none was supplied. The full array was emitted at approval time in `TeeCommitmentsRecorded`; slashing and provisioning oracles supply the array as a witness and verify `keccak256(abi.encode(witness)) == getTeeCommitmentRoot(serviceId, operator)`. -#### approveServiceWithBls +#### teeNonceFor ```solidity -function approveServiceWithBls(uint64 requestId, uint8 stakingPercent, uint256[4] blsPubkey) external +function teeNonceFor(uint64 requestId) external view returns (bytes32) ``` -Approve a service request with BLS public key for aggregated signature verification +Canonical TEE attestation nonce binding for `requestId` on this contract on this chain. Operators MUST submit this exact value as `nonceBinding` in any `TeeAttestationCommitment` for the request — it eliminates cross-request attestation replay at approval time. -#### approveServiceWithCommitmentsAndBls +#### blsPopMessage ```solidity -function approveServiceWithCommitmentsAndBls(uint64 requestId, struct Types.AssetSecurityCommitment[] commitments, uint256[4] blsPubkey) external +function blsPopMessage(address operator, uint256[4] blsPubkey) external view returns (bytes) ``` -Approve a service request with both security commitments and BLS public key +Build the canonical message an operator must sign with their BLS secret key to register a public key. Bound to chainId, the verifying contract, and operator. #### rejectService @@ -89,6 +93,16 @@ function rejectService(uint64 requestId) external Reject a service request (as operator) +#### expireServiceRequest + +```solidity +function expireServiceRequest(uint64 requestId) external +``` + +Permissionlessly expire a stale service request and refund the requester. + +_Anyone may call once `block.timestamp > req.createdAt + grace` (grace is `_requestExpiryGracePeriod` or `ProtocolConfig.REQUEST_EXPIRY_GRACE_PERIOD`). Reverts if the request was already rejected, already activated, or still within its grace window._ + #### createServiceFromQuotes ```solidity diff --git a/pages/developers/api/reference/generated/ITangleServices.mdx b/pages/developers/api/reference/generated/ITangleServices.mdx index f7d5171..6ee10af 100644 --- a/pages/developers/api/reference/generated/ITangleServices.mdx +++ b/pages/developers/api/reference/generated/ITangleServices.mdx @@ -50,36 +50,40 @@ Get resource requirements for a service request #### approveService ```solidity -function approveService(uint64 requestId, uint8 stakingPercent) external +function approveService(struct Types.ApprovalParams params) external ``` -Approve a service request (as operator) - simple version +Approve a service request as one of its operators. -#### approveServiceWithCommitments +_Single entrypoint covering every approval mode. Pass empty/zero fields on `ApprovalParams` to opt out of the corresponding capability:_ + +- `securityCommitments == []` — no per-asset commitment supplied. Only valid when the request has no security requirements OR the only requirement is the protocol-default TNT requirement (auto-filled at min-exposure). +- `blsPubkey == [0,0,0,0]` — operator does NOT register a BLS pubkey for aggregated job-result signing. BLS is opt-in; the protocol accepts any operator. +- `teeCommitments == []` — operator does NOT bind to a TEE attestation profile. + +#### getTeeCommitmentRoot ```solidity -function approveServiceWithCommitments(uint64 requestId, struct Types.AssetSecurityCommitment[] commitments) external +function getTeeCommitmentRoot(uint64 serviceId, address operator) external view returns (bytes32) ``` -Approve a service request with multi-asset security commitments - -_Commitments must match the security requirements specified in the request_ +Returns `keccak256(abi.encode(commitments))` over an operator's `TeeAttestationCommitment[]` for a service, or `bytes32(0)` if none was supplied. The full array was emitted at approval time in `TeeCommitmentsRecorded`; slashing and provisioning oracles supply the array as a witness and verify `keccak256(abi.encode(witness)) == getTeeCommitmentRoot(serviceId, operator)`. -#### approveServiceWithBls +#### teeNonceFor ```solidity -function approveServiceWithBls(uint64 requestId, uint8 stakingPercent, uint256[4] blsPubkey) external +function teeNonceFor(uint64 requestId) external view returns (bytes32) ``` -Approve a service request with BLS public key for aggregated signature verification +Canonical TEE attestation nonce binding for `requestId` on this contract on this chain. Operators MUST submit this exact value as `nonceBinding` in any `TeeAttestationCommitment` for the request — it eliminates cross-request attestation replay at approval time. -#### approveServiceWithCommitmentsAndBls +#### blsPopMessage ```solidity -function approveServiceWithCommitmentsAndBls(uint64 requestId, struct Types.AssetSecurityCommitment[] commitments, uint256[4] blsPubkey) external +function blsPopMessage(address operator, uint256[4] blsPubkey) external view returns (bytes) ``` -Approve a service request with both security commitments and BLS public key +Build the canonical message an operator must sign with their BLS secret key to register a public key. Bound to chainId, the verifying contract, and operator. #### rejectService @@ -89,6 +93,16 @@ function rejectService(uint64 requestId) external Reject a service request (as operator) +#### expireServiceRequest + +```solidity +function expireServiceRequest(uint64 requestId) external +``` + +Permissionlessly expire a stale service request and refund the requester. + +_Anyone may call once `block.timestamp > req.createdAt + grace` (grace is `_requestExpiryGracePeriod` or `ProtocolConfig.REQUEST_EXPIRY_GRACE_PERIOD`). Reverts if the request was already rejected, already activated, or still within its grace window._ + #### createServiceFromQuotes ```solidity diff --git a/pages/developers/auth-surface.mdx b/pages/developers/auth-surface.mdx index 42c0c85..bfb69d9 100644 --- a/pages/developers/auth-surface.mdx +++ b/pages/developers/auth-surface.mdx @@ -98,17 +98,16 @@ See [Slashing](/developers/slashing) for the full lifecycle and runbooks. ### Services -| Function | Caller | -| ------------------------------------------------------------- | ---------------------------------------------------- | -| `requestService(...)` | Anyone (when not paused) | -| `approveService(requestId, stakingPercent)` | Operator listed in the request (request not expired) | -| `approveServiceWithCommitments(...)` | Operator listed in the request | -| `approveServiceWithBls(requestId, stakingPercent, blsPubkey)` | Operator listed in the request | -| `approveServiceWithCommitmentsAndBls(...)` | Operator listed in the request | -| `rejectService(requestId)` | Operator listed in the request | -| `expireServiceRequest(requestId)` | Anyone, after grace period (when not activated) | -| `terminateService(serviceId)` | Service owner | -| `forceRemoveOperator(serviceId, operator)` | Blueprint manager only | +| Function | Caller | +| ------------------------------------------ | ---------------------------------------------------- | +| `requestService(...)` | Anyone (when not paused) | +| `approveService(ApprovalParams)` | Operator listed in the request (request not expired) | +| `rejectService(requestId)` | Operator listed in the request | +| `expireServiceRequest(requestId)` | Anyone, after grace period (when not activated) | +| `terminateService(serviceId)` | Service owner | +| `forceRemoveOperator(serviceId, operator)` | Blueprint manager only | + +`approveService` is a single entrypoint. Optional capabilities are opt-in via empty/zero fields on `ApprovalParams`: empty `securityCommitments`, zero `blsPubkey`, or empty `teeCommitments` each means "skip this capability." See [the slashing doc](/developers/slashing) for the per-asset commitment contract. ### Payments diff --git a/pages/developers/slashing.mdx b/pages/developers/slashing.mdx index 6e617b5..91bd87e 100644 --- a/pages/developers/slashing.mdx +++ b/pages/developers/slashing.mdx @@ -168,7 +168,7 @@ The deadline (`disputeResolutionDeadline`) matters because without auto-resoluti ## Per-Asset Commitment Slashing -When an operator joins a service via `approveServiceWithCommitments`, they declare per-asset exposure (`AssetSecurityCommitment[]`). On slash: +When an operator joins a service via `approveService(ApprovalParams)` with a non-empty `securityCommitments`, they declare per-asset exposure (`AssetSecurityCommitment[]`). On slash: - `_executeSlashOnStaking` reads `_serviceSecurityCommitments[serviceId][operator]`. - If commitments exist, it routes to `slashForService(operator, blueprintId, serviceId, commitments, slashBps, evidence)` which only burns the committed assets proportionally to `commitment.exposureBps`. diff --git a/scripts/check-tnt-core-sync.mjs b/scripts/check-tnt-core-sync.mjs index 0ed144f..a62a001 100644 --- a/scripts/check-tnt-core-sync.mjs +++ b/scripts/check-tnt-core-sync.mjs @@ -15,7 +15,9 @@ function resolveTntCoreDir() { ].filter(Boolean); for (const candidate of candidates) { - if (fs.existsSync(path.join(candidate, "src/interfaces/ITangleServices.sol"))) { + if ( + fs.existsSync(path.join(candidate, "src/interfaces/ITangleServices.sol")) + ) { return candidate; } } @@ -34,7 +36,10 @@ const helperPath = path.join( const sourcePath = path.join(tntCoreDir, "src/interfaces/ITangleServices.sol"); const docsPaths = [ path.join(repoRoot, "pages/developers/api/reference/ITangleServices.mdx"), - path.join(repoRoot, "pages/developers/api/reference/generated/ITangleServices.mdx"), + path.join( + repoRoot, + "pages/developers/api/reference/generated/ITangleServices.mdx", + ), ]; function readFile(targetPath) { @@ -57,8 +62,10 @@ const source = readFile(sourcePath).replace(/\s+/g, " "); const requiredSourceSnippets = [ "Types.ConfidentialityPolicy confidentiality", "function getServiceRequestResourceRequirements(", - "function approveServiceWithBls(", - "function approveServiceWithCommitmentsAndBls(", + "function approveService(Types.ApprovalParams calldata params)", + "function expireServiceRequest(uint64 requestId)", + "function getTeeCommitmentRoot(uint64 serviceId, address operator)", + "function teeNonceFor(uint64 requestId)", "function terminateServiceForNonPayment(", "event ServiceTerminatedForNonPayment(", ]; @@ -83,8 +90,10 @@ const requiredDocsSnippets = [ "function requestServiceWithExposure(uint64 blueprintId, address[] operators, uint16[] exposureBps, bytes config, address[] permittedCallers, uint64 ttl, address paymentToken, uint256 paymentAmount, enum Types.ConfidentialityPolicy confidentiality) external payable returns (uint64 requestId)", "function requestServiceWithSecurity(uint64 blueprintId, address[] operators, struct Types.AssetSecurityRequirement[] securityRequirements, bytes config, address[] permittedCallers, uint64 ttl, address paymentToken, uint256 paymentAmount, enum Types.ConfidentialityPolicy confidentiality) external payable returns (uint64 requestId)", "function getServiceRequestResourceRequirements(uint64 requestId) external view returns (struct Types.ResourceCommitment[])", - "function approveServiceWithBls(uint64 requestId, uint8 stakingPercent, uint256[4] blsPubkey) external", - "function approveServiceWithCommitmentsAndBls(uint64 requestId, struct Types.AssetSecurityCommitment[] commitments, uint256[4] blsPubkey) external", + "function approveService(struct Types.ApprovalParams params) external", + "function expireServiceRequest(uint64 requestId) external", + "function getTeeCommitmentRoot(uint64 serviceId, address operator) external view returns (bytes32)", + "function teeNonceFor(uint64 requestId) external view returns (bytes32)", "function terminateServiceForNonPayment(uint64 serviceId) external", "event ServiceRequested(uint64 requestId, uint64 blueprintId, address requester, enum Types.ConfidentialityPolicy confidentiality)", "event ServiceRequestedWithSecurity(uint64 requestId, uint64 blueprintId, address requester, enum Types.ConfidentialityPolicy confidentiality)",