From 58128fe3fc66fce33af78180a4e616a38f64c049 Mon Sep 17 00:00:00 2001 From: PJ Date: Thu, 12 Dec 2024 15:44:37 +0100 Subject: [PATCH 01/12] docs: add OpenAPI docs for consensus routes --- .changeset/extend_openapi_spec.md | 8 + openapi.yml | 778 +++++++++++++++++++++++++++++- 2 files changed, 779 insertions(+), 7 deletions(-) create mode 100644 .changeset/extend_openapi_spec.md diff --git a/.changeset/extend_openapi_spec.md b/.changeset/extend_openapi_spec.md new file mode 100644 index 000000000..0d8880205 --- /dev/null +++ b/.changeset/extend_openapi_spec.md @@ -0,0 +1,8 @@ +--- +default: minor +--- + +# Extend OpenAPI spec + +The following routes were added: +- consensus \ No newline at end of file diff --git a/openapi.yml b/openapi.yml index 3f1b7c689..ff536be80 100644 --- a/openapi.yml +++ b/openapi.yml @@ -1119,26 +1119,62 @@ paths: content: application/json: schema: - type: object - properties: - block: - type: string - description: The block to accept + $ref: "#/components/schemas/Block" responses: "200": description: Successfully accepted block - "400": - description: Malformed request + "500": + description: Internal server error content: text/plain: schema: type: string + /bus/consensus/network: + get: + summary: Get network details + description: Returns various details about the network. + responses: + "200": + description: Successfully retrieved network + content: + application/json: + schema: + $ref: "#/components/schemas/Network" + /bus/consensus/siafundfee/{payout}: + get: + summary: Get siafund fee + description: Returns the siafund fee for the specified payout. + parameters: + - name: payout + in: path + required: true + description: The payout to calculate the fee for + schema: + $ref: "#/components/schemas/Currency" + responses: + "200": + description: Successfully retrieved siafund fee + content: + application/json: + schema: + $ref: "#/components/schemas/Currency" "500": description: Internal server error content: text/plain: schema: type: string + /bus/consensus/state: + get: + summary: Get consensus state + description: Returns the current consensus state. + responses: + "200": + description: Successfully retrieved consensus state + content: + application/json: + schema: + $ref: "#/components/schemas/ConsensusState" components: schemas: @@ -1177,6 +1213,11 @@ components: type: boolean description: Whether the account requires a sync with the host. This is usually the case when the host reports insufficient balance for an account that the worker still believes to be funded. + Address: + allOf: + - $ref: "#/components/schemas/Hash256" + - description: The hash of a set of UnlockConditions + Alert: type: object properties: @@ -1203,17 +1244,209 @@ components: format: date-time description: The time the alert was created + Attestation: + type: object + properties: + publicKey: + $ref: "#/components/schemas/PublicKey" + key: + type: string + value: + type: string + format: byte + signature: + $ref: "#/components/schemas/Signature" + + Block: + type: object + properties: + parentID: + allOf: + - $ref: "#/components/schemas/BlockID" + - description: The ID of the parent block + nonce: + type: integer + format: uint64 + description: The nonce used to mine the block + timestamp: + type: string + format: date-time + description: The time the block was mined + minerPayouts: + type: array + items: + $ref: "#/components/schemas/SiacoinOutput" + transactions: + type: array + items: + $ref: "#/components/schemas/Transaction" + v2: + $ref: "#/components/schemas/V2BlockData" + + BlockID: + type: object + properties: + id: + allOf: + - $ref: "#/components/schemas/Hash256" + - description: A unique identifier for a block + + CoveredFields: + type: object + properties: + wholeTransaction: + type: boolean + description: Whether the whole transaction is covered by the signature + siacoinInputs: + type: array + items: + type: integer + format: uint64 + siacoinOutputs: + type: array + items: + type: integer + format: uint64 + fileContracts: + type: array + items: + type: integer + format: uint64 + fileContractRevisions: + type: array + items: + type: integer + format: uint64 + storageProofs: + type: array + items: + type: integer + format: uint64 + siafundInputs: + type: array + items: + type: integer + format: uint64 + siafundOutputs: + type: array + items: + type: integer + format: uint64 + minerFees: + type: array + items: + type: integer + format: uint64 + arbitraryData: + type: array + items: + type: integer + format: uint64 + signatures: + type: array + items: + type: integer + format: uint64 + Currency: type: string pattern: "^\\d+$" maxLength: 39 # fits 2^128 - 1 description: An unsigned amount of Hastings, the smallest unit of currency in Sia. 1 Siacoin (SC) equals 10^24 Hastings (H). + FileContract: + type: object + description: A storage agreement between a renter and a host. + properties: + filesize: + type: integer + format: uint64 + description: The size of the contract in bytes. + fileMerkleRoot: + allOf: + - $ref: "#/components/schemas/Hash256" + - description: The Merkle root of the contract's data. + windowStart: + type: integer + format: uint64 + description: The block height when the contract's proof window starts. + windowEnd: + type: integer + format: uint64 + description: The block height when the contract's proof window ends. + payout: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The total payout for the contract. + validProofOutputs: + type: array + description: List of outputs created if the contract is successfully fulfilled. + items: + $ref: "#/components/schemas/SiacoinOutput" + missedProofOutputs: + type: array + description: List of outputs created if the contract is not fulfilled. + items: + $ref: "#/components/schemas/SiacoinOutput" + unlockHash: + $ref: "#/components/schemas/Address" + revisionNumber: + type: integer + format: uint64 + description: The revision number of the contract. + FileContractID: allOf: - $ref: "#/components/schemas/Hash256" - description: A unique identifier for a file contract + FileContractRevision: + type: object + description: Represents a revision to an existing file contract. + properties: + parentID: + allOf: + - $ref: "#/components/schemas/FileContractID" + - description: The ID of the parent file contract being revised. + unlockConditions: + allOf: + - $ref: "#/components/schemas/UnlockConditions" + - description: The conditions required to unlock the contract for revision. + filesize: + type: integer + format: uint64 + description: The size of the file in bytes after the revision. + fileMerkleRoot: + allOf: + - $ref: "#/components/schemas/Hash256" + - description: The updated Merkle root of the file's data. + windowStart: + type: integer + format: uint64 + description: The block height when the revised proof window starts. + windowEnd: + type: integer + format: uint64 + description: The block height when the revised proof window ends. + validProofOutputs: + type: array + description: Updated outputs if the revised contract is successfully fulfilled. + items: + $ref: "#/components/schemas/SiacoinOutput" + missedProofOutputs: + type: array + description: Updated outputs if the revised contract is not fulfilled. + items: + $ref: "#/components/schemas/SiacoinOutput" + unlockHash: + allOf: + - $ref: "#/components/schemas/Address" + - description: The updated hash of the conditions required to unlock the contract funds. + revisionNumber: + type: integer + format: uint64 + description: The updated revision number of the contract. + Hash256: type: string pattern: ^[0-9a-fA-F]{64}$ @@ -1224,12 +1457,416 @@ components: pattern: "^ed25519:[0-9a-fA-F]{64}$" description: A ed25519 public key + SatisfiedPolicy: + type: object + properties: + policy: + type: object + signature: + type: array + items: + type: string + format: byte + preimages: + type: array + items: + type: string + format: byte + + SiacoinElement: + type: object + properties: + id: + allOf: + - $ref: "#/components/schemas/SiacoinOutputID" + - description: The ID of the element + stateElement: + allOf: + - $ref: "#/components/schemas/StateElement" + - description: The state of the element + siafundOutput: + allOf: + - $ref: "#/components/schemas/SiacoinOutput" + - description: The output of the element + maturityHeight: + type: integer + format: uint64 + description: The block height when the output matures + + SiacoinInput: + type: object + properties: + parentID: + allOf: + - $ref: "#/components/schemas/SiacoinOutputID" + - description: The ID of the output being spent + unlockConditions: + allOf: + - $ref: "#/components/schemas/UnlockConditions" + - description: The unlock conditions required to spend the output + + SiacoinOutput: + type: object + properties: + value: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The amount of Siacoins in the output + address: + $ref: "#/components/schemas/Address" + + SiacoinOutputID: + allOf: + - $ref: "#/components/schemas/Hash256" + - description: Unique identifier for a Siacoin output. + + SiafundElement: + type: object + properties: + id: + allOf: + - $ref: "#/components/schemas/SiafundOutputID" + - description: The ID of the element + stateElement: + allOf: + - $ref: "#/components/schemas/StateElement" + - description: The state of the element + siafundOutput: + allOf: + - $ref: "#/components/schemas/SiafundOutput" + - description: The output of the element + claimStart: + allOf: + - $ref: "#/components/schemas/Currency" + - description: value of SiafundTaxRevenue when element was created + + SiafundInput: + type: object + description: Represents an input used to spend an unspent Siafund output. + properties: + parentID: + allOf: + - $ref: "#/components/schemas/SiafundOutputID" + - description: The ID of the parent Siafund output being spent. + unlockConditions: + allOf: + - $ref: "#/components/schemas/UnlockConditions" + - description: The conditions required to unlock the parent Siafund output. + claimAddress: + allOf: + - $ref: "#/components/schemas/Address" + - description: The address receiving the Siacoin claim generated by the Siafund output. + + SiafundOutput: + type: object + description: Represents an output created to distribute Siafund. + properties: + value: + type: integer + format: uint64 + description: The amount of Siafund in the output. + address: + allOf: + - $ref: "#/components/schemas/Address" + - description: The address receiving the Siafund. + + SiafundOutputID: + allOf: + - $ref: "#/components/schemas/Hash256" + - description: Unique identifier for a Siafund output. + + Signature: + type: string + format: byte + pattern: "[0-9a-fA-F]{64}" + description: A ed25519 signature + SignedCurrency: type: string pattern: "^-?\\d+$" maxLength: 39 # fits 2^128 - 1 description: A signed amount of Hastings, the smallest unit of currency in Sia. 1 Siacoin (SC) equals 10^24 Hastings (H). + StateElement: + type: object + properties: + leafIndex: + type: integer + format: uint64 + description: The index of the element in the Merkle tree + merkleProof: + type: array + description: The Merkle proof demonstrating the inclusion of the leaf + items: + $ref: "#/components/schemas/Hash256" + + StorageProof: + type: object + description: Represents a proof of storage for a file contract. + properties: + parentID: + allOf: + - $ref: "#/components/schemas/FileContractID" + - description: The ID of the file contract being proven. + leaf: + type: string + format: byte + description: The selected leaf from the Merkle tree of the file's data. + proof: + type: array + description: The Merkle proof demonstrating the inclusion of the leaf. + items: + $ref: "#/components/schemas/Hash256" + + Transaction: + type: object + properties: + siacoinInputs: + type: array + description: List of Siacoin inputs used in the transaction. + items: + $ref: "#/components/schemas/SiacoinInput" + siacoinOutputs: + type: array + description: List of Siacoin outputs created by the transaction. + items: + $ref: "#/components/schemas/SiacoinOutput" + fileContracts: + type: array + description: List of file contracts created by the transaction. + items: + $ref: "#/components/schemas/FileContract" + fileContractRevisions: + type: array + description: List of revisions to existing file contracts included in the transaction. + items: + $ref: "#/components/schemas/FileContractRevision" + storageProofs: + type: array + description: List of storage proofs asserting the storage of data for file contracts. + items: + $ref: "#/components/schemas/StorageProof" + siafundInputs: + type: array + description: List of Siafund inputs spent in the transaction. + items: + $ref: "#/components/schemas/SiafundInput" + siafundOutputs: + type: array + description: List of Siafund outputs created by the transaction. + items: + $ref: "#/components/schemas/SiafundOutput" + minerFees: + type: array + description: List of miner fees included in the transaction. + items: + $ref: "#/components/schemas/Currency" + arbitraryData: + type: array + description: Arbitrary binary data included in the transaction. + items: + type: string + format: byte + signatures: + type: array + description: List of cryptographic signatures verifying the transaction. + items: + $ref: "#/components/schemas/TransactionSignature" + + TransactionSignature: + type: object + properties: + parentID: + allOf: + - $ref: "#/components/schemas/Hash256" + - description: The ID of the transaction being signed + publicKeyIndex: + type: integer + format: uint64 + description: The index of the public key used to sign the transaction + timelock: + type: integer + format: uint64 + description: The block height at which the output can be spent + coveredFields: + allOf: + - $ref: "#/components/schemas/CoveredFields" + - description: Indicates which fields of the transaction are covered by the signature + signature: + type: string + format: byte + description: The signature of the transaction + + UnlockConditions: + type: object + properties: + timelock: + type: integer + format: uint64 + description: The block height at which the output can be spent + publicKeys: + type: array + items: + $ref: "#/components/schemas/UnlockKey" + signaturesRequired: + type: integer + format: uint64 + description: The number of signatures required to spend the output + + UnlockKey: + type: object + properties: + algorithm: + type: string + format: bytes + key: + type: string + format: bytes + + V2BlockData: + type: object + properties: + height: + type: integer + format: uint64 + description: The height of the block + commitment: + $ref: "#/components/schemas/Hash256" + transactions: + type: array + items: + $ref: "#/components/schemas/V2Transaction" + + V2FileContract: + type: object + properties: + capacity: + type: integer + format: uint64 + filesize: + type: integer + format: uint64 + fileMerkleRoot: + $ref: "#/components/schemas/Hash256" + proofHeight: + type: integer + format: uint64 + expirationHeight: + type: integer + format: uint64 + renterOutput: + $ref: "#/components/schemas/SiacoinOutput" + hostOutput: + $ref: "#/components/schemas/SiacoinOutput" + missedHostValue: + $ref: "#/components/schemas/Currency" + totalCollateral: + $ref: "#/components/schemas/Currency" + renterPublicKey: + $ref: "#/components/schemas/PublicKey" + hostPublicKey: + $ref: "#/components/schemas/PublicKey" + revisionNumber: + type: integer + format: uint64 + renterSignature: + $ref: "#/components/schemas/Signature" + hostSignature: + $ref: "#/components/schemas/Signature" + + V2FileContractElement: + type: object + properties: + id: + allOf: + - $ref: "#/components/schemas/FileContractID" + - description: The ID of the element + stateElement: + allOf: + - $ref: "#/components/schemas/StateElement" + - description: The state of the element + v2FileContract: + $ref: "#/components/schemas/V2FileContract" + + V2FileContractResolution: + type: object + properties: + parent: + $ref: "#/components/schemas/V2FileContractElement" + resolution: + type: object + + V2FileContractRevision: + type: object + properties: + parent: + $ref: "#/components/schemas/V2FileContractElement" + revision: + $ref: "#/components/schemas/V2FileContract" + + V2SiacoinInput: + type: object + properties: + parent: + $ref: "#/components/schemas/SiacoinElement" + satisfiedPolicy: + $ref: "#/components/schemas/SatisfiedPolicy" + + V2SiafundInput: + type: object + properties: + parent: + $ref: "#/components/schemas/SiafundElement" + claimAddress: + $ref: "#/components/schemas/Address" + satisfiedPolicy: + $ref: "#/components/schemas/SatisfiedPolicy" + + V2Transaction: + type: object + properties: + siacoinInputs: + type: array + items: + $ref: "#/components/schemas/V2SiacoinInput" + siacoinOutputs: + type: array + items: + $ref: "#/components/schemas/SiacoinOutput" + siafundInputs: + type: array + items: + $ref: "#/components/schemas/V2SiafundInput" + siafundOutputs: + type: array + items: + $ref: "#/components/schemas/SiafundOutput" + fileContracts: + type: array + items: + $ref: "#/components/schemas/V2FileContract" + fileContractRevisions: + type: array + items: + $ref: "#/components/schemas/V2FileContractRevision" + fileContractResolutions: + type: array + items: + $ref: "#/components/schemas/V2FileContractResolution" + attestations: + type: array + items: + $ref: "#/components/schemas/Attestation" + arbitraryData: + type: array + items: + type: string + format: byte + newFoundationAddress: + $ref: "#/components/schemas/Address" + minerFee: + $ref: "#/components/schemas/Currency" + ############################# # # Helper types @@ -1290,6 +1927,21 @@ components: gougingSettings: $ref: "#/components/schemas/GougingSettings" + ConsensusState: + type: object + properties: + blockHeight: + type: integer + format: uint64 + description: The current block height + lastBlockTime: + type: string + format: date-time + description: The time of the last block + synced: + type: boolean + description: Whether the node is synced with the network + ContractsConfig: type: object properties: @@ -1413,6 +2065,118 @@ components: pattern: ^[0-9a-fA-F]{64}$ description: A unique identifier for a multipart upload + Network: + type: object + properties: + name: + type: string + description: The name of the network + initialCoinbase: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The initial coinbase reward + minimumCoinbase: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The minimum coinbase reward + initialTarget: + allOf: + - $ref: "#/components/schemas/BlockID" + - description: The initial target + blockInterval: + type: integer + format: uint64 + description: The block interval + maturityDelay: + type: integer + format: uint64 + description: The maturity delay + hardforkDevAddr: + type: object + properties: + height: + type: integer + format: uint64 + description: The height of the hardfork + oldAddress: + allOf: + - $ref: "#/components/schemas/Address" + - description: The old developer address + newAddress: + allOf: + - $ref: "#/components/schemas/Address" + - description: The new developer address + hardforkTax: + type: object + properties: + height: + type: integer + format: uint64 + description: The height of the hardfork + hardforkStorageProof: + type: object + properties: + height: + type: integer + format: uint64 + description: The height of the hardfork + hardforkOak: + type: object + properties: + height: + type: integer + format: uint64 + description: The height of the hardfork + fixHeight: + type: integer + format: uint64 + description: The fix height + genesisTimestamp: + type: string + format: date-time + description: The genesis timestamp + hardforkASIC: + type: object + properties: + height: + type: integer + format: uint64 + description: The height of the hardfork + oakTime: + type: integer + format: uint64 + description: The oak time + oakTarget: + allOf: + - $ref: "#/components/schemas/BlockID" + - description: The oak target + hardforkFoundation: + type: object + properties: + height: + type: integer + format: uint64 + description: The height of the hardfork + primaryAddress: + allOf: + - $ref: "#/components/schemas/Address" + - description: The primary address + failsafeAddress: + allOf: + - $ref: "#/components/schemas/Address" + - description: The failsafe address + hardforkV2: + type: object + properties: + allowHeight: + type: integer + format: uint64 + description: The allow height + requireHeight: + type: integer + format: uint64 + description: The require height + RedundancySettings: type: object properties: From 85eac7725166e12c0a04729d4c4a6d4c179645e3 Mon Sep 17 00:00:00 2001 From: PJ Date: Thu, 12 Dec 2024 16:03:53 +0100 Subject: [PATCH 02/12] docs: add syncer routes --- .changeset/extend_openapi_spec.md | 3 +- openapi.yml | 50 +++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/.changeset/extend_openapi_spec.md b/.changeset/extend_openapi_spec.md index 0d8880205..9809532f1 100644 --- a/.changeset/extend_openapi_spec.md +++ b/.changeset/extend_openapi_spec.md @@ -5,4 +5,5 @@ default: minor # Extend OpenAPI spec The following routes were added: -- consensus \ No newline at end of file +- consensus +- syncer \ No newline at end of file diff --git a/openapi.yml b/openapi.yml index ff536be80..bf5c4bcca 100644 --- a/openapi.yml +++ b/openapi.yml @@ -1176,6 +1176,51 @@ paths: schema: $ref: "#/components/schemas/ConsensusState" + /bus/syncer/address: + get: + summary: Get the syncer's address + description: Returns the address of the syncer. + responses: + "200": + description: Successfully retrieved syncer address + content: + application/json: + schema: + $ref: "#/components/schemas/SyncerAddress" + /bus/syncer/connect: + post: + summary: Connect to a syncer + description: Connects to the specified syncer. + requestBody: + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/SyncerAddress" + - description: The address of the syncer to connect to + responses: + "200": + description: Successfully connected to syncer + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + /bus/syncer/peers: + get: + summary: Get syncer peers + description: Returns the syncer's peers. + responses: + "200": + description: Successfully retrieved syncer peers + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/SyncerAddress" + components: schemas: ############################# @@ -2227,3 +2272,8 @@ components: minimum: 1 maximum: 255 description: The number of data shards the slab is split into + + SyncerAddress: + type: string + description: The address of the syncer + example: "118.92.232.145:9981" \ No newline at end of file From 3309123f8d392e3356a1ab54b63727391c6c1e30 Mon Sep 17 00:00:00 2001 From: PJ Date: Thu, 12 Dec 2024 16:17:05 +0100 Subject: [PATCH 03/12] docs: add txpool routes --- .changeset/extend_openapi_spec.md | 3 +- openapi.yml | 55 +++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/.changeset/extend_openapi_spec.md b/.changeset/extend_openapi_spec.md index 9809532f1..45b8be8df 100644 --- a/.changeset/extend_openapi_spec.md +++ b/.changeset/extend_openapi_spec.md @@ -6,4 +6,5 @@ default: minor The following routes were added: - consensus -- syncer \ No newline at end of file +- syncer +- txpool \ No newline at end of file diff --git a/openapi.yml b/openapi.yml index bf5c4bcca..1041b4387 100644 --- a/openapi.yml +++ b/openapi.yml @@ -1221,6 +1221,61 @@ paths: items: $ref: "#/components/schemas/SyncerAddress" + /bus/txpool/recommendedfee: + get: + summary: Get recommended fee + description: Returns the recommended fee for a transaction. + responses: + "200": + description: Successfully retrieved recommended fee + content: + application/json: + schema: + $ref: "#/components/schemas/Currency" + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + /bus/txpool/transactions: + get: + summary: Get all transactions + description: Returns all transactions in the transaction pool. + responses: + "200": + description: Successfully retrieved transactions + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/Transaction" + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + /bus/txpool/broadcast: + post: + summary: Broadcast transaction + description: Broadcasts the specified transaction. + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/Transaction" + responses: + "200": + description: Successfully broadcast transaction + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + components: schemas: ############################# From cc05c458498a9d9edddf3e29d1ad16efd37d8489 Mon Sep 17 00:00:00 2001 From: PJ Date: Thu, 12 Dec 2024 16:58:01 +0100 Subject: [PATCH 04/12] docs: add wallet routes --- .changeset/extend_openapi_spec.md | 3 +- openapi.yml | 244 ++++++++++++++++++++++++++++++ 2 files changed, 246 insertions(+), 1 deletion(-) diff --git a/.changeset/extend_openapi_spec.md b/.changeset/extend_openapi_spec.md index 45b8be8df..ca506cb12 100644 --- a/.changeset/extend_openapi_spec.md +++ b/.changeset/extend_openapi_spec.md @@ -7,4 +7,5 @@ default: minor The following routes were added: - consensus - syncer -- txpool \ No newline at end of file +- txpool +- wallet \ No newline at end of file diff --git a/openapi.yml b/openapi.yml index 1041b4387..f3eb66c93 100644 --- a/openapi.yml +++ b/openapi.yml @@ -1276,6 +1276,199 @@ paths: schema: type: string + /bus/wallet: + get: + summary: Get wallet information + description: Returns information about the wallet. + responses: + "200": + description: Successfully retrieved wallet + content: + application/json: + schema: + type: object + properties: + spendable: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The amount of spendable siacoins in the wallet + confirmed: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The amount of siacoins that have been confirmed in a block + unconfirmed: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The amount of siacoins that have not been confirmed in a block + immature: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The amount of siacoins that have yet to mature + address: + allOf: + - $ref: "#/components/schemas/Address" + - description: The wallet's address + scanHeight: + type: integer + format: uint64 + description: The height up until which the wallet is synced + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + /bus/wallet/events: + get: + summary: Get wallet events + description: Returns all events related to the wallet. + parameters: + - name: limit + in: query + description: The maximum number of events to return + schema: + type: integer + minimum: -1 + default: -1 + - name: offset + in: query + description: The number of events to skip + schema: + type: integer + minimum: 0 + default: 0 + responses: + "200": + description: Successfully retrieved wallet events + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/Event" + "400": + description: Malformed request + content: + text/plain: + schema: + type: string + examples: + invalidLimit: + summary: Invalid limit example + value: "limit must be greater than or equal to -1" + invalidOffset: + summary: Invalid offset example + value: "offset must be greater than or equal to 0" + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + /bus/wallet/pending: + get: + summary: Get unconfirmed events + description: Returns all unconfirmed events in the wallet. + responses: + "200": + description: Successfully retrieved pending events + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/Event" + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + /bus/wallet/redistribute: + post: + summary: Redistribute wallet funds + description: Redistributes the wallet's funds into desired number of outputs of requested value. + requestBody: + content: + application/json: + schema: + type: object + properties: + outputs: + type: integer + format: uint64 + description: The number of outputs to redistribute the wallet's funds into + amount: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The value of each output + responses: + "200": + description: Successfully redistributed wallet funds + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/TransactionID" + "400": + description: Malformed request + content: + text/plain: + schema: + type: string + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + /bus/wallet/send: + post: + summary: Send siacoins + description: Sends the specified amount of siacoins to the specified address. + requestBody: + content: + application/json: + schema: + type: object + properties: + address: + allOf: + - $ref: "#/components/schemas/Address" + - description: The address to send the siacoins to + amount: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The amount of siacoins to send + subtractMinerFee: + type: boolean + description: Whether to subtract the miner fee from the amount + useUnconfirmed: + type: boolean + description: Whether to use unconfirmed outputs + responses: + "200": + description: Successfully sent siacoins + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/TransactionID" + - description: The ID of the transaction + "400": + description: Malformed request + content: + text/plain: + schema: + type: string + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + components: schemas: ############################# @@ -1391,6 +1584,18 @@ components: - $ref: "#/components/schemas/Hash256" - description: A unique identifier for a block + ChainIndex: + type: object + properties: + height: + type: integer + format: uint64 + description: The height of the block in the blockchain + id: + allOf: + - $ref: "#/components/schemas/BlockID" + - description: The ID of the block + CoveredFields: type: object properties: @@ -1773,6 +1978,11 @@ components: items: $ref: "#/components/schemas/TransactionSignature" + TransactionID: + allOf: + - $ref: "#/components/schemas/Hash256" + - description: Unique identifier for a transaction. + TransactionSignature: type: object properties: @@ -2090,6 +2300,40 @@ components: pattern: '^(W/)?".*?"$' description: An ETag representing a resource + Event: + type: object + description: A transaction or other event that affects the wallet including miner payouts, siafund claims, and file contract payouts. + properties: + id: + allOf: + - $ref: "#/components/schemas/Hash256" + - description: The event's ID + index: + allOf: + - $ref: "#/components/schemas/ChainIndex" + - description: Information about the block that triggered the creation of this event + confirmations: + type: integer + format: uint64 + description: The number of blocks on top of the block that triggered the creation of this event + type: + type: string + description: The type of the event + data: + type: object + maturityHeight: + type: integer + format: uint64 + description: The block height when the event's data can be used + timestamp: + type: string + format: date-time + description: The time the event was created + relevant: + type: array + items: + $ref: "#/components/schemas/Address" + GougingSettings: type: object properties: From 394f3de828320b5568bf6918044e96adeb76cb51 Mon Sep 17 00:00:00 2001 From: PJ Date: Thu, 12 Dec 2024 17:03:22 +0100 Subject: [PATCH 05/12] docs: update changelog to patch --- .changeset/extend_openapi_spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/extend_openapi_spec.md b/.changeset/extend_openapi_spec.md index ca506cb12..c6eec6212 100644 --- a/.changeset/extend_openapi_spec.md +++ b/.changeset/extend_openapi_spec.md @@ -1,5 +1,5 @@ --- -default: minor +default: patch --- # Extend OpenAPI spec From 9d7e464a74ce8689f7917d9452460f1b1eb8fa12 Mon Sep 17 00:00:00 2001 From: PJ Date: Mon, 16 Dec 2024 09:54:13 +0100 Subject: [PATCH 06/12] docs: add examples --- openapi.yml | 124 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 77 insertions(+), 47 deletions(-) diff --git a/openapi.yml b/openapi.yml index f3eb66c93..8801a2f1d 100644 --- a/openapi.yml +++ b/openapi.yml @@ -729,6 +729,7 @@ paths: text/plain: schema: type: string + /bus/accounts/fund: post: summary: Fund account @@ -854,6 +855,7 @@ paths: text/plain: schema: type: string + /bus/alerts/dismiss: post: summary: Dismiss alerts @@ -874,6 +876,7 @@ paths: text/plain: schema: type: string + /bus/alerts/register: post: summary: Register an alert @@ -1003,6 +1006,7 @@ paths: text/plain: schema: type: string + /bus/bucket/{name}/policy: put: summary: Update bucket policy @@ -1045,6 +1049,7 @@ paths: text/plain: schema: type: string + /bus/bucket/{name}: get: summary: Get bucket @@ -1129,6 +1134,7 @@ paths: text/plain: schema: type: string + /bus/consensus/network: get: summary: Get network details @@ -1140,6 +1146,7 @@ paths: application/json: schema: $ref: "#/components/schemas/Network" + /bus/consensus/siafundfee/{payout}: get: summary: Get siafund fee @@ -1164,6 +1171,7 @@ paths: text/plain: schema: type: string + /bus/consensus/state: get: summary: Get consensus state @@ -1187,6 +1195,7 @@ paths: application/json: schema: $ref: "#/components/schemas/SyncerAddress" + /bus/syncer/connect: post: summary: Connect to a syncer @@ -1207,6 +1216,7 @@ paths: text/plain: schema: type: string + /bus/syncer/peers: get: summary: Get syncer peers @@ -1238,6 +1248,7 @@ paths: text/plain: schema: type: string + /bus/txpool/transactions: get: summary: Get all transactions @@ -1257,6 +1268,7 @@ paths: text/plain: schema: type: string + /bus/txpool/broadcast: post: summary: Broadcast transaction @@ -1318,6 +1330,7 @@ paths: text/plain: schema: type: string + /bus/wallet/events: get: summary: Get wallet events @@ -1365,6 +1378,7 @@ paths: text/plain: schema: type: string + /bus/wallet/pending: get: summary: Get unconfirmed events @@ -1384,6 +1398,7 @@ paths: text/plain: schema: type: string + /bus/wallet/redistribute: post: summary: Redistribute wallet funds @@ -1423,6 +1438,7 @@ paths: text/plain: schema: type: string + /bus/wallet/send: post: summary: Send siacoins @@ -1588,9 +1604,9 @@ components: type: object properties: height: - type: integer - format: uint64 - description: The height of the block in the blockchain + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The height of the block in the blockchain id: allOf: - $ref: "#/components/schemas/BlockID" @@ -1672,13 +1688,13 @@ components: - $ref: "#/components/schemas/Hash256" - description: The Merkle root of the contract's data. windowStart: - type: integer - format: uint64 - description: The block height when the contract's proof window starts. + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The block height when the contract's proof window starts. windowEnd: - type: integer - format: uint64 - description: The block height when the contract's proof window ends. + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The block height when the contract's proof window ends. payout: allOf: - $ref: "#/components/schemas/Currency" @@ -1694,11 +1710,9 @@ components: items: $ref: "#/components/schemas/SiacoinOutput" unlockHash: - $ref: "#/components/schemas/Address" + $ref: "#/components/schemas/Address" revisionNumber: - type: integer - format: uint64 - description: The revision number of the contract. + $ref: "#/components/schemas/RevisionNumber" FileContractID: allOf: @@ -1726,13 +1740,13 @@ components: - $ref: "#/components/schemas/Hash256" - description: The updated Merkle root of the file's data. windowStart: - type: integer - format: uint64 - description: The block height when the revised proof window starts. + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The block height when the revised proof window starts. windowEnd: - type: integer - format: uint64 - description: The block height when the revised proof window ends. + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The block height when the revised proof window ends. validProofOutputs: type: array description: Updated outputs if the revised contract is successfully fulfilled. @@ -1748,9 +1762,7 @@ components: - $ref: "#/components/schemas/Address" - description: The updated hash of the conditions required to unlock the contract funds. revisionNumber: - type: integer - format: uint64 - description: The updated revision number of the contract. + $ref: "#/components/schemas/RevisionNumber" Hash256: type: string @@ -1770,8 +1782,7 @@ components: signature: type: array items: - type: string - format: byte + $ref: "#/components/schemas/Signature" preimages: type: array items: @@ -1794,9 +1805,9 @@ components: - $ref: "#/components/schemas/SiacoinOutput" - description: The output of the element maturityHeight: - type: integer - format: uint64 - description: The block height when the output matures + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The block height when the output matures SiacoinInput: type: object @@ -1995,25 +2006,25 @@ components: format: uint64 description: The index of the public key used to sign the transaction timelock: - type: integer - format: uint64 - description: The block height at which the output can be spent + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The block height at which the outputs in the transaction can be spent coveredFields: allOf: - $ref: "#/components/schemas/CoveredFields" - description: Indicates which fields of the transaction are covered by the signature signature: - type: string - format: byte - description: The signature of the transaction + allOf: + - $ref: "#/components/schemas/Signature" + - description: The signature of the transaction UnlockConditions: type: object properties: timelock: - type: integer - format: uint64 - description: The block height at which the output can be spent + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The block height at which the outputs can be spent publicKeys: type: array items: @@ -2037,9 +2048,9 @@ components: type: object properties: height: - type: integer - format: uint64 - description: The height of the block + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The height of the block commitment: $ref: "#/components/schemas/Hash256" transactions: @@ -2077,8 +2088,7 @@ components: hostPublicKey: $ref: "#/components/schemas/PublicKey" revisionNumber: - type: integer - format: uint64 + $ref: "#/components/schemas/RevisionNumber" renterSignature: $ref: "#/components/schemas/Signature" hostSignature: @@ -2193,6 +2203,12 @@ components: hosts: $ref: "#/components/schemas/HostsConfig" + BlockHeight: + type: integer + format: uint64 + description: The height of a block + example: 92813 + Bucket: type: object properties: @@ -2241,9 +2257,9 @@ components: type: object properties: blockHeight: - type: integer - format: uint64 - description: The current block height + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The current block height lastBlockTime: type: string format: date-time @@ -2318,13 +2334,21 @@ components: description: The number of blocks on top of the block that triggered the creation of this event type: type: string + enum: + - miner + - foundation + - siafundClaim + - v1Transaction + - v1ContractResolution + - v2Transaction + - v2ContractResolution description: The type of the event data: type: object maturityHeight: - type: integer - format: uint64 - description: The block height when the event's data can be used + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The block height at which the payout matures. timestamp: type: string format: date-time @@ -2535,6 +2559,12 @@ components: format: int32 description: The number of total data shards a piece of an object gets erasure-coded into + RevisionNumber: + type: integer + format: uint64 + description: The revision number of the contract + example: 246 + Sector: type: object description: Description of an uploaded sector From dd179240551765dcff47217fe94a1b7587feccc2 Mon Sep 17 00:00:00 2001 From: PJ Date: Mon, 16 Dec 2024 10:47:57 +0100 Subject: [PATCH 07/12] docs: add unlock key example --- openapi.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openapi.yml b/openapi.yml index 8801a2f1d..865836ba9 100644 --- a/openapi.yml +++ b/openapi.yml @@ -2040,9 +2040,17 @@ components: algorithm: type: string format: bytes + description: | + A fixed 16-byte array that specifies the algorithm used to generate + the key + example: "ed25519" key: + description: | + A 32-byte key represented as a hex-encoded string. Must be exactly + 64 characters long, containing only hexadecimal digits type: string format: bytes + pattern: "^[a-fA-F0-9]{64}$" V2BlockData: type: object From ebccf978cd997da90db03f24a5bb6d7fd6b7bf78 Mon Sep 17 00:00:00 2001 From: PJ Date: Mon, 16 Dec 2024 11:16:42 +0100 Subject: [PATCH 08/12] docs: extend open API spec --- .changeset/extend_openapi_spec.md | 2 +- bus/routes.go | 2 +- openapi.yml | 82 ++++++++++++++++++------------- 3 files changed, 51 insertions(+), 35 deletions(-) diff --git a/.changeset/extend_openapi_spec.md b/.changeset/extend_openapi_spec.md index c6eec6212..e4831ecd8 100644 --- a/.changeset/extend_openapi_spec.md +++ b/.changeset/extend_openapi_spec.md @@ -1,5 +1,5 @@ --- -default: patch +default: major --- # Extend OpenAPI spec diff --git a/bus/routes.go b/bus/routes.go index 2fe14b41a..3d6c03f61 100644 --- a/bus/routes.go +++ b/bus/routes.go @@ -219,7 +219,7 @@ func (b *Bus) consensusStateHandler(jc jape.Context) { } func (b *Bus) consensusNetworkHandler(jc jape.Context) { - jc.Encode(*b.cm.TipState().Network) + jc.Encode(b.cm.TipState().Network) } func (b *Bus) postSystemSQLite3BackupHandler(jc jape.Context) { diff --git a/openapi.yml b/openapi.yml index 865836ba9..85d1872dd 100644 --- a/openapi.yml +++ b/openapi.yml @@ -1593,12 +1593,9 @@ components: $ref: "#/components/schemas/V2BlockData" BlockID: - type: object - properties: - id: - allOf: - - $ref: "#/components/schemas/Hash256" - - description: A unique identifier for a block + allOf: + - $ref: "#/components/schemas/Hash256" + - description: A unique identifier for a block ChainIndex: type: object @@ -2451,73 +2448,87 @@ components: allOf: - $ref: "#/components/schemas/Currency" - description: The initial coinbase reward + - default: "300000000000000000000000000000" minimumCoinbase: allOf: - $ref: "#/components/schemas/Currency" - description: The minimum coinbase reward + - default: "30000000000000000000000000000" initialTarget: allOf: - $ref: "#/components/schemas/BlockID" - description: The initial target + - default: "0000000020000000000000000000000000000000000000000000000000000000" blockInterval: type: integer format: uint64 description: The block interval + default: 600000000000 maturityDelay: type: integer format: uint64 description: The maturity delay + default: 144 hardforkDevAddr: type: object properties: height: - type: integer - format: uint64 - description: The height of the hardfork + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The height of the hardfork + - example: 10000 oldAddress: allOf: - $ref: "#/components/schemas/Address" - description: The old developer address + - default: "7d0c44f7664e2d34e53efde0661a6f628ec9264785ae8e3cd7c973e8d190c3c97b5e3ecbc567" newAddress: allOf: - $ref: "#/components/schemas/Address" - description: The new developer address + - default: "f371c70bce9eb8979cd5099f599ec4e4fcb14e0afcf31f9791e03e6496a4c0b358c98279730b" hardforkTax: type: object properties: height: - type: integer - format: uint64 - description: The height of the hardfork + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The height of the hardfork + - example: 21000 hardforkStorageProof: type: object properties: height: - type: integer - format: uint64 - description: The height of the hardfork + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The height of the hardfork + - example: 100000 hardforkOak: type: object properties: height: - type: integer - format: uint64 - description: The height of the hardfork + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The height of the hardfork + - example: 135000 fixHeight: - type: integer - format: uint64 - description: The fix height + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The height of the fix + - example: 139000 genesisTimestamp: type: string format: date-time description: The genesis timestamp + default: "2015-06-06T16:13:20+02:00" hardforkASIC: type: object properties: height: - type: integer - format: uint64 - description: The height of the hardfork + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The height of the hardfork + - example: 179000 oakTime: type: integer format: uint64 @@ -2530,28 +2541,33 @@ components: type: object properties: height: - type: integer - format: uint64 - description: The height of the hardfork + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The height of the hardfork + - example: 298000 primaryAddress: allOf: - $ref: "#/components/schemas/Address" - description: The primary address + - default: "053b2def3cbdd078c19d62ce2b4f0b1a3c5e0ffbeeff01280efb1f8969b2f5bb4fdc680f0807" failsafeAddress: allOf: - $ref: "#/components/schemas/Address" - description: The failsafe address + - default: "27c22a6c6e6645802a3b8fa0e5374657438ef12716d2205d3e866272de1b644dbabd53d6d560" hardforkV2: type: object properties: allowHeight: - type: integer - format: uint64 - description: The allow height + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The height at which V2 consensus types are allowed + - example: 1000000 requireHeight: - type: integer - format: uint64 - description: The require height + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The height at which V2 consensus types are required + - example: 1025000 RedundancySettings: type: object From 2abb5c396fc0451ca807f95cae45e4793060d908 Mon Sep 17 00:00:00 2001 From: PJ Date: Mon, 16 Dec 2024 13:41:52 +0100 Subject: [PATCH 09/12] docs: add contracts routes --- .changeset/extend_openapi_spec.md | 1 + bus/routes.go | 2 +- openapi.yml | 379 +++++++++++++++++++++++++++++- 3 files changed, 378 insertions(+), 4 deletions(-) diff --git a/.changeset/extend_openapi_spec.md b/.changeset/extend_openapi_spec.md index e4831ecd8..01d2cbe8c 100644 --- a/.changeset/extend_openapi_spec.md +++ b/.changeset/extend_openapi_spec.md @@ -6,6 +6,7 @@ default: major The following routes were added: - consensus +- contracts - syncer - txpool - wallet \ No newline at end of file diff --git a/bus/routes.go b/bus/routes.go index 3d6c03f61..b7f1afa27 100644 --- a/bus/routes.go +++ b/bus/routes.go @@ -787,7 +787,7 @@ func (b *Bus) contractsHandlerGET(jc jape.Context) { case api.ContractFilterModeArchived: case api.ContractFilterModeGood: default: - jc.Error(fmt.Errorf("invalid filter mode: '%v'", filterMode), http.StatusBadRequest) + jc.Error(fmt.Errorf("invalid filter mode '%v', must be one of [active, archived, all, good]", filterMode), http.StatusBadRequest) return } diff --git a/openapi.yml b/openapi.yml index 85d1872dd..8fa904dc8 100644 --- a/openapi.yml +++ b/openapi.yml @@ -1184,6 +1184,275 @@ paths: schema: $ref: "#/components/schemas/ConsensusState" + /bus/contracts: + get: + summary: Get all contracts + parameters: + - name: filtermode + in: query + schema: + type: string + enum: [active, archived, all, good] + default: active + responses: + "200": + description: List of contracts + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/ContractMetadata" + "400": + description: Malformed request + content: + text/plain: + schema: + type: string + examples: + invalidFilterMode: + summary: Invalid filter mode example + value: "invalid filter mode 'bad', must be one of [active, archived, all, good]" + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + put: + summary: Add a contract + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ContractMetadata" + responses: + "200": + description: Successfully updated contract + "500": + description: Internal server error + + /contracts/all: + delete: + summary: Archives all contracts + responses: + "200": + description: All contracts where archived successfully + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + + /contracts/archive: + post: + summary: Archive contracts + requestBody: + content: + application/json: + schema: + type: object + description: A mapping of file contract IDs to archive reasons. + additionalProperties: + $ref: "#/components/schemas/FileContractID" + example: + "fcid:fd887808d78b3c8c6c04d1bbc14a0f6ebc2f546514e3a4b79102e31da712423c": "custom reason" + "fcid:82ffce83b89817e876194a07f1b4442052e2bb4932ca80a6a51753d86da3d840": "custom reason" + responses: + "200": + description: Contracts archived successfully + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + + /contracts/form: + post: + summary: Form a new contract + requestBody: + content: + application/json: + schema: + type: object + description: The request body for the POST /contracts endpoint. + properties: + endHeight: + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The block height at which the contract will end. + hostCollateral: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The amount of collateral the host is committing. + hostKey: + allOf: + - $ref: "#/components/schemas/PublicKey" + - description: The public key of the host. + renterFunds: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The funds the renter is committing. + renterAddress: + allOf: + - $ref: "#/components/schemas/Address" + - description: The renter's address + responses: + "200": + description: Contract formed successfully + content: + application/json: + schema: + $ref: "#/components/schemas/ContractMetadata" + "400": + description: Invalid request parameters + content: + text/plain: + schema: + type: string + examples: + invalidEndHeight: + summary: No end height provided + value: "EndHeight can not be zero" + invalidHostKey: + summary: No host key provided + value: "HostKey must be provided" + invalidHostCollateral: + summary: No host collateral provided + value: "HostCollateral can not be zero" + invalidRenterFunds: + summary: No renter funds provided + value: "RenterFunds can not be zero" + invalidRenterAddress: + summary: No renter address provided + value: "RenterAddress must be provided" + "404": + description: Host not found + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + + /contracts/prunable: + get: + summary: Get prunable contract data + responses: + "200": + description: Prunable contract data + content: + application/json: + schema: + type: object + description: The response containing prunable contract data and summary statistics. + properties: + contracts: + type: array + description: A list of prunable contracts with their size information. + items: + type: object + description: Contains the ID and size information of a prunable contract. + properties: + id: + $ref: "#/components/schemas/FileContractID" + prunable: + type: integer + format: uint64 + description: The amount of prunable data in bytes. + size: + type: integer + format: uint64 + description: The size of the contract in bytes + example: + totalPrunable: + type: integer + format: uint64 + description: The total prunable size across all contracts in bytes + totalSize: + type: integer + format: uint64 + description: The total size of all contracts in bytes + + /contracts/renewed/{id}: + get: + summary: Get renewed contract + parameters: + - name: id + in: path + required: true + schema: + $ref: "#/components/schemas/FileContractID" + responses: + "200": + description: Renewed contract metadata + content: + application/json: + schema: + $ref: "#/components/schemas/ContractMetadata" + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + + /contracts/spending: + post: + summary: Record contract spending + requestBody: + content: + application/json: + schema: + type: array + items: + type: object + properties: + deletions: + allOf: + - $ref: "#/components/schemas/Currency" + - description: Total amount spent on sector deletions + fundAccount: + allOf: + - $ref: "#/components/schemas/Currency" + - description: Total amount spent on funding ephemeral accounts + sectorRoots: + allOf: + - $ref: "#/components/schemas/Currency" + - description: Total amount spent on listing sector roots + uploads: + allOf: + - $ref: "#/components/schemas/Currency" + - description: Total amount spent on storing sectors + + contractID: + $ref: "#/components/schemas/FileContractID" + revisionNumber: + $ref: "#/components/schemas/RevisionNumber" + size: + type: integer + format: uint64 + description: The size of the contract in bytes + missedHostPayout: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The amount of siacoins that the host will receive if the contract resolves missed + validRenterPayout: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The amount of siacoins that the renter will receive if the contract resolves valid. + responses: + "200": + description: Spending recorded successfully + "500": + description: Internal server error + content: + text/plain: + schema: + type: string + /bus/syncer/address: get: summary: Get the syncer's address @@ -1609,6 +1878,110 @@ components: - $ref: "#/components/schemas/BlockID" - description: The ID of the block + ContractMetadata: + type: object + properties: + id: + allOf: + - $ref: "#/components/schemas/FileContractID" + - description: The unique identifier for the file contract. + hostKey: + allOf: + - $ref: "#/components/schemas/PublicKey" + - description: The public key of the host. + v2: + type: boolean + description: Indicates if the contract is a V2 contract. + proofHeight: + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The height at which the storage proof needs to be submitted + renewedFrom: + allOf: + - $ref: "#/components/schemas/FileContractID" + - description: The ID of the contract this one was renewed from + revisionHeight: + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The block height of the latest revision + revisionNumber: + allOf: + - $ref: "#/components/schemas/RevisionNumber" + - description: The current revision number of the contract + size: + type: integer + format: uint64 + description: The size of the contract in bytes + startHeight: + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The block height at which the contract created + state: + type: string + description: The state of the contract + enum: + - pending + - active + - complete + - failed + usability: + type: string + description: The usability status of the contract + enum: + - good + - bad + windowStart: + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The block height when the contract's proof window starts. + windowEnd: + allOf: + - $ref: "#/components/schemas/BlockHeight" + - description: The block height when the contract's proof window ends. + contractPrice: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The price of forming the contract. + initialRenterFunds: + allOf: + - $ref: "#/components/schemas/Currency" + - description: The initial funds provided by the renter. + spending: + allOf: + - $ref: "#/components/schemas/ContractSpending" + - description: Costs and spending details of the contract. + archivalReason: + type: string + description: The reason for archiving the contract, if applicable. + enum: + - renewed + - removed + - hostpruned + renewedTo: + allOf: + - $ref: "#/components/schemas/FileContractID" + - description: The ID of the contract this one was renewed to, if applicable. + + ContractSpending: + type: object + properties: + deletions: + allOf: + - $ref: "#/components/schemas/Currency" + - description: Total amount spent on sector deletions + fundAccount: + allOf: + - $ref: "#/components/schemas/Currency" + - description: Total amount spent on funding ephemeral accounts + sectorRoots: + allOf: + - $ref: "#/components/schemas/Currency" + - description: Total amount spent on listing sector roots + uploads: + allOf: + - $ref: "#/components/schemas/Currency" + - description: Total amount spent on storing sectors + CoveredFields: type: object properties: @@ -1712,9 +2085,9 @@ components: $ref: "#/components/schemas/RevisionNumber" FileContractID: - allOf: - - $ref: "#/components/schemas/Hash256" - - description: A unique identifier for a file contract + type: string + pattern: "^fcid:[0-9a-fA-F]{64}$" + description: A unique identifier for a file contract FileContractRevision: type: object From 00de3d69fe13dbac7b0cec186bd9eb19c0e27533 Mon Sep 17 00:00:00 2001 From: Chris Schinnerl Date: Mon, 16 Dec 2024 07:32:43 +0100 Subject: [PATCH 10/12] chore(deps): update core/coreutils dependencies --- go.mod | 4 ++-- go.sum | 8 ++++---- internal/rhp/v4/rhp.go | 3 ++- internal/test/e2e/host.go | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index a2820e7f2..6279c620f 100644 --- a/go.mod +++ b/go.mod @@ -14,8 +14,8 @@ require ( github.com/mattn/go-sqlite3 v1.14.24 github.com/montanaflynn/stats v0.7.1 github.com/shopspring/decimal v1.4.0 - go.sia.tech/core v0.7.2-0.20241210224920-0534a5928ddb - go.sia.tech/coreutils v0.7.1-0.20241211045514-6881993d8806 + go.sia.tech/core v0.8.0 + go.sia.tech/coreutils v0.8.0 go.sia.tech/gofakes3 v0.0.5 go.sia.tech/hostd v1.1.3-0.20241212081824-0f6d95b852db go.sia.tech/jape v0.12.1 diff --git a/go.sum b/go.sum index c5157f74d..1c2f29700 100644 --- a/go.sum +++ b/go.sum @@ -55,10 +55,10 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= -go.sia.tech/core v0.7.2-0.20241210224920-0534a5928ddb h1:JHX+qWKS9sAXmEroICAu2jPQkr3CYUF7iWd/zlATsBM= -go.sia.tech/core v0.7.2-0.20241210224920-0534a5928ddb/go.mod h1:tM9tPD+1jp8d+dqVpX6idTyv5RpI0GEh5L5SyuOpqlc= -go.sia.tech/coreutils v0.7.1-0.20241211045514-6881993d8806 h1:zmLtpmFQPKMukYMiQByZzOODvMshriyLhK12BnIsmU8= -go.sia.tech/coreutils v0.7.1-0.20241211045514-6881993d8806/go.mod h1:6z3oHrQqcLoFEAT/l6XnvOivEGXgIfWBKcq0OqsouWA= +go.sia.tech/core v0.8.0 h1:J6vZQlVhpj4bTVeuC2GKkfkGEs8jf0j651Kl1wwOxjg= +go.sia.tech/core v0.8.0/go.mod h1:Wj1qzvpMM2rqEQjwWJEbCBbe9VWX/mSJUu2Y2ABl1QA= +go.sia.tech/coreutils v0.8.0 h1:1dcl0vxY+MBgAdJ7PdewAr8RkZJn4/6wAKEZfi4iYn0= +go.sia.tech/coreutils v0.8.0/go.mod h1:ml5MefDMWCvPKNeRVIGHmyF5tv27C9h1PiI/iOiTGLg= go.sia.tech/gofakes3 v0.0.5 h1:vFhVBUFbKE9ZplvLE2w4TQxFMQyF8qvgxV4TaTph+Vw= go.sia.tech/gofakes3 v0.0.5/go.mod h1:LXEzwGw+OHysWLmagleCttX93cJZlT9rBu/icOZjQ54= go.sia.tech/hostd v1.1.3-0.20241212081824-0f6d95b852db h1:ey3ezMYHPzY+FZ4yL8xsAWnCJWI2J9z4rtpmRa8dj0A= diff --git a/internal/rhp/v4/rhp.go b/internal/rhp/v4/rhp.go index 4bb9471df..ccc384f29 100644 --- a/internal/rhp/v4/rhp.go +++ b/internal/rhp/v4/rhp.go @@ -119,7 +119,8 @@ func (c *Client) FundAccounts(ctx context.Context, hk types.PublicKey, hostIP st // LatestRevision returns the latest revision of a contract. func (c *Client) LatestRevision(ctx context.Context, hk types.PublicKey, addr string, contractID types.FileContractID) (revision types.V2FileContract, _ error) { err := c.tpool.withTransport(ctx, hk, addr, func(c rhp.TransportClient) (err error) { - revision, err = rhp.RPCLatestRevision(ctx, c, contractID) + res, err := rhp.RPCLatestRevision(ctx, c, contractID) + revision = res.Contract return err }) return revision, err diff --git a/internal/test/e2e/host.go b/internal/test/e2e/host.go index b683ab270..5aa01ed3c 100644 --- a/internal/test/e2e/host.go +++ b/internal/test/e2e/host.go @@ -307,7 +307,7 @@ func NewHost(privKey types.PrivateKey, cm *chain.Manager, dir string, network *c rhpv3 := rhpv3.NewSessionHandler(rhp3Listener, privKey, cm, s, wallet, accounts, contracts, registry, storage, settings, log.Named("rhpv3")) go rhpv3.Serve() - rhpv4 := rhp4.NewServer(privKey, cm, s, contracts, wallet, settings, storage, rhp4.WithPriceTableValidity(30*time.Minute), rhp4.WithContractProofWindowBuffer(1)) + rhpv4 := rhp4.NewServer(privKey, cm, s, contracts, wallet, settings, storage, rhp4.WithPriceTableValidity(30*time.Minute)) go rhp.ServeRHP4SiaMux(rhp4Listener, rhpv4, log.Named("rhp4")) return &Host{ From dff56f93cd6f54883599b06cf4ff4777a2cdd310 Mon Sep 17 00:00:00 2001 From: Chris Schinnerl Date: Mon, 16 Dec 2024 09:47:16 +0100 Subject: [PATCH 11/12] address comment and use testutil.NewEphemeralContractor in test host --- internal/rhp/v4/rhp.go | 2 +- internal/test/e2e/host.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/rhp/v4/rhp.go b/internal/rhp/v4/rhp.go index ccc384f29..877e396e9 100644 --- a/internal/rhp/v4/rhp.go +++ b/internal/rhp/v4/rhp.go @@ -118,7 +118,7 @@ func (c *Client) FundAccounts(ctx context.Context, hk types.PublicKey, hostIP st // LatestRevision returns the latest revision of a contract. func (c *Client) LatestRevision(ctx context.Context, hk types.PublicKey, addr string, contractID types.FileContractID) (revision types.V2FileContract, _ error) { - err := c.tpool.withTransport(ctx, hk, addr, func(c rhp.TransportClient) (err error) { + err := c.tpool.withTransport(ctx, hk, addr, func(c rhp.TransportClient) error { res, err := rhp.RPCLatestRevision(ctx, c, contractID) revision = res.Contract return err diff --git a/internal/test/e2e/host.go b/internal/test/e2e/host.go index 5aa01ed3c..8248182b7 100644 --- a/internal/test/e2e/host.go +++ b/internal/test/e2e/host.go @@ -17,6 +17,7 @@ import ( "go.sia.tech/coreutils/chain" rhp4 "go.sia.tech/coreutils/rhp/v4" "go.sia.tech/coreutils/syncer" + "go.sia.tech/coreutils/testutil" "go.sia.tech/coreutils/wallet" "go.sia.tech/hostd/host/accounts" "go.sia.tech/hostd/host/contracts" @@ -307,7 +308,7 @@ func NewHost(privKey types.PrivateKey, cm *chain.Manager, dir string, network *c rhpv3 := rhpv3.NewSessionHandler(rhp3Listener, privKey, cm, s, wallet, accounts, contracts, registry, storage, settings, log.Named("rhpv3")) go rhpv3.Serve() - rhpv4 := rhp4.NewServer(privKey, cm, s, contracts, wallet, settings, storage, rhp4.WithPriceTableValidity(30*time.Minute)) + rhpv4 := rhp4.NewServer(privKey, cm, s, testutil.NewEphemeralContractor(cm), wallet, settings, storage, rhp4.WithPriceTableValidity(30*time.Minute)) go rhp.ServeRHP4SiaMux(rhp4Listener, rhpv4, log.Named("rhp4")) return &Host{ From d929af8e7ee3c24e7fa1da7c45a27425289e9e78 Mon Sep 17 00:00:00 2001 From: Chris Schinnerl Date: Mon, 16 Dec 2024 15:58:14 +0100 Subject: [PATCH 12/12] fix TestSectorPruning --- internal/test/e2e/cluster.go | 8 +++++++- internal/test/e2e/host.go | 37 +++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/internal/test/e2e/cluster.go b/internal/test/e2e/cluster.go index ff2127910..606177391 100644 --- a/internal/test/e2e/cluster.go +++ b/internal/test/e2e/cluster.go @@ -115,7 +115,13 @@ func (tc *TestCluster) ContractRoots(ctx context.Context, fcid types.FileContrac if h == nil { return nil, fmt.Errorf("no host found for contract %v", c) } - return h.contracts.SectorRoots(fcid), nil + var roots []types.Hash256 + state, unlock, err := h.contractsV2.LockV2Contract(fcid) + if err == nil { + roots = append(roots, state.Roots...) + defer unlock() + } + return append(roots, h.contracts.SectorRoots(fcid)...), nil } func (tc *TestCluster) IsPassedV2AllowHeight() bool { diff --git a/internal/test/e2e/host.go b/internal/test/e2e/host.go index 8248182b7..bc1adb8f1 100644 --- a/internal/test/e2e/host.go +++ b/internal/test/e2e/host.go @@ -112,14 +112,15 @@ type Host struct { s *syncer.Syncer syncerCancel context.CancelFunc - store *sqlite.Store - wallet *wallet.SingleAddressWallet - settings *settings.ConfigManager - storage *storage.VolumeManager - index *index.Manager - registry *registry.Manager - accounts *accounts.AccountManager - contracts *contracts.Manager + store *sqlite.Store + wallet *wallet.SingleAddressWallet + settings *settings.ConfigManager + storage *storage.VolumeManager + index *index.Manager + registry *registry.Manager + accounts *accounts.AccountManager + contracts *contracts.Manager + contractsV2 *testutil.EphemeralContractor rhpv2 *rhpv2.SessionHandler rhpv3 *rhpv3.SessionHandler @@ -308,7 +309,8 @@ func NewHost(privKey types.PrivateKey, cm *chain.Manager, dir string, network *c rhpv3 := rhpv3.NewSessionHandler(rhp3Listener, privKey, cm, s, wallet, accounts, contracts, registry, storage, settings, log.Named("rhpv3")) go rhpv3.Serve() - rhpv4 := rhp4.NewServer(privKey, cm, s, testutil.NewEphemeralContractor(cm), wallet, settings, storage, rhp4.WithPriceTableValidity(30*time.Minute)) + contractsV2 := testutil.NewEphemeralContractor(cm) + rhpv4 := rhp4.NewServer(privKey, cm, s, contractsV2, wallet, settings, storage, rhp4.WithPriceTableValidity(30*time.Minute)) go rhp.ServeRHP4SiaMux(rhp4Listener, rhpv4, log.Named("rhp4")) return &Host{ @@ -318,14 +320,15 @@ func NewHost(privKey types.PrivateKey, cm *chain.Manager, dir string, network *c s: s, syncerCancel: syncerCancel, - store: db, - wallet: wallet, - settings: settings, - index: idx, - storage: storage, - registry: registry, - accounts: accounts, - contracts: contracts, + store: db, + wallet: wallet, + settings: settings, + index: idx, + storage: storage, + registry: registry, + accounts: accounts, + contracts: contracts, + contractsV2: contractsV2, rhpv2: rhpv2, rhpv3: rhpv3,