Content Distribution
Confidence Level:Brainstorm
The Content Distribution component allows retrieval miners and and content providers to negotiate content distribution. Miners offer hosting to providers, and providers send data then pay when its retrieved by clients
# Dependencies
Name | Kind | APIs |
---|---|---|
Data Transfer | required | ManagerAPI |
# Roadmap
V0: Existing or 3 months
The storage API is arguably somewaht similar to this distribution API, except the providers make the offers and money is paid for retrieval, not storage.
V1: 1 Year
It may make sense for hosting and distribution to operate more like an automatic ledger -- content provider asks get automaticallys matched with miner pararms and content providers may not be allowed to reject deals that fall within the parameters of the ask.
V2: Future
Ultimately this is a wide open research problem and hopefully during 2021 ResNetLab can look at potential apporaches.
# Preliminary API
This API is purely speculative
WARNING
This is based of the idea that retrieval miners offer hosting deals to content providers based off of the information in the content bid index. It's not clear if that is the right direction-- content providers may be behind a VPN/NAT, meaning they may be undialable.
package contentdistribution
import (
"time"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/retrieval-market-spec/docs/components/contentrouting"
"github.com/filecoin-project/retrieval-market-spec/docs/components/datatransfer"
"github.com/ipfs/go-cid"
"github.com/ipld/go-ipld-prime"
"github.com/libp2p/go-libp2p-core/peer"
)
// ClientHostingDealState is the state of an in progress hosting deal
// fields TBD
type ClientHostingDealState ipld.Node
// ClientHostingEvent is an event that occurs in a hosting deal lifecycle on the
// client
type ClientHostingEvent uint64
type ClientHostingEventData struct {
Event ClientHostingEvent
State ClientHostingDealState
}
// ClientHostingDealID is a value that uniquely identifies a hosting deal for a
// client
type ClientHostingDealID struct {
Provider peer.ID
HostingDealID HostingDealID
}
type DesiredRequestsServed struct {
Min uint64
Max uint64
}
type HostingAsk struct {
// Root is the root CID of the content the provider would like to make
// available
Root cid.Cid
// Selector indicates the rest of the DAG of the content the provider would
// like to make available
Selector ipld.Node
// PricePerByteServed is amount paid for each retrieval on a per-byte basis
PricePerByteServed abi.TokenAmount
// PricePerRequestServed is amount paid for each retrieval on a per-byte
// basis
PricePerRequestServed abi.TokenAmount
// MinimumBandwidthBytes indicates the expected transfer speed in bytes
DesiredAvgBandwidthBytes uint64
// MaximumTimeToFirstByte specifies the maximum miner latency
MaximumTimeToFirstByte time.Duration
// RequestsServed indicates how many requests you are bidding on by
// Geographic region
RequestsServed map[contentrouting.GeographicRegion]DesiredRequestsServed
// ExpiryTime indicates when this deal will go stale
ExpiryTime time.Time
}
type HostingClientAPI interface {
// SetAsks sets the list of content the provider would like to pay to host
SetAsks(asks []HostingAsk)
// GetAsks returns the content providers content and what they're willing to
// pay for it.
GetAsks() []HostingAsk
// get notified when certain types of events happen
EventsNotify() <-chan ClientHostingEventData
// ListDeals shows the in progress deals for this exchange protocol
ListDeals() map[ClientHostingDealID]ClientHostingDealState
}
type HostingOffer struct {
// Root is the root CID of the content the provider would like to make
// available
Root cid.Cid
// Selector indicates the rest of the DAG of the content the provider would
// like to make available
Selector ipld.Node
// PricePerByteServed is amount paid for each retrieval on a per-byte basis
PricePerByteServed abi.TokenAmount
// PricePerRequestServed is amount paid for each retrieval on a per-byte
// basis
PricePerRequestServed abi.TokenAmount
// MinimumBandwidthBytes indicates the expected transfer speed in bytes
// TODO: is this possible to actually measure?
MinimumAvgBandwidthBytes uint64
// MaximumTimeToFirstByte specifies the maximum miner latency
// TODO: is this possible to actually measure?
MaximumTimeToFirstByte time.Duration
// RequestsServed indicates how many requests will be served by region
RequestsServed map[contentrouting.GeographicRegion]uint64
}
type HostingDealID uint64
// ProviderHostingDealState is the state of an in progress hosting deal
// fields TBD
type ProviderHostingDealState ipld.Node
// ProviderHostingEvent is an event that occurs in a deal lifecycle on the
// provider
type ProviderHostingEvent uint64
type ProviderHostingEventData struct {
Event ProviderHostingEvent
State ProviderHostingDealState
}
type HostingProviderAPI interface {
// OfferHosting initiates a new request to host data based on parameters
// discovered on
// the content bid index. It initiates a new data transfer request to the
// content provider to
// send content to host
// TODO: Is this ok? Is the content provider possibly behind a firewall?
OfferHostingDeal(p peer.ID, offer HostingOffer) (HostingDealID, error)
// GetDeal returns a given deal by deal ID, if it exists
GetHostingDeal(dealID HostingDealID) (ProviderHostingDealState, error)
// ListDeals returns all deals
ListHostingDeals() (map[HostingDealID]ProviderHostingDealState, error)
// get notified when certain types of events happen
EventsNotify() <-chan ProviderHostingEventData
}
// HostingValidatorAPI is an interface provided to data transfer to validate
// incoming offers by the party seeking to provide data
type HostingValidatorAPI interface {
// ValidatePush validates an incoming data transfer push request received
// for
// this exchange protocol
ValidatePush(
sender peer.ID,
voucher datatransfer.Voucher,
baseCid cid.Cid,
selector ipld.Node,
) (datatransfer.VoucherResult, error)
// ValidatePull validates an incoming data transfer pull request received
// for
// this exchange protocol
ValidatePull(
receiver peer.ID,
voucher datatransfer.Voucher,
baseCid cid.Cid,
selector ipld.Node,
) (datatransfer.VoucherResult, error)
}
TIP
You've made it to the end of the Components section. Now maybe you'd like to learn how all these components come together to perform higher level Roles