feat(versioning): snapshot corpus per spec version
mdBook / build (push) Canceled after 0s
mdBook / deploy (push) Canceled after 0s

A frozen spec is only meaningful if it's paired with the corpus
that was current at release time — otherwise a v0.1.0 reader
follows "see corpus/payloads/ack/" and lands on a file whose
test vectors may have changed since v0.1.0 was cut.

Three changes:

1. `cut-version` now copies BOTH src/ AND corpus/ into the
   snapshot directory. A release is the pair, not just the text.

2. The corpus URL rewriting in cut-version now retargets
   /tree/main/corpus -> /tree/main/versions/<v>/corpus (and the
   blob variant). This lets the link resolve on GitHub from main
   alone — no git tag required, since the frozen copy is a real
   path under main. Downgrades the "tag is REQUIRED" message from
   last commit back to "optionally tag the commit".

3. The frozen corpus's spec_ref fields get rewritten too: from
   `src/04-payload-ack.md` to `versions/<v>/04-payload-ack.md`,
   so a reader following a test vector lands on the spec text the
   vector was paired with at release time.

versions/v0.1.0/ regenerated from scratch via `just cut-version v0.1.0`
to pick up the corpus snapshot + the new sed patterns. The release
is now self-consistent: v0.1.0 spec links go to v0.1.0 corpus, which
links back to v0.1.0 spec.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
swaitsandClaude Opus 4.7 committed 2026-05-12 10:38:02 -06:00
1 parent f83d4088e3
commit 9232c16f7c
71 files changed
+5924 -28

No files matched your search

@@ -0,0 +1,75 @@
{
"$schema": "../../../schema/test-vector.schema.json",
"name": "Framing - Decode Only",
"spec_ref": "versions/v0.1.0/01-wire-format.md",
"protocol_version": 0,
"description": "Tests one-way decode cases where the binary is valid to decode but may not be the canonical encoding a conformant encoder would produce.",
"vectors": [
{
"id": "dec-001",
"description": "Decode-only: ACK FLOOD with trailing bytes beyond the 4-byte CRC payload",
"type": "decode_only",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "DEADBEEF"
}
},
"binary": "0D 00 DEADBEEF 00",
"notes": "Binary has 1 trailing byte after the 4-byte ACK CRC. Decoders MUST accept this (payload_len includes the extra byte). Encoders would not produce trailing bytes."
},
{
"id": "dec-002",
"description": "Decode-only: raw_custom FLOOD with path hash_count=0 but hash_size=2",
"type": "decode_only",
"structured": {
"header": {
"version": 0,
"payload_type": "raw_custom",
"route_type": "flood"
},
"path": {
"hash_size": 2,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "AA"
}
},
"binary": "3D 40 AA",
"notes": "Path_len byte 0x40 encodes hash_size=2 (bits 6-7 = 01) with hash_count=0. Decoders must handle non-default hash_size even when hash_count is zero. Encoders typically default hash_size=1 when hash_count=0."
},
{
"id": "dec-003",
"description": "Decode-only: raw_custom FLOOD with path hash_size=3 and hash_count=0",
"type": "decode_only",
"structured": {
"header": {
"version": 0,
"payload_type": "raw_custom",
"route_type": "flood"
},
"path": {
"hash_size": 3,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "BB"
}
},
"binary": "3D 80 BB",
"notes": "Path_len byte 0x80 encodes hash_size=3 (bits 6-7 = 10) with hash_count=0. Same as dec-002 but with hash_size=3."
}
]
}
@@ -0,0 +1,33 @@
{
"$schema": "../../schema/test-vector.schema.json",
"name": "Framing - Empty Payload Rejection",
"spec_ref": "versions/v0.1.0/01-wire-format.md",
"protocol_version": 0,
"description": "Verifies that packets with zero-length payload are rejected. The reference implementation (Packet::readFrom) checks 'if (i >= len) return false' after reading header+transport+path_len+path, requiring at least 1 byte of payload.",
"vectors": [
{
"id": "ep-001",
"description": "FLOOD packet with no payload bytes (just header + path_len)",
"type": "invalid",
"binary": "0D 00",
"expected_error": "empty_payload",
"notes": "2 bytes total: header 0x0D + path_len 0x00. No payload bytes remain. readFrom returns false because i(2) >= len(2)."
},
{
"id": "ep-002",
"description": "TRANSPORT_FLOOD with no payload (header + transport + path_len only)",
"type": "invalid",
"binary": "0C 0000 0000 00",
"expected_error": "empty_payload",
"notes": "6 bytes: header(1) + transport(4) + path_len(1). i=6, len=6, so i>=len = true."
},
{
"id": "ep-003",
"description": "FLOOD packet with path but no payload",
"type": "invalid",
"binary": "0D 02 AABB",
"expected_error": "empty_payload",
"notes": "4 bytes: header(1) + path_len(1) + path(2). i=4, len=4."
}
]
}
@@ -0,0 +1,139 @@
{
"$schema": "../../schema/test-vector.schema.json",
"name": "Framing - Maximum Size Packets",
"spec_ref": "versions/v0.1.0/01-wire-format.md",
"protocol_version": 0,
"description": "Tests packets at or near the maximum wire size of 255 bytes (MAX_TRANS_UNIT). Verifies size calculation: total = 1 (header) + transport(0|4) + 1 (path_len) + path_bytes + payload_len.",
"vectors": [
{
"id": "max-001",
"description": "Maximum FLOOD packet: 255 bytes with empty path and 253-byte payload",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "raw_custom",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFC"
}
},
"binary": "3D 00 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFC",
"notes": "Total: 1 + 0 + 1 + 0 + 253 = 255 bytes. However payload exceeds MAX_PACKET_PAYLOAD (184). This is a wire-level max size test only; payload-level validation would reject this."
},
{
"id": "max-002",
"description": "Maximum valid FLOOD packet respecting MAX_PACKET_PAYLOAD: 1 + 1 + 0 + 184 = 186 bytes",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "raw_custom",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7"
}
},
"binary": "3D 00 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7",
"notes": "Total: 1 + 1 + 184 = 186 bytes. Payload is exactly MAX_PACKET_PAYLOAD (184 bytes = 0x00..0xB7)."
},
{
"id": "max-003",
"description": "Large FLOOD packet with maximum path (63 bytes) and payload",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "raw_custom",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 63,
"hashes": [
"01",
"02",
"03",
"04",
"05",
"06",
"07",
"08",
"09",
"0A",
"0B",
"0C",
"0D",
"0E",
"0F",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
"17",
"18",
"19",
"1A",
"1B",
"1C",
"1D",
"1E",
"1F",
"20",
"21",
"22",
"23",
"24",
"25",
"26",
"27",
"28",
"29",
"2A",
"2B",
"2C",
"2D",
"2E",
"2F",
"30",
"31",
"32",
"33",
"34",
"35",
"36",
"37",
"38",
"39",
"3A",
"3B",
"3C",
"3D",
"3E",
"3F"
]
},
"payload": {
"data": "DEADBEEF"
}
},
"binary": "3D 3F 0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F DEADBEEF",
"notes": "Total: 1 + 1 + 63 + 4 = 69 bytes. Max path with small payload."
}
]
}
@@ -0,0 +1,127 @@
{
"$schema": "../../schema/test-vector.schema.json",
"name": "Framing - Minimal Valid Packets",
"spec_ref": "versions/v0.1.0/01-wire-format.md",
"protocol_version": 0,
"description": "Tests the smallest valid packets for each route type. A valid packet must have at least header(1) + path_len(1) + payload(1+) bytes, plus 4 bytes for transport codes if applicable.",
"vectors": [
{
"id": "min-001",
"description": "Minimal FLOOD packet: 3 bytes (header + path_len + 1-byte payload)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "raw_custom",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "FF"
}
},
"binary": "3D 00 FF",
"notes": "Smallest valid FLOOD packet: 3 bytes total."
},
{
"id": "min-002",
"description": "Minimal DIRECT packet: 3 bytes",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "raw_custom",
"route_type": "direct"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "FF"
}
},
"binary": "3E 00 FF",
"notes": "Smallest valid DIRECT packet: 3 bytes total."
},
{
"id": "min-003",
"description": "Minimal TRANSPORT_FLOOD packet: 7 bytes (header + 4 transport + path_len + 1-byte payload)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "raw_custom",
"route_type": "transport_flood"
},
"transport_codes": [
0,
0
],
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "FF"
}
},
"binary": "3C 0000 0000 00 FF",
"notes": "Smallest valid TRANSPORT_FLOOD packet: 7 bytes total."
},
{
"id": "min-004",
"description": "Minimal TRANSPORT_DIRECT packet: 7 bytes",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "raw_custom",
"route_type": "transport_direct"
},
"transport_codes": [
0,
0
],
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "FF"
}
},
"binary": "3F 0000 0000 00 FF",
"notes": "Smallest valid TRANSPORT_DIRECT packet: 7 bytes total."
},
{
"id": "min-005",
"description": "Minimal ACK via FLOOD: 6 bytes (header + path_len + 4-byte CRC)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000000"
}
},
"binary": "0D 00 00000000",
"notes": "ACK with zero CRC. 6 bytes total."
}
]
}
@@ -0,0 +1,165 @@
{
"$schema": "../../schema/test-vector.schema.json",
"name": "Header - Combined Field Encoding",
"spec_ref": "versions/v0.1.0/02-header.md",
"protocol_version": 0,
"description": "Combinatorial tests of header byte encoding, exercising various combinations of version, payload type, and route type to verify correct bit packing.",
"vectors": [
{
"id": "hdr-000",
"description": "All-zero header: version=0, request=0, transport_flood=0",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "request",
"route_type": "transport_flood"
},
"transport_codes": [
0,
0
],
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"dest_hash": "00",
"src_hash": "00",
"cipher_mac": "0000",
"ciphertext": "00000000000000000000000000000000"
}
},
"binary": "00 0000 0000 00 0000 0000 00000000000000000000000000000000",
"notes": "Header: (0<<6)|(0<<2)|0 = 0x00."
},
{
"id": "hdr-001",
"description": "Version=0, ADVERT, DIRECT route",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "advert",
"route_type": "direct"
},
"path": {
"hash_size": 1,
"hash_count": 2,
"hashes": [
"AA",
"BB"
]
},
"payload": {
"data": "FF"
}
},
"binary": "12 02 AABB FF",
"notes": "Header: (0<<6)|(4<<2)|2 = 0x12. path_len=0x02 (hash_size=1, count=2). Path: AA BB."
},
{
"id": "hdr-002",
"description": "Version=1, CONTROL, FLOOD route",
"type": "encode_decode",
"structured": {
"header": {
"version": 1,
"payload_type": "control",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "FF"
}
},
"binary": "6D 00 FF",
"notes": "Header: (1<<6)|(11<<2)|1 = 0x40+0x2C+0x01 = 0x6D."
},
{
"id": "hdr-003",
"description": "Version=0, RAW_CUSTOM, TRANSPORT_DIRECT with non-trivial transport codes",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "raw_custom",
"route_type": "transport_direct"
},
"transport_codes": [
256,
512
],
"path": {
"hash_size": 1,
"hash_count": 1,
"hashes": [
"AA"
]
},
"payload": {
"data": "CAFEBABE"
}
},
"binary": "3F 0001 0002 01 AA CAFEBABE",
"notes": "Header: (0<<6)|(15<<2)|3 = 0x3F. Transport codes: 256=0x0100 LE=0001, 512=0x0200 LE=0002."
},
{
"id": "hdr-004",
"description": "Version=0, TRACE, FLOOD with path",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "trace",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 3,
"hashes": [
"AA",
"BB",
"CC"
]
},
"payload": {
"data": "0102030405060708 09"
}
},
"binary": "25 03 AABBCC 010203040506070809",
"notes": "Header: (0<<6)|(9<<2)|1 = 0x25. path_len=0x03 (1-byte hashes, 3 hops)."
},
{
"id": "hdr-005",
"description": "Maximum header value that isn't 0xFF sentinel: version=2, RAW_CUSTOM, TRANSPORT_DIRECT",
"type": "encode_decode",
"structured": {
"header": {
"version": 2,
"payload_type": "raw_custom",
"route_type": "transport_direct"
},
"transport_codes": [
0,
0
],
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "AA"
}
},
"binary": "BF 0000 0000 00 AA",
"notes": "Header: (2<<6)|(15<<2)|3 = 0x80+0x3C+0x03 = 0xBF."
}
]
}
@@ -0,0 +1,308 @@
{
"$schema": "../../schema/test-vector.schema.json",
"name": "Header - Payload Types",
"spec_ref": "versions/v0.1.0/02-header.md",
"protocol_version": 0,
"description": "Tests encoding of all defined payload types in the header byte. Uses FLOOD routing and minimal payloads to isolate header encoding.",
"vectors": [
{
"id": "pt-000",
"description": "Payload type REQUEST (0x00) - header byte encodes type in bits 2-5",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "request",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"dest_hash": "AB",
"src_hash": "CD",
"cipher_mac": "1122",
"ciphertext": "DEADBEEFCAFEBABE0102030405060708"
}
},
"binary": "01 00 ABCD 1122 DEADBEEFCAFEBABE0102030405060708",
"notes": "Header: (0<<6)|(0<<2)|1 = 0x01. Payload: dest_hash(1) + src_hash(1) + MAC(2) + 16 bytes ciphertext."
},
{
"id": "pt-001",
"description": "Payload type RESPONSE (0x01)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "response",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"dest_hash": "AB",
"src_hash": "CD",
"cipher_mac": "1122",
"ciphertext": "DEADBEEFCAFEBABE0102030405060708"
}
},
"binary": "05 00 ABCD 1122 DEADBEEFCAFEBABE0102030405060708",
"notes": "Header: (0<<6)|(1<<2)|1 = 0x05."
},
{
"id": "pt-002",
"description": "Payload type TXT_MSG (0x02)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "txt_msg",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"dest_hash": "AB",
"src_hash": "CD",
"cipher_mac": "1122",
"ciphertext": "DEADBEEFCAFEBABE0102030405060708"
}
},
"binary": "09 00 ABCD 1122 DEADBEEFCAFEBABE0102030405060708",
"notes": "Header: (0<<6)|(2<<2)|1 = 0x09."
},
{
"id": "pt-003",
"description": "Payload type ACK (0x03)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "DEADBEEF"
}
},
"binary": "0D 00 EFBEADDE",
"notes": "Header: (0<<6)|(3<<2)|1 = 0x0D. CRC 0xDEADBEEF as LE = EFBEADDE."
},
{
"id": "pt-004",
"description": "Payload type ADVERT (0x04) - minimal advert with 1 byte payload",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "advert",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "FF"
}
},
"binary": "11 00 FF",
"notes": "Header: (0<<6)|(4<<2)|1 = 0x11. Using raw payload to test header encoding in isolation."
},
{
"id": "pt-005",
"description": "Payload type GRP_TXT (0x05)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "grp_txt",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"channel_hash": "AB",
"cipher_mac": "1122",
"ciphertext": "DEADBEEFCAFEBABE0102030405060708"
}
},
"binary": "15 00 AB 1122 DEADBEEFCAFEBABE0102030405060708",
"notes": "Header: (0<<6)|(5<<2)|1 = 0x15."
},
{
"id": "pt-006",
"description": "Payload type GRP_DATA (0x06)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "grp_data",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"channel_hash": "AB",
"cipher_mac": "1122",
"ciphertext": "DEADBEEFCAFEBABE0102030405060708"
}
},
"binary": "19 00 AB 1122 DEADBEEFCAFEBABE0102030405060708",
"notes": "Header: (0<<6)|(6<<2)|1 = 0x19."
},
{
"id": "pt-007",
"description": "Payload type ANON_REQ (0x07)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "anon_req",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "FF"
}
},
"binary": "1D 00 FF",
"notes": "Header: (0<<6)|(7<<2)|1 = 0x1D. Minimal payload to test header."
},
{
"id": "pt-008",
"description": "Payload type PATH (0x08)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "path",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "FF"
}
},
"binary": "21 00 FF",
"notes": "Header: (0<<6)|(8<<2)|1 = 0x21."
},
{
"id": "pt-009",
"description": "Payload type TRACE (0x09)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "trace",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "FF"
}
},
"binary": "25 00 FF",
"notes": "Header: (0<<6)|(9<<2)|1 = 0x25."
},
{
"id": "pt-010",
"description": "Payload type MULTIPART (0x0A)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "multipart",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "FF"
}
},
"binary": "29 00 FF",
"notes": "Header: (0<<6)|(10<<2)|1 = 0x29."
},
{
"id": "pt-011",
"description": "Payload type CONTROL (0x0B)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "control",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "FF"
}
},
"binary": "2D 00 FF",
"notes": "Header: (0<<6)|(11<<2)|1 = 0x2D."
},
{
"id": "pt-012",
"description": "Payload type RAW_CUSTOM (0x0F)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "raw_custom",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"data": "CAFEBABE"
}
},
"binary": "3D 00 CAFEBABE",
"notes": "Header: (0<<6)|(15<<2)|1 = 0x3D."
}
]
}
@@ -0,0 +1,131 @@
{
"$schema": "../../schema/test-vector.schema.json",
"name": "Header - Route Types",
"spec_ref": "versions/v0.1.0/02-header.md",
"protocol_version": 0,
"description": "Tests encoding and decoding of all 4 route types in the header byte, using ACK (payload_type=3) as a simple payload.",
"vectors": [
{
"id": "rt-000",
"description": "Route type TRANSPORT_FLOOD (0x00) with ACK payload",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "transport_flood"
},
"transport_codes": [
0,
0
],
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "01020304"
}
},
"binary": "0C 0000 0000 00 04030201",
"notes": "Header: version=0, payload_type=3 (ACK), route_type=0 (TRANSPORT_FLOOD). 0x0C = (0<<6)|(3<<2)|0. Transport codes both zero. path_len=0x00 (hash_size=1, count=0). ACK CRC 0x01020304 as LE = 04030201."
},
{
"id": "rt-001",
"description": "Route type FLOOD (0x01) with ACK payload",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "01020304"
}
},
"binary": "0D 00 04030201",
"notes": "Header: 0x0D = (0<<6)|(3<<2)|1. No transport codes. path_len=0x00. ACK CRC as LE."
},
{
"id": "rt-002",
"description": "Route type DIRECT (0x02) with ACK payload",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "direct"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "01020304"
}
},
"binary": "0E 00 04030201",
"notes": "Header: 0x0E = (0<<6)|(3<<2)|2. No transport codes."
},
{
"id": "rt-003",
"description": "Route type TRANSPORT_DIRECT (0x03) with ACK payload",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "transport_direct"
},
"transport_codes": [
4660,
22136
],
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "01020304"
}
},
"binary": "0F 3412 7856 00 04030201",
"notes": "Header: 0x0F = (0<<6)|(3<<2)|3. Transport codes: 4660=0x1234 as LE=3412, 22136=0x5678 as LE=7856."
},
{
"id": "rt-004",
"description": "TRANSPORT_FLOOD with non-zero transport codes",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "transport_flood"
},
"transport_codes": [
65535,
1
],
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "FFFFFFFF"
}
},
"binary": "0C FFFF 0100 00 FFFFFFFF",
"notes": "Transport code 1: 0xFFFF as LE = FFFF. Transport code 2: 1 as LE = 0100. CRC 0xFFFFFFFF as LE."
}
]
}
@@ -0,0 +1,97 @@
{
"$schema": "../../schema/test-vector.schema.json",
"name": "Header - Protocol Versions",
"spec_ref": "versions/v0.1.0/02-header.md",
"protocol_version": 0,
"description": "Tests encoding of all 4 protocol version values in header bits 6-7. Uses ACK (type=3) with FLOOD routing as a simple baseline.",
"vectors": [
{
"id": "ver-000",
"description": "Version 0 (V1, current) - bits 6-7 = 00",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 00 01000000",
"notes": "Header: (0<<6)|(3<<2)|1 = 0x0D. Version 0 = V1."
},
{
"id": "ver-001",
"description": "Version 1 (V2, reserved) - bits 6-7 = 01",
"type": "encode_decode",
"structured": {
"header": {
"version": 1,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "4D 00 01000000",
"notes": "Header: (1<<6)|(3<<2)|1 = 0x4D. Version 1 = V2 (reserved)."
},
{
"id": "ver-002",
"description": "Version 2 (V3, reserved) - bits 6-7 = 10",
"type": "encode_decode",
"structured": {
"header": {
"version": 2,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "8D 00 01000000",
"notes": "Header: (2<<6)|(3<<2)|1 = 0x8D. Version 2 = V3 (reserved)."
},
{
"id": "ver-003",
"description": "Version 3 (V4, reserved) - bits 6-7 = 11",
"type": "encode_decode",
"structured": {
"header": {
"version": 3,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "CD 00 01000000",
"notes": "Header: (3<<6)|(3<<2)|1 = 0xCD. Version 3 = V4 (reserved)."
}
]
}
@@ -0,0 +1,57 @@
{
"$schema": "../../schema/test-vector.schema.json",
"name": "Invalid - Bad Path Length Encoding",
"spec_ref": "versions/v0.1.0/03-path.md",
"protocol_version": 0,
"description": "Tests invalid path_len values including the reserved hash_size=4 and path overflow conditions.",
"vectors": [
{
"id": "bpl-001",
"description": "Reserved hash size code 3 (hash_size would be 4): path_len=0xC0",
"type": "invalid",
"binary": "0D C0 01000000",
"expected_error": "reserved_hash_size",
"notes": "path_len=0xC0: bits 6-7=11 (hash size code 3). isValidPathLen returns false because hash_size==4."
},
{
"id": "bpl-002",
"description": "Reserved hash size code 3 with non-zero count: path_len=0xC1",
"type": "invalid",
"binary": "0D C1 AA 01000000",
"expected_error": "reserved_hash_size",
"notes": "path_len=0xC1: hash size code 3 (reserved), count=1. Invalid regardless of count."
},
{
"id": "bpl-003",
"description": "Reserved hash size code 3, max count: path_len=0xFF",
"type": "invalid",
"binary": "0D FF 0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F 01000000",
"expected_error": "reserved_hash_size",
"notes": "path_len=0xFF: hash size code 3 (reserved), count=63. Even if hash_size=4 were valid, 63*4=252 > MAX_PATH_SIZE."
},
{
"id": "bpl-004",
"description": "Path overflow: hash_size=2, count=33 (66 bytes > MAX_PATH_SIZE)",
"type": "invalid",
"binary": "0D 61 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233343536373839 3A3B3C3D3E3F4041 01000000",
"expected_error": "path_overflow",
"notes": "path_len=0x61: hash_size=2, count=33. 33*2=66 > MAX_PATH_SIZE (64). isValidPathLen returns false."
},
{
"id": "bpl-005",
"description": "Path overflow: hash_size=3, count=22 (66 bytes > MAX_PATH_SIZE)",
"type": "invalid",
"binary": "0D 96 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F4041 01000000",
"expected_error": "path_overflow",
"notes": "path_len=0x96: hash_size=3, count=22. 22*3=66 > MAX_PATH_SIZE (64)."
},
{
"id": "bpl-006",
"description": "Path overflow edge case: hash_size=1, count=63 is valid (63<=64), but with hash_size=2 and count=33 it overflows",
"type": "invalid",
"binary": "0D 61 0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F3031323334353637383940 4142 DEADBEEF",
"expected_error": "path_overflow",
"notes": "path_len=0x61: size code 1 (hash_size=2), count 33. 33*2=66 > 64."
}
]
}
@@ -0,0 +1,49 @@
{
"$schema": "../../schema/test-vector.schema.json",
"name": "Invalid - Too Short Packets",
"spec_ref": "versions/v0.1.0/01-wire-format.md",
"protocol_version": 0,
"description": "Tests packets that are shorter than the minimum required size for their route type.",
"vectors": [
{
"id": "short-001",
"description": "1-byte packet (FLOOD): only header, missing path_len and payload",
"type": "invalid",
"binary": "0D",
"expected_error": "too_short",
"notes": "Minimum FLOOD packet is 3 bytes. This is 1."
},
{
"id": "short-002",
"description": "2-byte packet (FLOOD): header + path_len, missing payload",
"type": "invalid",
"binary": "0D 00",
"expected_error": "empty_payload",
"notes": "Header + path_len present but no payload. i=2, len=2, so i>=len."
},
{
"id": "short-003",
"description": "5-byte TRANSPORT_FLOOD: header + transport codes, missing path_len",
"type": "invalid",
"binary": "0C 00000000",
"expected_error": "too_short",
"notes": "TRANSPORT_FLOOD needs at least 7 bytes (1+4+1+1). This has 5."
},
{
"id": "short-004",
"description": "6-byte TRANSPORT_FLOOD: header + transport + path_len, missing payload",
"type": "invalid",
"binary": "0C 00000000 00",
"expected_error": "empty_payload",
"notes": "All framing present but zero payload."
},
{
"id": "short-005",
"description": "FLOOD with path consuming all remaining bytes",
"type": "invalid",
"binary": "0D 03 AABBCC",
"expected_error": "empty_payload",
"notes": "header(1) + path_len(1) + path(3) = 5 bytes = total. i=5, len=5."
}
]
}
@@ -0,0 +1,65 @@
{
"$schema": "../../schema/test-vector.schema.json",
"name": "Invalid - Truncated Packets",
"spec_ref": "versions/v0.1.0/01-wire-format.md",
"protocol_version": 0,
"description": "Tests packets that are truncated at various points, verifying that decoders reject them gracefully.",
"vectors": [
{
"id": "trunc-001",
"description": "Empty packet (0 bytes)",
"type": "invalid",
"binary": "",
"expected_error": "too_short",
"notes": "Zero-length input. Cannot read header."
},
{
"id": "trunc-002",
"description": "Header only (1 byte, FLOOD route)",
"type": "invalid",
"binary": "0D",
"expected_error": "too_short",
"notes": "Only header byte. Cannot read path_len."
},
{
"id": "trunc-003",
"description": "Header only (1 byte, TRANSPORT_FLOOD route) - transport codes truncated",
"type": "invalid",
"binary": "0C",
"expected_error": "too_short",
"notes": "Route type 0x00 requires 4 transport code bytes, but only header is present."
},
{
"id": "trunc-004",
"description": "TRANSPORT_FLOOD with partial transport codes (2 of 4 bytes)",
"type": "invalid",
"binary": "0C 1234",
"expected_error": "too_short",
"notes": "Only 2 of 4 transport code bytes present."
},
{
"id": "trunc-005",
"description": "TRANSPORT_FLOOD with transport codes but no path_len",
"type": "invalid",
"binary": "0C 0000 0000",
"expected_error": "too_short",
"notes": "5 bytes: header + 4 transport code bytes. Missing path_len."
},
{
"id": "trunc-006",
"description": "FLOOD with path_len indicating 3 hops but only 1 path byte",
"type": "invalid",
"binary": "0D 03 AA FF",
"expected_error": "truncated_path",
"notes": "path_len=0x03 means 3 bytes of path expected but only 1 byte follows before the alleged payload. The decoder would read 3 path bytes (AA FF ??) and run out."
},
{
"id": "trunc-007",
"description": "FLOOD with 2-byte hash path_len=0x42 (4 path bytes needed) but only 2 available",
"type": "invalid",
"binary": "0D 42 AABB FF",
"expected_error": "truncated_path",
"notes": "path_len=0x42: hash_size=2, count=2, need 4 path bytes. Only 2 bytes before payload marker."
}
]
}
@@ -0,0 +1,156 @@
{
"$schema": "../../schema/test-vector.schema.json",
"name": "Path - Boundary Conditions",
"spec_ref": "versions/v0.1.0/03-path.md",
"protocol_version": 0,
"description": "Tests boundary conditions for path encoding including maximum valid values and values just below overflow thresholds.",
"vectors": [
{
"id": "pb-001",
"description": "hash_size=2, count=31 (62 bytes, 2 below max)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 2,
"hash_count": 31,
"hashes": [
"0001",
"0203",
"0405",
"0607",
"0809",
"0A0B",
"0C0D",
"0E0F",
"1011",
"1213",
"1415",
"1617",
"1819",
"1A1B",
"1C1D",
"1E1F",
"2021",
"2223",
"2425",
"2627",
"2829",
"2A2B",
"2C2D",
"2E2F",
"3031",
"3233",
"3435",
"3637",
"3839",
"3A3B",
"3C3D"
]
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 5F 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D 01000000",
"notes": "path_len=0x5F: hash_size=2, count=31. Path: 62 bytes. Just below max."
},
{
"id": "pb-002",
"description": "hash_size=3, count=20 (60 bytes, 3 below max for this hash_size)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 3,
"hash_count": 20,
"hashes": [
"000102",
"030405",
"060708",
"090A0B",
"0C0D0E",
"0F1011",
"121314",
"151617",
"18191A",
"1B1C1D",
"1E1F20",
"212223",
"242526",
"272829",
"2A2B2C",
"2D2E2F",
"303132",
"333435",
"363738",
"393A3B"
]
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 94 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233343536373839 3A3B 01000000",
"notes": "path_len=0x94: hash_size=3, count=20. Path: 60 bytes."
},
{
"id": "pb-003",
"description": "Single-byte path: hash_size=1, count=1",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 1,
"hashes": [
"00"
]
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 01 00 01000000",
"notes": "Minimal non-empty path. Hash value 0x00 is valid."
},
{
"id": "pb-004",
"description": "Path with all-FF hashes",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 3,
"hashes": [
"FF",
"FF",
"FF"
]
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 03 FFFFFF 01000000",
"notes": "All hashes are 0xFF. Valid encoding."
}
]
}
@@ -0,0 +1,260 @@
{
"$schema": "../../schema/test-vector.schema.json",
"name": "Path - Hash Counts",
"spec_ref": "versions/v0.1.0/03-path.md",
"protocol_version": 0,
"description": "Tests various hash count values including zero, small, and maximum values for each hash size.",
"vectors": [
{
"id": "hc-000",
"description": "Zero hops (hash_count=0, hash_size=1) - empty path",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 00 01000000",
"notes": "path_len=0x00. Zero-length path."
},
{
"id": "hc-001",
"description": "Zero hops with hash_size=2 - still empty path",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 2,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 40 01000000",
"notes": "path_len=0x40: hash_size=2, count=0. Path is still 0 bytes even though hash_size>1."
},
{
"id": "hc-002",
"description": "Zero hops with hash_size=3",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 3,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 80 01000000",
"notes": "path_len=0x80: hash_size=3, count=0. Path is 0 bytes."
},
{
"id": "hc-010",
"description": "Maximum count for hash_size=1: 63 hops, 63 bytes",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 63,
"hashes": [
"01",
"02",
"03",
"04",
"05",
"06",
"07",
"08",
"09",
"0A",
"0B",
"0C",
"0D",
"0E",
"0F",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
"17",
"18",
"19",
"1A",
"1B",
"1C",
"1D",
"1E",
"1F",
"20",
"21",
"22",
"23",
"24",
"25",
"26",
"27",
"28",
"29",
"2A",
"2B",
"2C",
"2D",
"2E",
"2F",
"30",
"31",
"32",
"33",
"34",
"35",
"36",
"37",
"38",
"39",
"3A",
"3B",
"3C",
"3D",
"3E",
"3F"
]
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 3F 0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F 01000000",
"notes": "path_len=0x3F: hash_size=1, count=63. Path: 63 bytes. Maximum valid path for 1-byte hashes."
},
{
"id": "hc-020",
"description": "Maximum count for hash_size=2: 32 hops, 64 bytes (exactly MAX_PATH_SIZE)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 2,
"hash_count": 32,
"hashes": [
"0001",
"0203",
"0405",
"0607",
"0809",
"0A0B",
"0C0D",
"0E0F",
"1011",
"1213",
"1415",
"1617",
"1819",
"1A1B",
"1C1D",
"1E1F",
"2021",
"2223",
"2425",
"2627",
"2829",
"2A2B",
"2C2D",
"2E2F",
"3031",
"3233",
"3435",
"3637",
"3839",
"3A3B",
"3C3D",
"3E3F"
]
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 60 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F 01000000",
"notes": "path_len=0x60: bits 6-7=01 (hash_size=2), bits 0-5=32. Path: 64 bytes = MAX_PATH_SIZE. Maximum valid for 2-byte hashes."
},
{
"id": "hc-030",
"description": "Maximum count for hash_size=3: 21 hops, 63 bytes",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 3,
"hash_count": 21,
"hashes": [
"000102",
"030405",
"060708",
"090A0B",
"0C0D0E",
"0F1011",
"121314",
"151617",
"18191A",
"1B1C1D",
"1E1F20",
"212223",
"242526",
"272829",
"2A2B2C",
"2D2E2F",
"303132",
"333435",
"363738",
"393A3B",
"3C3D3E"
]
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 95 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E 01000000",
"notes": "path_len=0x95: bits 6-7=10 (hash_size=3), bits 0-5=21. Path: 63 bytes. Maximum valid for 3-byte hashes (22*3=66 would overflow)."
}
]
}
@@ -0,0 +1,188 @@
{
"$schema": "../../schema/test-vector.schema.json",
"name": "Path - Hash Sizes",
"spec_ref": "versions/v0.1.0/03-path.md",
"protocol_version": 0,
"description": "Tests all valid hash sizes (1, 2, 3 bytes) in the path length encoding. These vectors are critical for catching implementations that treat path_len as a raw byte count.",
"vectors": [
{
"id": "hs-001",
"description": "Hash size 1 (code 0), 1 hop",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 1,
"hashes": [
"AA"
]
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 01 AA 01000000",
"notes": "path_len=0x01: bits 6-7=00 (size code 0, hash_size=1), bits 0-5=1 (count=1). Path: 1 byte."
},
{
"id": "hs-002",
"description": "Hash size 1 (code 0), 5 hops",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 5,
"hashes": [
"AA",
"BB",
"CC",
"DD",
"EE"
]
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 05 AABBCCDDEE 01000000",
"notes": "path_len=0x05: hash_size=1, count=5. Path: 5 bytes."
},
{
"id": "hs-010",
"description": "Hash size 2 (code 1), 1 hop",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 2,
"hash_count": 1,
"hashes": [
"AABB"
]
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 41 AABB 01000000",
"notes": "path_len=0x41: bits 6-7=01 (size code 1, hash_size=2), bits 0-5=1 (count=1). Path: 2 bytes. An implementation treating 0x41=65 as raw byte count would fail."
},
{
"id": "hs-011",
"description": "Hash size 2 (code 1), 2 hops",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 2,
"hash_count": 2,
"hashes": [
"AABB",
"CCDD"
]
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 42 AABBCCDD 01000000",
"notes": "path_len=0x42: hash_size=2, count=2. Path: 4 bytes. This is the example that catches the meshcore-rs bug (0x42=66 raw vs 4 actual bytes)."
},
{
"id": "hs-012",
"description": "Hash size 2 (code 1), 5 hops",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 2,
"hash_count": 5,
"hashes": [
"1122",
"3344",
"5566",
"7788",
"99AA"
]
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 45 112233445566778899AA 01000000",
"notes": "path_len=0x45: hash_size=2, count=5. Path: 10 bytes."
},
{
"id": "hs-020",
"description": "Hash size 3 (code 2), 1 hop",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 3,
"hash_count": 1,
"hashes": [
"AABBCC"
]
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 81 AABBCC 01000000",
"notes": "path_len=0x81: bits 6-7=10 (size code 2, hash_size=3), bits 0-5=1. Path: 3 bytes."
},
{
"id": "hs-021",
"description": "Hash size 3 (code 2), 3 hops",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 3,
"hash_count": 3,
"hashes": [
"AABBCC",
"DDEEFF",
"112233"
]
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 83 AABBCC DDEEFF 112233 01000000",
"notes": "path_len=0x83: hash_size=3, count=3. Path: 9 bytes."
}
]
}
@@ -0,0 +1,183 @@
{
"$schema": "../../schema/test-vector.schema.json",
"name": "Transport Codes - Basic",
"spec_ref": "versions/v0.1.0/01-wire-format.md",
"protocol_version": 0,
"description": "Tests transport code encoding with various values and route types that include/exclude transport codes.",
"vectors": [
{
"id": "tc-001",
"description": "Transport codes with TRANSPORT_FLOOD, both zero",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "transport_flood"
},
"transport_codes": [
0,
0
],
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0C 0000 0000 00 01000000",
"notes": "Both transport codes zero."
},
{
"id": "tc-002",
"description": "Transport codes with TRANSPORT_DIRECT, typical values",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "transport_direct"
},
"transport_codes": [
1000,
2000
],
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0F E803 D007 00 01000000",
"notes": "TC1: 1000=0x03E8 LE=E803. TC2: 2000=0x07D0 LE=D007."
},
{
"id": "tc-003",
"description": "Transport codes at maximum uint16 values",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "transport_flood"
},
"transport_codes": [
65535,
65535
],
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0C FFFF FFFF 00 01000000",
"notes": "Both transport codes at maximum: 0xFFFF."
},
{
"id": "tc-004",
"description": "Transport codes: code1=1, code2=0",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "transport_flood"
},
"transport_codes": [
1,
0
],
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0C 0100 0000 00 01000000",
"notes": "TC1=1 LE=0100, TC2=0."
},
{
"id": "tc-005",
"description": "Transport codes: code1=0x8000, code2=0x0001 (verify high bit handling)",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "transport_direct"
},
"transport_codes": [
32768,
1
],
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0F 0080 0100 00 01000000",
"notes": "TC1: 0x8000 LE=0080. TC2: 1 LE=0100."
},
{
"id": "tc-006",
"description": "FLOOD route (no transport codes) - verify they are absent from wire",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "flood"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0D 00 01000000",
"notes": "FLOOD route: no transport codes on wire. Total: 1 (header) + 1 (path_len) + 4 (ACK) = 6 bytes."
},
{
"id": "tc-007",
"description": "DIRECT route (no transport codes) - verify they are absent from wire",
"type": "encode_decode",
"structured": {
"header": {
"version": 0,
"payload_type": "ack",
"route_type": "direct"
},
"path": {
"hash_size": 1,
"hash_count": 0,
"hashes": []
},
"payload": {
"ack_crc": "00000001"
}
},
"binary": "0E 00 01000000",
"notes": "DIRECT route: no transport codes on wire."
}
]
}