-
Notifications
You must be signed in to change notification settings - Fork 1.1k
fix(core)!: use standard peer-record domain and payload type #6205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Add cross-implementation interoperability tests that verify Rust can decode and verify signed peer records created by Go and JavaScript libp2p implementations. Test fixtures: - JavaScript fixture generated using @libp2p/peer-record - Go fixture generated using go-libp2p/core/peer - Both use standard domain 'libp2p-peer-record' and payload type [3, 1] Current behavior: - Tests FAIL with UnexpectedPayloadType error - Rust expects '/libp2p/routing-state-record' [47, 108, ...] - JS/Go provide standard payload type [3, 1] This demonstrates the incompatibility bug that will be fixed in the next commit.
Changes PeerRecord to use the standard libp2p-peer-record constants instead of routing-state-record values, ensuring interoperability with Go and JavaScript implementations. Changes: - PAYLOAD_TYPE: '/libp2p/routing-state-record' -> [0x03, 0x01] - DOMAIN_SEP: 'libp2p-routing-state' -> 'libp2p-peer-record' The payload type [0x03, 0x01] is the multicodec identifier for libp2p-peer-record, as defined in the multicodec table: https://github.com/multiformats/multicodec/blob/master/table.csv This matches the implementations in: - Go: https://github.com/libp2p/go-libp2p/blob/master/core/peer/record.go#L21-L29 - JS: https://github.com/libp2p/js-libp2p/blob/main/packages/peer-record/src/peer-record/consts.ts#L1-L7 BREAKING CHANGE: Existing signed peer records created with Rust libp2p will not be verifiable with this change, as the domain and payload type have changed. However, this fixes interoperability with Go/JS libp2p. Fixes cross-implementation compatibility issue where Rust could not verify signed peer records from Go/JS implementations.
Documents the breaking fix that aligns PeerRecord constants with Go/JS implementations, changing domain to 'libp2p-peer-record' and payload type to [0x03, 0x01] for cross-implementation compatibility. Pull-Request: libp2p#6205.
Bumps libp2p-core from 0.43.1 to 0.44.0 due to breaking change in PeerRecord domain and payload type constants. This is a minor version bump (not patch) because the change breaks compatibility with existing Rust-created peer records. The breaking change: - PAYLOAD_TYPE: '/libp2p/routing-state-record' -> [0x03, 0x01] - DOMAIN_SEP: 'libp2p-routing-state' -> 'libp2p-peer-record' Existing signed peer records created with the old constants will not be verifiable after this change, but the new constants align with Go/JS implementations and fix cross-implementation interoperability. See also: - PR libp2p#6205: The fix implementation - Issue libp2p#6204: Original bug report"
jxs
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Ron, and thanks for this!
This does not seem like a bug, as Thomas when implementing followed the RFC:
Domain strings may be any valid UTF-8 string, but should be fairly short and descriptive of their use case, for example "libp2p-routing-record".
to avoid breaking changes I'd suggest we create a new method like from_signed_envelope_with_domain wdyt? I also don't think we need the interop files
CC @elenaf9
The issue here is not only about the domain. Even if we allow the caller to provide a domain string, it’s still not enough — because the failure occurs earlier, due to an invalid payload type (BadPayload(UnexpectedPayloadType)). Right now, the Rust implementation signs a peer record using defaults that do not match the values used in Go, JS, and Python. Those implementations validate against a specific domain and payload type. For example: Go: Py: Because of this, leaving the current Rust function as-is will produce signatures that will not interoperate with other libp2p stacks. It will sign a PeerRecord — but one that other languages will reject. So at minimum, we should either: Remove the existing no-arg function and introduce a new function that requires both domain and payload type explicitly, |
Description
Description
Fixes #6204
Changes
PeerRecordto use the standard libp2p-peer-record constants instead of routing-state-record values, ensuring interoperability with Go and JavaScript implementations.Changes
PAYLOAD_TYPE:"/libp2p/routing-state-record"→[0x03, 0x01]DOMAIN_SEP:"libp2p-routing-state"→"libp2p-peer-record"The payload type
[0x03, 0x01]is the multicodec identifier for libp2p-peer-record, as defined in:This matches the implementations in:
Testing
Added cross-implementation interoperability tests:
core/tests/peer_record_interop.rs- Tests that verify Rust can decode and verify signed peer records from Go and JScore/tests/fixtures/- Test fixtures with signed peer records generated by Go and JS implementationsBefore the fix, these tests failed with:
BadPayload(UnexpectedPayloadType { expected: [47, 108, ...], got: [3, 1] })
After the fix, all tests pass.
Breaking Change
Notes & open questions
None - this is a straightforward alignment with the standard used by other libp2p implementations.
Change checklist