diff --git a/pages/developers/blueprints/_meta.ts b/pages/developers/blueprints/_meta.ts index 4b0aeba..8017362 100644 --- a/pages/developers/blueprints/_meta.ts +++ b/pages/developers/blueprints/_meta.ts @@ -3,6 +3,7 @@ import { Meta } from "nextra"; const meta: Meta = { introduction: "Introduction", "use-cases": "Use Cases", + "pricing-engine": "Pricing", manager: "Blueprint Manager", }; diff --git a/pages/developers/blueprints/pricing-engine.mdx b/pages/developers/blueprints/pricing-engine.mdx new file mode 100644 index 0000000..9819899 --- /dev/null +++ b/pages/developers/blueprints/pricing-engine.mdx @@ -0,0 +1,208 @@ +--- +title: Blueprint Pricing +--- + +# Blueprint Pricing + +This guide explains how pricing works for blueprint execution and how to integrate pricing functionality into your applications that use Tangle Network blueprints. + +## Prerequisites + +- Understanding of Blueprint concepts and execution model +- Familiarity with Tangle Network architecture +- Basic knowledge of cryptographic signatures and verification + +## Pricing Workflow + +The complete workflow for getting quotes and executing blueprints consists of: + +1. **Finding Operators**: Retrieve all operators registered for the blueprint to be executed. + +2. **Requesting Quotes**: Request price quotes from operators: + + - Generate a proof-of-work for the request + - Create a properly formatted price request + - Submit the request via gRPC (at the address specified by each operator on-chain) + +3. **Processing Quotes**: When you receive quotes from operators: + + - Verify their signatures + - Validate the proof-of-work + - Compare prices + +4. **Selecting Operators**: Choose which operators to use based on their pricing quotes, typically selecting the most cost-effective options. + +5. **Submitting Request**: Submit an on-chain request that includes your selected quotes via the `request_with_signed_price_quotes` services extrinsic. + +6. **Blueprint Execution**: The selected operators will execute the blueprint according to the agreed terms. + +## Pricing API + +To request price quotes, your application will use the gRPC API provided by operators. You just need to send a `GetPrice` gRPC request to the operator's gRPC endpoint. Here's the service definition in protobuf: + +```protobuf +// The pricing service definition +service Pricing { + // Retrieves a signed price quote for a given blueprint + rpc GetPrice (GetPriceRequest) returns (GetPriceResponse); +} +``` + +### Message Types + +Here are the key message types you'll work with: + +```protobuf +// The pricing service definition +service PricingEngine { + // Retrieves a signed price quote for a given blueprint + rpc GetPrice (GetPriceRequest) returns (GetPriceResponse); +} + +// Asset type enumeration +enum AssetType { + CUSTOM = 0; + ERC20 = 1; +} + +// Asset type definition +message Asset { + oneof asset_type { + // Custom asset with a numeric identifier + uint64 custom = 1; + // ERC20 token with an H160 address + bytes erc20 = 2; + } +} + +// Security requirements for an asset +message AssetSecurityRequirements { + // The asset type + Asset asset = 1; + // Minimum exposure percentage (0-100) + uint32 minimum_exposure_percent = 2; + // Maximum exposure percentage (0-100) + uint32 maximum_exposure_percent = 3; +} + +// Security commitment for an asset +message AssetSecurityCommitment { + // The asset type + Asset asset = 1; + // Committed exposure percentage (0-100) + uint32 exposure_percent = 2; +} + +// Resource requirement for a specific resource type +message ResourceRequirement { + // Resource kind (CPU, Memory, GPU, etc.) + string kind = 1; + // Quantity required + uint64 count = 2; +} + +// Pricing for a specific resource type +message ResourcePricing { + // Resource kind (CPU, Memory, GPU, etc.) + string kind = 1; + // Quantity of the resource + uint64 count = 2; + // Price per unit in USD with decimal precision + double price_per_unit_rate = 3; +} + +// Request message for GetPrice RPC +message GetPriceRequest { + // The blueprint ID + uint64 blueprint_id = 1; + // Time-to-live for service in blocks + uint64 ttl_blocks = 2; + // Proof of work to prevent DDOS + bytes proof_of_work = 3; + // Optional resource recommendations + repeated ResourceRequirement resource_requirements = 4; + // Security requirements for assets + AssetSecurityRequirements security_requirements = 5; +} + +// Response message for GetPrice RPC +message GetPriceResponse { + // The quote details + QuoteDetails quote_details = 1; + // Signature of the hash of the body + bytes signature = 2; + // Operator ID + bytes operator_id = 3; + // Proof of work response + bytes proof_of_work = 4; +} + +// The detailed quote information +message QuoteDetails { + // The blueprint ID + uint64 blueprint_id = 1; + // Time-to-live for service in blocks + uint64 ttl_blocks = 2; + // Total cost in USD with decimal precision + double total_cost_rate = 3; + // Timestamp when quote was generated + uint64 timestamp = 4; + // Expiry timestamp + uint64 expiry = 5; + // Resource pricing details + repeated ResourcePricing resources = 6; + // Security commitments for assets + AssetSecurityCommitment security_commitments = 7; +} +``` + +## Implementation Steps + +### 1. Generating Proof-of-Work + +Before requesting a quote, you need to generate a valid proof-of-work for the request. The Operator pricing server uses the Equix Equihash Rust implementation for proof-of-work generation. + +### 2. Creating and sending a Price Request + +Next, create a price request with your requirements using the types defined in [Message Types](#message-types) and send it to each operator registered to the blueprint you want to run. Both the registered operators and their gRPC endpoints are available on-chain. + +### 3. Verifying Quote Signatures + +When you receive quotes, verify their authenticity by using the hash of the quote details and the operator's signature of the quote's hash that was included in the response. + +### 4. Selecting Operators + +After verifying the quotes, select the operators you want to use based on their pricing and security commitments. It is recommended to automatically select the lowest-priced operators. + +### 5. Requesting service with quotes + +After selecting the operators, submit your request to the blockchain using the `request_with_signed_price_quotes` services extrinsic with the selected operators and their quotes. + +## Understanding Pricing Calculations + +Operators calculate prices using this formula: + +``` +Price = Resource Cost × Duration Factor × Security Factor +``` + +This means that the total cost of a blueprint execution is the sum of the prices from all selected operators. + +Where: + +- **Resource Cost** = resource_count × price_per_unit_rate +- **Duration Factor** = time_blocks × BLOCK_TIME +- **Security Factor** = Factor based on security requirements + +Understanding this helps you estimate costs and evaluate quotes effectively. + +## Best Practices + +1. **Get Multiple Quotes**: Always request quotes from all registered operators to compare prices +2. **Verify All Signatures**: Always verify the signature of each quote before using it +3. **Check Expiry Times**: Ensure quotes haven't expired before submitting them to the blockchain +4. **Include Complete Security Requirements**: Specify all necessary security parameters in your requests +5. **Handle Errors Gracefully**: Implement proper error handling for failed quote requests +6. **Keep Quotes Intact**: Never modify quote details after receiving them +7. **Use Fresh Proof-of-Work**: Generate a new proof-of-work for each request +8. **Expect Price Variation**: Don't assume all operators will provide the same price diff --git a/pages/developers/troubleshooting.mdx b/pages/developers/troubleshooting.mdx index c02deb1..059edf8 100644 --- a/pages/developers/troubleshooting.mdx +++ b/pages/developers/troubleshooting.mdx @@ -27,16 +27,7 @@ Caused by: note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ``` -1. Verify your `gadget` version and compare your `rust_toolchain.toml` against the [Blueprint Template](https://github.com/tangle-network/blueprint-template) repository. - - - -2. Verify that your blueprint's jobs and reports are implemented correctly. Occasionally, our SDK may have breaking changes to the error reporting. You will want to consider commenting out metadata generation and then rebuilding to check for errors in the blueprint. +Verify that your blueprint's jobs and reports are implemented correctly. Occasionally, our SDK may have breaking changes to the error reporting. You will want to consider commenting out metadata generation and then rebuilding to check for errors in the blueprint. {/* TODO: Add URL */} diff --git a/pages/operators/_meta.ts b/pages/operators/_meta.ts index 9d3820a..4ed33d6 100644 --- a/pages/operators/_meta.ts +++ b/pages/operators/_meta.ts @@ -14,6 +14,7 @@ const meta: Meta = { title: "Blueprint Operators", }, operator: "Running an operator", + pricing: "Pricing", "-- Eigenlayer AVS Operators": { type: "separator", title: "Eigenlayer AVS Operators", diff --git a/pages/operators/pricing/_meta.ts b/pages/operators/pricing/_meta.ts new file mode 100644 index 0000000..fb3da9c --- /dev/null +++ b/pages/operators/pricing/_meta.ts @@ -0,0 +1,7 @@ +import { Meta } from "nextra"; + +const meta: Meta = { + overview: "Overview", +}; + +export default meta; diff --git a/pages/operators/pricing/overview.mdx b/pages/operators/pricing/overview.mdx new file mode 100644 index 0000000..1cf4167 --- /dev/null +++ b/pages/operators/pricing/overview.mdx @@ -0,0 +1,96 @@ +--- +title: Blueprint Pricing Overview +--- + +# Blueprint Pricing + +As a blueprint operator, you'll need to set up pricing for your services to receive fair compensation for the resources you provide. This guide explains how pricing works in the Tangle Network and how to configure it properly. + +## Prerequisites + +- Basic understanding of Tangle Network operations +- Familiarity with running and maintaining a Tangle node +- Knowledge of basic blueprint concepts + +## How Blueprint Pricing Works + +The pricing process follows these steps: + +1. **Registration**: When you register as an operator for a blueprint, you provide your pricing service address in your preferences + - **Note**: If your RPC server address changes, you can update it on-chain for any registered blueprint through the `updateRpcAddress` services extrinsic call +2. **Quote Requests**: Users request price quotes from registered operators like you +3. **Quote Generation**: Your service calculates prices based on resource requirements, creates security commitments, and signs quotes +4. **Operator Selection**: Users select operators based on price and other factors +5. **Service Execution**: Once selected, you'll begin execution of the blueprint and receive payment + +## Setting Up Your Pricing Service + +Your pricing service needs to be available via gRPC for users to request quotes. Here's how to configure it: + +### Pricing Configuration + +Create a TOML configuration file with your pricing structure. The file should include both default pricing for all blueprints and specific pricing for particular blueprints: + +```toml +# Default pricing for all blueprints +[default] +resources = [ + { kind = "CPU", count = 1, price_per_unit_rate = 0.001 }, + { kind = "MemoryMB", count = 1024, price_per_unit_rate = 0.00005 }, + { kind = "StorageMB", count = 1024, price_per_unit_rate = 0.00002 }, + { kind = "NetworkEgressMB", count = 1024, price_per_unit_rate = 0.00003 }, + { kind = "NetworkIngressMB", count = 1024, price_per_unit_rate = 0.00001 }, + { kind = "GPU", count = 1, price_per_unit_rate = 0.005 } +] + +# Blueprint-specific pricing (overrides default) +[123] # Blueprint ID +resources = [ + { kind = "CPU", count = 1, price_per_unit_rate = 0.0012 }, + { kind = "MemoryMB", count = 2048, price_per_unit_rate = 0.00006 }, + { kind = "StorageMB", count = 1024, price_per_unit_rate = 0.00002 }, + { kind = "NetworkEgressMB", count = 1024, price_per_unit_rate = 0.00003 }, + { kind = "NetworkIngressMB", count = 1024, price_per_unit_rate = 0.00001 }, + { kind = "GPU", count = 1, price_per_unit_rate = 0.005 } +] +``` + +Each resource type defines: + +- `kind`: The resource type (CPU, MemoryMB, StorageMB, etc.) +- `count`: The baseline quantity for the resource +- `price_per_unit_rate`: The price per unit in USD with decimal precision, where it is generally the price per block for the resource + +### How Prices Are Calculated + +The formula used to calculate blueprint execution pricing is: + +``` +Price = Resource Cost × Duration Factor × Security Factor +``` + +Where: + +- **Resource Cost** = resource_count × price_per_unit_rate +- **Duration Factor** = time_blocks × BLOCK_TIME +- **Security Factor** = Factor based on security commitment parameters + +## Security Commitments + +When users request your services, they include security requirements that specify what percentage of assets you need to secure. Your pricing service needs to respond with your commitment: + +- **Exposure Percentage**: The percentage of assets you guarantee to secure (between the user's minimum and maximum requirements) +- **Asset Types**: Can be Custom (u64) or ERC20 (H160 address) + +This commitment will be included with your signed quote. The commitment used for the quote is automatically the minimum exposure percentage specified in the user's security requirements. + +## Quote Security Considerations + +### Quote Signature + +- To ensure the validity of your quotes, your quotes are automatically signed. Users then verify the signature included in an Operator's quote when they receive it. This ensures a user is getting genuine quotes from you and other operators. + +### Protection Against Abuse + +- **Proof-of-Work Verification**: Users provide proof-of-work with their requests, defending against Denial-of-Service (DoS) attacks +- **Quote Expiry**: Quotes include an expiry time (typically 10-15 minutes) to prevent stale quotes