Skip to content

Move agreement negotiation off-chain, keep only mutual commitment on-chain #97

@mudigal

Description

@mudigal

Summary

The current agreement flow puts negotiation logic on-chain that doesn't need to be there. The chain should only handle the mutual commitment that needs to be provable for disputes/slashing.

Current Flow (3 extrinsics)

  1. create_bucket_with_storage — Auto-discovers a provider on-chain via find_matching_provider (O(n) iteration over all providers), creates bucket + agreement without provider consent
  2. request_primary_agreement — User submits agreement request on-chain, reserves funds, stores temporary AgreementRequest
  3. accept_agreement — Provider accepts on-chain, finalizes the agreement

Problems

  • find_matching_provider is O(n) on-chain work — iterates all registered providers in runtime storage. This is a DoS vector as the provider set grows and wastes blockspace for logic that doesn't need a proof. https://hackmd.io/@C1JDzk4wSpu-_9KIRuGLgg/B1Wc1kNlzg
  • request_primary_agreement is just negotiation — storing a temporary request on-chain burns gas and storage for coordination that can happen off-chain via HTTP.
  • create_bucket_with_storage bypasses provider consent — it auto-selects and binds a provider without their explicit agreement to the specific deal.
  • Temporary storage overheadAgreementRequests storage map exists only to bridge two extrinsics, plus expiry/cleanup logic.

Ideal Flow

Off-chain (client + provider HTTP)

  1. Client discovers providers via runtime API queries (query_find_matching_providers, query_available_providers) — already implemented in DiscoveryClient
  2. Client negotiates terms (price, duration, bytes) with provider via HTTP
  3. Provider signs the agreed terms off-chain

On-chain (single extrinsic)

  1. establish_agreement(bucket_id, provider, terms, provider_signature) — verifies both parties' consent via signature, locks funds, creates the agreement

Benefits

  • One extrinsic instead of two/three for agreement creation
  • No O(n) on-chain iteration — matching stays off-chain where it belongs
  • No temporary AgreementRequest storage — no expiry cleanup needed
  • Provider consent is explicit — provider signs the specific deal terms
  • Chain only does what needs a proof — the binding commitment for disputes/slashing

Scope

  • Remove create_bucket, create_bucket_with_storage extrinsic
  • Update replica storage request flow to use provider-signed agreement term
  • Remove on-chain find_matching_provider
  • Replace request_primary_agreement + accept_agreement with a single establish_agreement extrinsic that takes a provider signature
  • Remove AgreementRequests storage map and related cleanup logic (reject_agreement, withdraw_agreement_request, request expiry)
  • Add provider-side HTTP endpoint for agreement negotiation/signing
  • Update DiscoveryClient / client SDK to use the new flow
  • Update file system client (storage-interfaces/file-system/client) accordingly
  • Update tests and benchmarks

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions