From f0c90b5da7fce4e5883ce7b63ed4d9ce87a4f597 Mon Sep 17 00:00:00 2001 From: Travis Vachon Date: Tue, 28 May 2024 16:58:53 -0700 Subject: [PATCH 01/11] feat: egress billing RFC First writeup of the proposal for egress billing. Looking for feedback on the ideas and on the coherence of the writeup. --- rfc/egress-billing.md | 251 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 rfc/egress-billing.md diff --git a/rfc/egress-billing.md b/rfc/egress-billing.md new file mode 100644 index 0000000..aecee35 --- /dev/null +++ b/rfc/egress-billing.md @@ -0,0 +1,251 @@ +# w3s.link gateway egress billing + +## Authors + +- [Travis Vachon](https://github.com/travis) +- [Irakli Gozalishvili](https://github.com/gozala) + +## Goals + +We need to start charging for data served by our gateway ("gateway egress"). Users who upload data using `w3up` should +be charged when we serve that data through the gateway that is currently hosted at https://w3s.link. Importantly, if +two users upload the same data, we need to ensure the correct party is billed when we serve that data through +the gateway - for instance, if I upload a file that a massive NFT platform also uploaded, I should not be charged +when that platform serves that data to millions of their customers through their website. + +Charging for *all* reads is a non-goal - we believe there is a tradeoff between strict accounting and read performance +and we generally want to err on the side of performant reads. + +## Abstract + +The business has the capacity to pay for some number of reads - we'll call this R. We will +first implement a global per-CID rate-limit that is expected to account for roughly 75-90% +of R. This rate limit will be used for all content that has not been configured with another +rate limit, and for content that has been configured with other rate limits that have already +been reached. If a request is made for content that has "used up" all available rate limits, including +its public rate limit, the response MAY be an HTTP 429 (`Too Many Requests`), but MAY be an HTTP 200 (`OK`) with the content +if doing so allows us to optimize read performance. Requests served despite being over all rate +limits will account for the remaining 10-25% of R. [note: I'm not sure if these percentage ranges for R are right] + +In order to allow our users to guarantee consistent read performance in their applications, we +will allow them to configure rate limits using the “content commitments“ returned from blob uploads. +These content commitments can be delegated to the gateway and parameterized to set rate limits +in a flexible and extensible way - essentially, a user will authorize the gateway to serve their content +with some restrictions. At read time, if the gateway can find a valid content commitment it will serve the content, +and if not it will fall back to the behavior described above. + +Finally, in order to give ourselves maximum flexibility to optimize read performance, we propose +a high performance rate-limit tracking system based on a mature caching service - we will +use [Redis] in this document as an example, but other services like memcached or Caddy should be considered. +When read requests come in to the gateway, this system will be used to determine whether the request should +be served. After the request is served it will be passed to a backend job processing system which +will both record the system for administrative purposes (eg, billing) AND update the rate limit caching +system. We expect this to result in some amount of "unauthorized" read request service, for example if two requests for +the same content arrive at nearly the same time they will both be served 200s, since the rate limits will only be +updated some time after a request is served. This pattern is similar in some ways to the "stale while revalidate" +pattern that is popular on the web today - stale rate limits will be used while they are revalidated in the background. + +Taken together, this should allow us to keep reads extremely performant - ideally we will need only a single Redis +request and a small amount of computation to decide whether to serve content. It will also give users an +extremely flexible and extensible mechanism to control how and when their content is served, including support for +`Origin`-gating and other CDN-esque tools to control their egress costs. + +## Introduction + +We currently operate the IPFS gateway at https://w3s.link as a free service. As a result, it is an unbound source of "cost" +for our business. Covering some amount of the costs associated with this service make sense as a marketing and community +building expense, but operating it for free makes it prohibitively expensive to give our customers acceptable read performance +for their applications through our gateway. + +In order to fix this, we propose a design for billing our customers for data egress related to their applications. The suggested +design allows us to maintain extremely fast read performance by allowing us to configure the "acceptable level" of "unpaid" +data egress and giving our customers a way to authorize paid data egress using the "content claims" returned by the +[blob upload service]. + +## Rate Limits + +Business realities (runway, need for marketing and community growth, etc) will determine an acceptable level of data egress +through our gateway that can be paid for by the business. We will call this _R_, the "number of requests we're willing to pay for." + +We will use a tool like Redis to implement this rate limit, because it has a long history of being used for this and +the right set of primitives to support it well: https://redis.io/glossary/rate-limiting/ - we will use Redis as an example +in this document but recommend researching other tools like memcached and Caddy before making a final implementation decision. + +When the gateway receives a request for some content, it will make a request to Redis for the relevant rate limit data and decide to +serve the request based on the response. In order to maintain acceptable read performance, we recommend avoiding any other network +IO in making the decision to serve a piece of content. In the event that content is served as a result of the rate limit caching service +being out of date, we count that request against _R_. + +The following TypeScript pseudocode illustrates the rate limiting algorithm: + +ts +``` +enum RateLimited { + Yes, + No, + Maybe, +} + +async function handle(request){ + const rateLimited = checkRedisToDetermineIfRateLimited(request) + const cid = getCidFromRequest(request) + switch (rateLimited) { + case Yes: + return { status: 429, message: `${cid} is currently rate limited, please try again later` } + case No: + return { status: 200, body: readContentFromW3up(cid) } + case Maybe: + return { status: 200, body: readContentFromW3up(cid) } + } +} +``` + +### User Configuration + +In order to allow our users to use uploaded content in their applications and guarantee acceptable read performance, +we propose use the "[content commitments]" generated by the w3up [blob upload service]. + +```js +{ // Content commitment with CID bafy..site + // Storage node authorizes access to the stored resource + "iss": "did:web:asia.web3.storage", + // To Alice + "aud": "did:key:zAlice", + // Indefinitely + "exp": null, + "cmd": "/assert/location", + // Subject is storage node because they own that resource + "sub": "did:web:asia.web3.storage", + "pol": [ + // multihash must match an uploaded blob + ["==", ".content", { "/": { "bytes": "mEi...sfKg" } }], + // must be available from this url + ["==", ".url", "https://asia.w3s.link/ipfs/bafk...7fi"], + ] +} +``` + +[TODO: should I translate this into UCAN.current too?] + +The "content commitment" above, with CID `bafy...site`, represents a claim that content will be available from +the URL `https://asia.w3s.link/ipfs/bafk...7fi` indefinitely. Alice can use it to create and sign the following +delegation to the w3s.link gateway: + +```js +{ // bafy..auth + "iss": "did:key:zAlice", + "aud": "did:web:w3s.link", + "exp": 1716235987 // restrict to a month + "cmd": "/assert/location", + // Subject is storage node because they own that resource + "sub": "did:web:asia.web3.storage", + "pol": [ + // Request origin header must be example.com + ["==", ".headers['origin']", "example.com"], + // Request URL must have a query string that includes "token=zrptvx" + ["==", ".query.token", "zrptvx"] + ], + "meta": { "proof": { "/": "bafy..site" } } +} +``` + +This delegation authorizes the gateway to serve this content when the HTTP request's `Origin` header has a +value of `example.com` and the request URL has a query string that includes `token=zrptvx`. This functions +as an "unlimited" rate limit and can be used to authorize, for example, unlimited egress billing for requests. + +#### Rate Limit Accounting + +When the gateway receives a request, it will query the [content claims service] for claims about the requested +CID [TODO: and also other information like origin and token?]. If multiple claims establishing different rate limits +are found, one is chosen randomly and its request count is incremented, resulting in billing to the +party that authorized the rate limit. If no claims are found, the public rate limit request count is incremented. + +These queries and the updates to rate limits they are used to create should not be done in the hot-path of reads - instead +this should be done in background jobs and the read logic should read from whatever data store these tasks are using to manage +rate limits. + +#### Bulk Configuration + +NOTE: The following this requires support for "delegations without inline proofs" as specified in UCAN 1.0 + +If users would like to set rate limits on a set of CIDs in a single operation, they can create an intermediary "principle" +to which they can address delegations - in this example we will call this principle `did:key:zGroup`. + +We first create a content commitment addressed to the group: + +```js +{ // bafy..group + "iss": "did:key:zAlice", + "aud": "did:key:zGroup", + "exp": 1716235987 // restrict to a month + "cmd": "/assert/location", + // Subject is storage node because they own that resource + "sub": "did:web:asia.web3.storage", + "pol": [ + // Request origin header must be example.com + ["==", ".headers['origin']", "example.com"], + ["==", ".query.token", "zrptvx"] + ], + "meta": { "proof": { "/": "bafy..site" } } +} +``` + +and then create an open-ended delegation from the group to the gateway, with the same `pol` (TODO: or more restrictive?) fields: + +```js +{ // bafy..access + "iss": "did:key:zGroup", + "aud": "did:web:w3s.link", + "exp": 1716235987 // restrict to a month + "cmd": "/assert/location", + // Subject is storage node because they own that resource + "sub": "did:web:asia.web3.storage", + "pol": [ + // Request origin header must be example.com + ["==", ".headers['origin']", "example.com"], + ["==", ".query.token", "zrptvx"] + ] +} +``` + +For any given CID, the gateway will be able to look up the CID-specific content commitment as well as the +group-to-gateway content commitment and combine them to create a chain rooted in the original content commitment +provided by the w3up service on content upload. The gateway should take care to check that each link in the +chain is valid (though this will hopefully be handled by the UCAN tooling). + +## Implementation Considerations + +As stated above, a core design goal is to keep reads extremely performant. This generally implies +that we should try to make a decision about whether or not to serve a request with as little IO (and to +a lesser extent compute) as possible. As we suggest above, a service like Redis is designed to serve +this use-case (https://redis.io/glossary/rate-limiting/) well, and ideally will be the only service +consulted when making a decision about whether or not to serve content. + +This implies that the first time we are asked to serve a piece of content, we will serve it. This is +totally acceptable because we propose a global rate limit greater than 0. After serving the content, we will +further process the request using a background job-execution framework. This background job will determine +whether a particular CID should be rate limited. In some cases, especially cases where the same CID is being +requested many times, this may result in content being served despite being over all applicable rate limits - this +is acceptable since Redis will eventually be updated and the amount of reads that fall into this category are +expected to be within the bounds of the read capacity the business is willing to serve. + +On the topic of Redis, it's worth noting that it is no longer open source: + +https://redis.io/blog/redis-adopts-dual-source-available-licensing/ + +We may want to consider using an open source alternative like https://github.com/nalgeon/redka if we +are concerned about using "source available" products - my inclination is to use Redis but consider products like +Redka as a fallback in case Redis no longer meets our needs. + +## TODO + +- [ ] research Redis and alternatives +- [ ] design the caching system + +## Resources + +[capability design sketch](https://hackmd.io/trUTYf90TjaCyzft2aIFdg) +[content commitments](https://hackmd.io/@gozala/content-claims) +[content claims service](https://github.com/web3-storage/content-claims) +[blob upload service](https://github.com/w3s-project/specs/blob/main/w3-blob.md) +[Redis](https://redis.io/) \ No newline at end of file From 09924d4cbcd8dd515545e98a5750b907afd62f9c Mon Sep 17 00:00:00 2001 From: Travis Vachon Date: Tue, 28 May 2024 17:01:12 -0700 Subject: [PATCH 02/11] fix: typo --- rfc/egress-billing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rfc/egress-billing.md b/rfc/egress-billing.md index aecee35..d8e9a33 100644 --- a/rfc/egress-billing.md +++ b/rfc/egress-billing.md @@ -78,8 +78,8 @@ being out of date, we count that request against _R_. The following TypeScript pseudocode illustrates the rate limiting algorithm: -ts -``` + +```ts enum RateLimited { Yes, No, From c9c7763082050e28bb3f4558a951e3fed9237b80 Mon Sep 17 00:00:00 2001 From: Travis Vachon Date: Wed, 29 May 2024 11:56:36 -0700 Subject: [PATCH 03/11] feat: trim down and clarify abstract --- rfc/egress-billing.md | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/rfc/egress-billing.md b/rfc/egress-billing.md index d8e9a33..7edfbd9 100644 --- a/rfc/egress-billing.md +++ b/rfc/egress-billing.md @@ -22,10 +22,8 @@ The business has the capacity to pay for some number of reads - we'll call this first implement a global per-CID rate-limit that is expected to account for roughly 75-90% of R. This rate limit will be used for all content that has not been configured with another rate limit, and for content that has been configured with other rate limits that have already -been reached. If a request is made for content that has "used up" all available rate limits, including -its public rate limit, the response MAY be an HTTP 429 (`Too Many Requests`), but MAY be an HTTP 200 (`OK`) with the content -if doing so allows us to optimize read performance. Requests served despite being over all rate -limits will account for the remaining 10-25% of R. [note: I'm not sure if these percentage ranges for R are right] +been reached. Requests served despite being over all other available rate limits will account +for the remaining 10-25% of R. [note: I'm not sure if these percentage ranges for R are right] In order to allow our users to guarantee consistent read performance in their applications, we will allow them to configure rate limits using the “content commitments“ returned from blob uploads. @@ -35,15 +33,13 @@ with some restrictions. At read time, if the gateway can find a valid content co and if not it will fall back to the behavior described above. Finally, in order to give ourselves maximum flexibility to optimize read performance, we propose -a high performance rate-limit tracking system based on a mature caching service - we will -use [Redis] in this document as an example, but other services like memcached or Caddy should be considered. -When read requests come in to the gateway, this system will be used to determine whether the request should -be served. After the request is served it will be passed to a backend job processing system which -will both record the system for administrative purposes (eg, billing) AND update the rate limit caching -system. We expect this to result in some amount of "unauthorized" read request service, for example if two requests for -the same content arrive at nearly the same time they will both be served 200s, since the rate limits will only be -updated some time after a request is served. This pattern is similar in some ways to the "stale while revalidate" -pattern that is popular on the web today - stale rate limits will be used while they are revalidated in the background. +a high performance rate-limit tracking system based on industry-standard tools for this purpose. After +the request is served it will be passed to a backend job processing system which will update the rate limit caching +system. We expect this to result in some amount of "unauthorized" read request service - for example, if two requests for +the same content arrive at nearly the same time they will always both be served even if the second request +goes over all established rate limits, since the rate limits will only be updated some time after a request is served. +This pattern is similar in some ways to the "stale while revalidate" pattern that is popular on the web today - stale +rate limits will be used while they are revalidated in the background. Taken together, this should allow us to keep reads extremely performant - ideally we will need only a single Redis request and a small amount of computation to decide whether to serve content. It will also give users an From 6ff056f221e4f90398d7d516b6aaaedc5bb98ff1 Mon Sep 17 00:00:00 2001 From: Travis Vachon Date: Wed, 29 May 2024 12:01:07 -0700 Subject: [PATCH 04/11] fix: more clarification and editing --- rfc/egress-billing.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rfc/egress-billing.md b/rfc/egress-billing.md index 7edfbd9..3bf09eb 100644 --- a/rfc/egress-billing.md +++ b/rfc/egress-billing.md @@ -18,12 +18,11 @@ and we generally want to err on the side of performant reads. ## Abstract -The business has the capacity to pay for some number of reads - we'll call this R. We will -first implement a global per-CID rate-limit that is expected to account for roughly 75-90% -of R. This rate limit will be used for all content that has not been configured with another +The business has the capacity to pay for some number of reads - we'll call this _R_. We will +first implement a global per-CID rate-limit that is expected to account for N% +of _R_. This rate limit will be used for all content that has not been configured with another rate limit, and for content that has been configured with other rate limits that have already -been reached. Requests served despite being over all other available rate limits will account -for the remaining 10-25% of R. [note: I'm not sure if these percentage ranges for R are right] +been reached. In order to allow our users to guarantee consistent read performance in their applications, we will allow them to configure rate limits using the “content commitments“ returned from blob uploads. @@ -39,10 +38,11 @@ system. We expect this to result in some amount of "unauthorized" read request s the same content arrive at nearly the same time they will always both be served even if the second request goes over all established rate limits, since the rate limits will only be updated some time after a request is served. This pattern is similar in some ways to the "stale while revalidate" pattern that is popular on the web today - stale -rate limits will be used while they are revalidated in the background. +rate limits will be used while they are revalidated in the background. Requests served this way despite being over all +available rate limits will account for the remaining (100 - N)% of _R_. -Taken together, this should allow us to keep reads extremely performant - ideally we will need only a single Redis -request and a small amount of computation to decide whether to serve content. It will also give users an +Taken together, this should allow us to keep reads extremely performant - ideally we will need only a single network +request to the rate limits service and a small amount of computation to decide whether to serve content. It will also give users an extremely flexible and extensible mechanism to control how and when their content is served, including support for `Origin`-gating and other CDN-esque tools to control their egress costs. From 84dc4f3139e5c9bae741309be253c1d03fd315cb Mon Sep 17 00:00:00 2001 From: Travis Vachon Date: Wed, 29 May 2024 12:36:41 -0700 Subject: [PATCH 05/11] feat: add sequence diagram --- rfc/egress-billing.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rfc/egress-billing.md b/rfc/egress-billing.md index 3bf09eb..ac5bba0 100644 --- a/rfc/egress-billing.md +++ b/rfc/egress-billing.md @@ -46,6 +46,16 @@ request to the rate limits service and a small amount of computation to decide w extremely flexible and extensible mechanism to control how and when their content is served, including support for `Origin`-gating and other CDN-esque tools to control their egress costs. +```mermaid +sequenceDiagram + Alice->>Gateway: Do you have bafk...7fi? + Gateway->>Rate Limit Service: Has bafk...7fi exceeded rate limits? + Rate Limit Service-->>Gateway: YES or NO or UNKNOWN + Gateway-)Accounting Service: Serving/not serving bafk...7fi + Gateway-->>Alice: 200 if YES or UNKNOWN, 429 if NO + Accounting Service->>Rate Limit Service: Update rate limits +``` + ## Introduction We currently operate the IPFS gateway at https://w3s.link as a free service. As a result, it is an unbound source of "cost" From 74c44eb90e8e39e09f695b0179393934736cd340 Mon Sep 17 00:00:00 2001 From: Travis Vachon Date: Wed, 29 May 2024 12:57:42 -0700 Subject: [PATCH 06/11] feat: another diagram and some clarity about how to set rate limits --- rfc/egress-billing.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rfc/egress-billing.md b/rfc/egress-billing.md index ac5bba0..fb0bc7c 100644 --- a/rfc/egress-billing.md +++ b/rfc/egress-billing.md @@ -159,6 +159,18 @@ This delegation authorizes the gateway to serve this content when the HTTP reque value of `example.com` and the request URL has a query string that includes `token=zrptvx`. This functions as an "unlimited" rate limit and can be used to authorize, for example, unlimited egress billing for requests. +Additional `pol` entries can be added to set more stringent rate limits, +for example specifying that a particular content commitment may +only be used 100 times per minute or 1000 total. The syntax and +specifics of these rate limits will be defined in a formal specification. + +```mermaid +sequenceDiagram + Alice->>Blob Service: Please store bafk...7fi + Blob Service-->>Alice: Stored - you can present bafy..site to fetch bafk...7fi + Alice-)Gateway: You can present bafy..site to fetch bafk...7fi +``` + #### Rate Limit Accounting When the gateway receives a request, it will query the [content claims service] for claims about the requested From 2da9e12a39a9490e7fc76040dd583b9a893d2b73 Mon Sep 17 00:00:00 2001 From: Travis Vachon Date: Wed, 29 May 2024 14:52:27 -0700 Subject: [PATCH 07/11] feat: even more diagrams! --- rfc/egress-billing.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/rfc/egress-billing.md b/rfc/egress-billing.md index fb0bc7c..ee79a2c 100644 --- a/rfc/egress-billing.md +++ b/rfc/egress-billing.md @@ -182,6 +182,15 @@ These queries and the updates to rate limits they are used to create should not this should be done in background jobs and the read logic should read from whatever data store these tasks are using to manage rate limits. +```mermaid +sequenceDiagram + Gateway-)Accounting Service: I received a request for bafk...7fi + Accounting Service->>Content Claims Service: Give me claims relevant to this request + Content Claims Service-->>Accounting Service: Here are the claims I can find + Accounting Service->>Rate Limiting Service: Increment rate limit usage for this claim + Rate Limiting Service-->>Accounting Service: OK, done +``` + #### Bulk Configuration NOTE: The following this requires support for "delegations without inline proofs" as specified in UCAN 1.0 From 2d186550adf24e2c1daf062dcce5a491f5213510 Mon Sep 17 00:00:00 2001 From: Travis Vachon Date: Wed, 29 May 2024 15:07:36 -0700 Subject: [PATCH 08/11] feat: MORE DIAGRAMS and more cleanup --- rfc/egress-billing.md | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/rfc/egress-billing.md b/rfc/egress-billing.md index ee79a2c..24c9738 100644 --- a/rfc/egress-billing.md +++ b/rfc/egress-billing.md @@ -112,7 +112,7 @@ In order to allow our users to use uploaded content in their applications and gu we propose use the "[content commitments]" generated by the w3up [blob upload service]. ```js -{ // Content commitment with CID bafy..site +{ // Content commitment with CID bafy...site // Storage node authorizes access to the stored resource "iss": "did:web:asia.web3.storage", // To Alice @@ -151,7 +151,7 @@ delegation to the w3s.link gateway: // Request URL must have a query string that includes "token=zrptvx" ["==", ".query.token", "zrptvx"] ], - "meta": { "proof": { "/": "bafy..site" } } + "meta": { "proof": { "/": "bafy...site" } } } ``` @@ -167,8 +167,8 @@ specifics of these rate limits will be defined in a formal specification. ```mermaid sequenceDiagram Alice->>Blob Service: Please store bafk...7fi - Blob Service-->>Alice: Stored - you can present bafy..site to fetch bafk...7fi - Alice-)Gateway: You can present bafy..site to fetch bafk...7fi + Blob Service-->>Alice: Stored - you can present bafy...site to fetch bafk...7fi + Alice-)Gateway: You can present bafy...auth to fetch bafk...7fi ``` #### Rate Limit Accounting @@ -213,7 +213,7 @@ We first create a content commitment addressed to the group: ["==", ".headers['origin']", "example.com"], ["==", ".query.token", "zrptvx"] ], - "meta": { "proof": { "/": "bafy..site" } } + "meta": { "proof": { "/": "bafy...site" } } } ``` @@ -240,6 +240,18 @@ group-to-gateway content commitment and combine them to create a chain rooted in provided by the w3up service on content upload. The gateway should take care to check that each link in the chain is valid (though this will hopefully be handled by the UCAN tooling). +```mermaid +sequenceDiagram + Alice->>Blob Service: Please store bafk...7fi + Blob Service-->>Alice: Stored - you can present bafy...site to fetch bafk...7fi + Alice-)Group: You can present bafy...group to fetch bafk...7fi + Group-)Gateway: You can present bafy..access to fetch bafk...7fi +``` + +Note that `bafy..access` alone will not be enough to authorize retrieval +of the content - the accounting system will need to combine it with +a CID-specific content commitment that has been delegated to `Group`. + ## Implementation Considerations As stated above, a core design goal is to keep reads extremely performant. This generally implies @@ -268,6 +280,7 @@ Redka as a fallback in case Redis no longer meets our needs. - [ ] research Redis and alternatives - [ ] design the caching system +- [ ] work plan ## Resources From 90c602495113a838161543b6b0284684dbc84a50 Mon Sep 17 00:00:00 2001 From: Travis Vachon Date: Wed, 29 May 2024 15:26:25 -0700 Subject: [PATCH 09/11] feat: work planning --- rfc/egress-billing.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/rfc/egress-billing.md b/rfc/egress-billing.md index 24c9738..5b4037e 100644 --- a/rfc/egress-billing.md +++ b/rfc/egress-billing.md @@ -193,7 +193,7 @@ sequenceDiagram #### Bulk Configuration -NOTE: The following this requires support for "delegations without inline proofs" as specified in UCAN 1.0 +NOTE: The following requires support for "delegations without inline proofs" as specified in UCAN 1.0 If users would like to set rate limits on a set of CIDs in a single operation, they can create an intermediary "principle" to which they can address delegations - in this example we will call this principle `did:key:zGroup`. @@ -278,9 +278,21 @@ Redka as a fallback in case Redis no longer meets our needs. ## TODO +- [ ] quick prototype spike - (in hoverboard?) + - just the single-CID flow for now + - nail down details of: + - what is a delegation vs invocation + - how this integrates with our billing service +- [ ] design and specify the first version of the gateway configuration - [ ] research Redis and alternatives -- [ ] design the caching system -- [ ] work plan +- [ ] design the rate limits service +- [ ] build the rate limits service +- [ ] design the accounting service +- [ ] build the accounting service +- [ ] update hoverboard (?) to use the rate limits and accounting services +- [ ] update other pieces of infrastructure to use rate limits and accounting services (what are these?) + + ## Resources From f3aaa54f6389afc726491819ffe17c87b716f8fe Mon Sep 17 00:00:00 2001 From: Travis Vachon Date: Wed, 29 May 2024 16:26:55 -0700 Subject: [PATCH 10/11] feat: add more options for Redis-compatible services --- rfc/egress-billing.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/rfc/egress-billing.md b/rfc/egress-billing.md index 5b4037e..1c36eea 100644 --- a/rfc/egress-billing.md +++ b/rfc/egress-billing.md @@ -274,7 +274,13 @@ https://redis.io/blog/redis-adopts-dual-source-available-licensing/ We may want to consider using an open source alternative like https://github.com/nalgeon/redka if we are concerned about using "source available" products - my inclination is to use Redis but consider products like -Redka as a fallback in case Redis no longer meets our needs. +Redka as a fallback in case Redis no longer meets our needs. We may also want to consider using AWS or Cloudflare products with Redis-compatible APIs: + +https://aws.amazon.com/memorydb/ +https://aws.amazon.com/elasticache/ +https://developers.cloudflare.com/workers/databases/native-integrations/upstash/ + +Using one of these services is probably the most expedient way to prototype this - since the gateway currently runs on Cloudflare, Upstash is perhaps the most promising. ## TODO From 6d955e90c1cdcbcd5f796edff0654021b86b722e Mon Sep 17 00:00:00 2001 From: Travis Vachon Date: Thu, 30 May 2024 13:47:05 -0700 Subject: [PATCH 11/11] feat: clarify group section --- rfc/egress-billing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfc/egress-billing.md b/rfc/egress-billing.md index 1c36eea..d32098d 100644 --- a/rfc/egress-billing.md +++ b/rfc/egress-billing.md @@ -250,7 +250,7 @@ sequenceDiagram Note that `bafy..access` alone will not be enough to authorize retrieval of the content - the accounting system will need to combine it with -a CID-specific content commitment that has been delegated to `Group`. +a CID-specific content commitment that has been delegated to `Group` like `bafy..group`. ## Implementation Considerations