Skip to content

Commit

Permalink
Reintroduce provide records via PUT to HTTP delegated routing
Browse files Browse the repository at this point in the history
Previous work reduced the scope of IPIP-337 to read operations only. The
changes here re-introduce the write operations originally written by
@guseggert back into IPIP-337.

The specification documents the ability to provide Bitswap records over
`PUT` requests with advisory TTL. An implementation of the specification
is already present in go-libipfs.

See:
 - #370
  • Loading branch information
masih committed Feb 13, 2023
1 parent 4c1c5d7 commit 6336689
Showing 1 changed file with 103 additions and 3 deletions.
106 changes: 103 additions & 3 deletions routing/DELEGATED_CONTENT_ROUTING_HTTP.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ Specifications for some transfer protocols are provided in the "Transfer Protoco

### `GET /routing/v1/providers/{CID}`

#### Response codes
#### `GET` Response codes

- `200` (OK): the response body contains 0 or more records
- `404` (Not Found): must be returned if no matching records are found
- `422` (Unprocessable Entity): request does not conform to schema or semantic constraints

#### Response Body
#### `GET` Response Body

```json
{
Expand All @@ -90,6 +90,48 @@ Response limit: 100 providers

Each object in the `Providers` list is a *read provider record*.

### `PUT /routing/v1/providers`

#### `PUT` Response codes

- `200` (OK): the server processed the full list of provider records (possibly unsuccessfully, depending on the semantics of the particular records)
- `400` (Bad Request): the server deems the request to be invalid and cannot process it
- `422` (Unprocessable Entity): request does not conform to schema or semantic constraints
- `501` (Not Implemented): the server does not support providing records

#### `PUT` Request Body

```json
{
"Providers": [
{
"Protocol": "<protocol_name>",
"Schema": "bitswap",
...
}
]
}
```

Each object in the `Providers` list is a *write provider record*.

#### `PUT` Response Body

```json
{
"ProvideResults": [
{ ... }
]
}
```

- `ProvideResults` is a list of results in the same order as the `Providers` in the request, and the schema of each object is determined by the `Protocol` of the corresponding write object (called "Write Provider Records Response" in the Known Transfer Protocols section)
- This may contain output information such as TTLs, errors, etc.
- It is undefined whether the server will allow partial results
- The work for processing each provider record should be idempotent so that it can be retried without excessive cost in the case of full or partial failure of the request
- Default limit of 100 keys per request
- Implements pagination according to the Pagination section

## Pagination

This API does not support pagination, but optional pagination can be added in a backwards-compatible spec update.
Expand Down Expand Up @@ -118,7 +160,7 @@ limits, allowing every site to query the API for results:

```plaintext
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Methods: GET, PUT, OPTIONS
```

## Known Transfer Protocols
Expand Down Expand Up @@ -148,6 +190,60 @@ Specification: [ipfs/specs/BITSWAP.md](https://github.com/ipfs/specs/blob/main/B

The server should respect a passed `transport` query parameter by filtering against the `Addrs` list.

#### Bitswap Write Provider Records

```json
{
"Protocol": "transport-bitswap",
"Schema": "bitswap",
"Signature": "<signature>",
"Payload": "<payload>"
}
```

- `Signature`: a multibase-encoded signature of the sha256 hash of the `Payload` field, signed using the private key of the Peer ID specified in the `Payload` JSON. Signing details for specific key types should follow [libp2p/peerid specs](https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#key-types), unless stated otherwise.

- Servers may ignore this field if they do not require signature verification.
- `Payload`: a string containing a serialized JSON object which conforms with the following schema:

```json
{
"Keys": ["cid1", "cid2"],
"Timestamp": 0,
"AdvisoryTTL": 0,
"ID": "12D3K...",
"Addrs": ["/ip4/..."]
}
```

- `Keys` is a list of the CIDs being provided
- `Timestamp` is the current time
- `AdvisoryTTL` is the time by which the caller expects the server to keep the record available
- If this value is unknown, the caller may use a value of 0
- `ID` is the peer ID that was used to sign the record
- `Addrs` is a list of string-encoded multiaddrs

A [400 Bad Request](https://httpwg.org/specs/rfc9110.html#status.400) response code should be returned if the signature check fails.

Note that this only supports Peer IDs expressed as identity multihashes. Peer IDs with older key types that exceed 42 bytes are not verifiable since they only contain a hash of the key, not the key itself.
Normally, if the Peer ID contains only a hash of the key, then the key is obtained out-of-band (e.g. by fetching the block via IPFS).
If support for these Peer IDs is needed in the future, this spec can be updated to allow the client to provide the key and key type out-of-band by adding optional `PublicKey` and `PublicKeyType` fields, and if the Peer ID is a CID, then the server can verify the public key's authenticity against the CID, and then proceed with the rest of the verification scheme.

The `Payload` field is a string, not a proper JSON object, to prevent its contents from being accidentally parsed and re-encoded by intermediaries, which may change the order of JSON fields and thus cause the record to fail validation.

#### Write Provider Records Response

```json
{
"AdvisoryTTL": 0
}
```

- `AdvisoryTTL` is the time at which the server expects itself to drop the record
- If less than the `AdvisoryTTL` in the request, then the client should re-issue the request by that point
- If greater than the `AdvisoryTTL` in the request, then the server expects the client to be responsible for the content for up to that amount of time (TODO: this is ambiguous)
- If 0, the server makes no claims about the lifetime of the record

### Filecoin Graphsync

Multicodec name: `transport-graphsync-filecoinv1`
Expand All @@ -173,3 +269,7 @@ Specification: [ipfs/go-graphsync/blob/main/docs/architecture.md](https://github
- `PieceCID`: the CID of the [piece](https://spec.filecoin.io/systems/filecoin_files/piece/#section-systems.filecoin_files.piece) within which the data is stored
- `VerifiedDeal`: whether the deal corresponding to the data is verified
- `FastRetrieval`: whether the provider claims there is an unsealed copy of the data available for fast retrieval

#### Filecoin Graphsync Write Provider Records

There is currently no specified schema.

0 comments on commit 6336689

Please sign in to comment.