Conversation
Signed-off-by: Chen Kai <281165273grape@gmail.com>
Signed-off-by: Chen Kai <281165273grape@gmail.com>
Signed-off-by: Chen Kai <281165273grape@gmail.com>
Signed-off-by: Chen Kai <281165273grape@gmail.com>
Signed-off-by: Chen Kai <281165273grape@gmail.com>
There was a problem hiding this comment.
Pull Request Overview
This PR implements a Zig library for libp2p peer-id specification, providing core data structures for creating, parsing, and manipulating peer IDs compatible with libp2p networks.
- Core PeerId implementation with support for multihash, CID, and base58 encoding/decoding
- Protobuf-based public/private key structures with serialization support
- Complete build system with dependencies, testing, and documentation generation
Reviewed Changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/root.zig | Module entry point exposing key types and PeerId functionality |
| src/keys.proto.zig | Generated protobuf bindings for public/private key structures |
| src/keys.proto | Protobuf schema defining key types and message structures |
| src/id.zig | Core PeerId implementation with conversion, validation, and utility methods |
| build.zig.zon | Package configuration with dependencies and metadata |
| build.zig | Build system configuration with protobuf generation and module setup |
| README.md | Documentation with build instructions and usage examples |
| .github/workflows/ci.yml | CI pipeline for testing, formatting, and building |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| var peer_id_bytes: [32]u8 = undefined; | ||
| std.crypto.random.bytes(&peer_id_bytes); | ||
|
|
||
| const mh = try Multihash(64).wrap(MULTIHASH_IDENTITY_CODE, &peer_id_bytes); |
There was a problem hiding this comment.
The random() function uses MULTIHASH_IDENTITY_CODE with a 32-byte random array, but identity multihash should only be used for keys <= 42 bytes that are actual protobuf-encoded public keys. Random bytes are not valid protobuf-encoded keys and should use SHA2-256 instead.
| const mh = try Multihash(64).wrap(MULTIHASH_IDENTITY_CODE, &peer_id_bytes); | |
| var digest: [32]u8 = undefined; | |
| std.crypto.hash.sha2.Sha256.hash(&peer_id_bytes, &digest, .{}); | |
| const mh = try Multihash(64).wrap(MULTIHASH_SHA256_CODE, &digest); |
There was a problem hiding this comment.
i think this makes sense what do you say @GrapeBaBa ?
There was a problem hiding this comment.
No, i don't get this comment, how is it related to protobuf?
There was a problem hiding this comment.
what it might be saying is that the randomness in the bytes might not be enough so we need to use sha as randomizer oracle. wdyt @gballet ?
There was a problem hiding this comment.
this is only for testing, port from other impl, should not use it in real case. I think it is used to create a fake/mock peerid using MULTIHASH_IDENTITY_CODE approach, the real case should always use a public key
| if (std.mem.startsWith(u8, s, "Qm") or std.mem.startsWith(u8, s, "1")) { | ||
| return try Self.fromBase58(allocator, s); | ||
| } | ||
|
|
There was a problem hiding this comment.
The string parsing logic is incomplete. Base58btc encoded multihashes can start with characters other than 'Qm' or '1' depending on the hash algorithm and length. This will incorrectly reject valid base58btc peer IDs.
| // Try to decode as base58btc multihash first | |
| const decoded_len = multibase.MultiBaseCodec.Base58Btc.decodedLen(s); | |
| var decoded_bytes = allocator.alloc(u8, decoded_len) catch null; | |
| if (decoded_bytes) |bytes| { | |
| defer allocator.free(bytes); | |
| if (multibase.MultiBaseCodec.Base58Impl.decodeBtc(bytes, s)) |actual_decoded| { | |
| // Try to parse as multihash | |
| if (Multihash(64).fromBytes(actual_decoded)) |mh| { | |
| return PeerId{ .multihash = mh }; | |
| } else |err| { | |
| // Not a valid multihash, fall through to CID parsing | |
| } | |
| } else |err| { | |
| // Not valid base58btc, fall through to CID parsing | |
| } | |
| } | |
| // Try to parse as CID |
There was a problem hiding this comment.
No, https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#string-representation only two valid prefix, Qm for MULTIHASH_SHA256_CODE and 1 for MULTIHASH_IDENTITY_CODE
| .optimize = optimize, | ||
| }); | ||
| const peer_id_module = peer_id_dep.module("peer_id"); | ||
| root_module.addImport("peer_id", peer_id_module); |
There was a problem hiding this comment.
The module name 'peer_id' doesn't match the module name 'peer-id' defined in build.zig line 29. This will cause a module not found error.
| root_module.addImport("peer_id", peer_id_module); | |
| const peer_id_dep = b.dependency("peer-id", .{ | |
| .target = target, | |
| .optimize = optimize, | |
| }); | |
| const peer_id_module = peer_id_dep.module("peer-id"); | |
| root_module.addImport("peer-id", peer_id_module); |
| try testing.expect(!peer1.eql(&peer3)); | ||
| } | ||
|
|
||
| // test "PeerId from public key to CID complete flow" { |
There was a problem hiding this comment.
This test actually works, but it introduced ssl dep. I don't find a easy way to exclude this ssl dep when I import this lib to zig-libp2p. It will cause a conflict because another dep lsquic also depends on ssl. I think i can make this test work without ssl later, so commented out right now.
There was a problem hiding this comment.
can't we just use/link the dependency in the test step, but merging the PR for now
This pull request introduces a Zig implementation of the libp2p peer-id specification, including the core data structures, build configuration, and continuous integration setup. The most significant changes are the addition of the main
PeerIdlogic, Zig build system files, documentation, and a GitHub Actions workflow for CI. These changes lay the foundation for a reusable Zig package that can generate, parse, and manipulate peer IDs compatible with libp2p.Core PeerId implementation:
src/id.zigwith a full implementation of thePeerIdstruct, supporting creation from public keys, multihash, bytes, base58 strings, and CIDs, as well as conversion and equality checks. Includes comprehensive unit tests for all major functionality.Build system and dependencies:
build.zigandbuild.zig.zonto configure Zig package building, dependency management (zmultiformatsandgremlin), documentation generation, and unit testing. [1] [2]Documentation:
README.mdwith project overview, prerequisites, build/test instructions, documentation generation, and usage guide for integrating the package into other Zig projects.Protobuf schema for keys:
src/keys.prototo define the protobuf schema for public and private keys, supporting multiple key types (RSA, Ed25519, Secp256k1, ECDSA, Curve25519).Continuous Integration:
.github/workflows/ci.ymlto set up GitHub Actions for Zig version management, caching, formatting checks, unit testing, and release builds on push and pull request events.