diff --git a/src/ipips/ipip-0428.md b/src/ipips/ipip-0428.md index f33cd1890..4f8777d1f 100644 --- a/src/ipips/ipip-0428.md +++ b/src/ipips/ipip-0428.md @@ -17,6 +17,9 @@ editors: url: https://protocol.ai/ relatedIssues: - https://github.com/ipfs/specs/issues/376 + - https://github.com/ipfs/boxo/pull/339 + - https://github.com/ipfs/kubo/pull/9932 + - https://github.com/ipfs/js-ipns/pull/234 order: 428 tags: ['ipips'] --- @@ -92,7 +95,6 @@ We can get to that future in two steps: V2-only records that are protobuf with only two fields: Data CBOR+signatureV2. - ### User benefit - End users: the main benefit for end user is the smaller size of IPNS Records and @@ -133,7 +135,6 @@ included at the end of this IPIP. Describe alternate designs that were considered and related work. 1. Just switch to V2-only as the new default! - - No, this would be a breaking change. We have to do this in two steps, because we've rushed the way V2 was introduced in 2021, and STILL require field copying, even when `signatureV1` is missing. So technically there was @@ -141,11 +142,10 @@ Describe alternate designs that were considered and related work. adjust validation to only care about CBOR values when there is no `signatureV1`. 2. Why keeping the outer protobuf envelope? Could we make IPNS DAG-CBOR-only? - - Due to how long it takes for decentralized network nodes to upgrade, we prefer evolution rather than revolution. - - Protobuf is an useful envelope for two reasons: - 1. ensures the opaque V2-only record can be passed and stored in existing infrastructure - 2. allows us to evolve IPNS record ("V3") in the future without impacting existing infrastructure + - Protobuf is a useful envelope for two reasons: + 1. Ensures the opaque V2-only record can be passed and stored in existing infrastructure. + 2. Allows us to evolve IPNS record ("V3") in the future without impacting existing infrastructure. ## Test fixtures @@ -153,10 +153,10 @@ TODO: IPNS record that is valid for 100 years and 1. V1-only → record invalid 1. V1+V2 (both signatures valid) → record valid -1. V1+V2 (both signatures valid, but 'value' is different in V1) → record invalid -1. V1+V2 (only V1 valid) → record invalid -1. V1+V2 (only V2 valid, V1 missing signature) → record valid (because we do V1 validation only when signatureV1 is present in protobuf) -1. V2-only (only V2 valid) → record valid +1. V1+V2 (both signatures valid, but 'value' is different in V1 pb) → record invalid +1. V1+V2 (only signatureV1 valid) → record invalid +1. V1+V2 (only signatureV2 valid) → record valid +1. V2-only (no V1 fields) → record valid ### Copyright diff --git a/src/ipns/ipns-record.md b/src/ipns/ipns-record.md index 5be866659..2b77bca91 100644 --- a/src/ipns/ipns-record.md +++ b/src/ipns/ipns-record.md @@ -239,7 +239,7 @@ IPNS implementations MUST support sending and receiving a serialized `IpnsEntry` less than or equal to **10 KiB** in size. Records over the limit MAY be ignored. Handling records larger than the -limit is not recommended so as to keep compatibility with implementations and +limit is not recommended to keep compatibility with implementations and transports that follow this specification. ### Backward Compatibility @@ -316,7 +316,7 @@ Creating a new IPNS record MUST follow the below steps: serialized copy in `IpnsEntry.pubKey` - This step SHOULD be skipped for Ed25519, and any other key types that are - small enough (32 bytes) to be inlined inside of [IPNS Name](#ipns-name) itself. + small enough (32 bytes) to be inlined inside [IPNS Name](#ipns-name) itself. 5. Create `IpnsEntry.signatureV2` @@ -327,10 +327,9 @@ Creating a new IPNS record MUST follow the below steps: - Sign concatenated bytes from the previous step using the private key, and store the signature in `IpnsEntry.signatureV2` -7. Confirm that the serialized `IpnsEntry` bytes sum to less than or equal to +6. Confirm that the serialized `IpnsEntry` bytes sum to less than or equal to [the size limit](#record-size-limit). - Created `IpnsEntry` protobuf includes signed `data` CBOR and optional public key: ```protobuf @@ -357,14 +356,14 @@ the [DAG-CBOR specification](https://ipld.io/specs/codecs/dag-cbor/spec/): } ``` -#### Record Creation: V1+V2 with Legacy V1 Signature +#### Record Creation with Legacy SignatureV1 :::warning Fields related to `signatureV1` has been deprecated since 2021. V1 signatures are no longer used during record validation. -However it may be necessary to create a V1+V2 record that allows legacy +However, it may be necessary to create a V2+V1 record that allows legacy software to use IPNS to upgrade itself to the latest version which supports V2 signatures. In such case, follow the steps below. @@ -378,7 +377,7 @@ signatures. In such case, follow the steps below. - If you want to store additional metadata in the record, add it under unique keys at `IpnsEntry.data`. - The order of fields impacts signature verification. If you are using an alternative CBOR implementation, make sure the CBOR field order follows :cite[rfc7049] sorting rules: length and then bytewise. The order of fields impacts signature verification. 4. If your public key can't be inlined inside the IPNS Name, include a serialized copy in `IpnsEntry.pubKey` - - This step SHOULD be skipped for Ed25519, and any other key types that are inlined inside of [IPNS Name](#ipns-name) itself. + - This step SHOULD be skipped for Ed25519, and any other key types that are inlined inside [IPNS Name](#ipns-name) itself. 5. Create `IpnsEntry.signatureV2` - Create bytes for signing by concatenating `ipns-signature:` prefix (bytes in hex: `69706e732d7369676e61747572653a`) with raw CBOR bytes from `IpnsEntry.data` - Sign concatenated bytes from the previous step using the private key, and store the signature in `IpnsEntry.signatureV2` @@ -420,11 +419,13 @@ Implementations MUST ensure `IpnsEntry.signatureV2` is used instead. Value from `IpnsEntry.value` MUST never be used unless it is the same as signed `IpnsEntry.data[Value]`. -## Integration with IPFS +## Appendix: Notes for Implementers + +### Integration with IPFS Below are additional notes for implementers, documenting how IPNS is integrated within IPFS ecosystem. -### Local Record +#### Local Record This record is stored in the peer's repo datastore and contains the **latest** version of the IPNS record published by the provided key. This record is useful for republishing, as well as tracking the sequence number. A legacy convention that implementers MAY want to follow is to store serialized `IpnsEntry` under: @@ -433,7 +434,7 @@ A legacy convention that implementers MAY want to follow is to store serialized Note: Base32 according to the :cite[rfc4648]. -### Routing Record +#### Routing Record The routing record is spread across the network according to the available routing systems. The two routing systems currently available in IPFS are the [libp2p Kademlia DHT](https://github.com/libp2p/specs/tree/master/kad-dht) and :cite[ipns-pubsub-router]. @@ -445,7 +446,11 @@ The two routing systems currently available in IPFS are the [libp2p Kademlia DHT As the `pubsub` topics must be `utf-8` for interoperability among different implementations, IPNS over PubSub topics use additional wrapping `/record/base64url-unpadded(key)` -### Implementations +#### Reference Implementations + +When language-specific nuances are not covered by this specification, consider +below reference implementations as the baseline for making decisions around +interoperability. - -