Skip to content

QLV2#61

Open
nicoburniske wants to merge 60 commits into
mainfrom
ql-v2
Open

QLV2#61
nicoburniske wants to merge 60 commits into
mainfrom
ql-v2

Conversation

@nicoburniske

@nicoburniske nicoburniske commented Feb 5, 2026

Copy link
Copy Markdown
Contributor

roughtly 40% tests

workspace crates:

  • ql-wire: wire-format definitions
  • ql-fsm: synchronous protocol state machine
  • ql-runtime: async runtime wrapper around ql-fsm
  • ql-rpc: RPC modality layer over streams

@nicoburniske
nicoburniske force-pushed the ql-v2 branch 2 times, most recently from aa7e806 to 1b84f43 Compare March 3, 2026 19:20
@nicoburniske
nicoburniske force-pushed the ql-v2 branch 5 times, most recently from a0af892 to 6db8123 Compare March 24, 2026 22:23
@nicoburniske
nicoburniske force-pushed the ql-v2 branch 3 times, most recently from b968b19 to 08625df Compare March 26, 2026 18:35
@nicoburniske
nicoburniske force-pushed the ql-v2 branch 12 times, most recently from 72f06ba to 1c955e5 Compare April 9, 2026 21:14
@nicoburniske
nicoburniske force-pushed the ql-v2 branch 2 times, most recently from 517194a to d1b767f Compare April 17, 2026 03:08
@nicoburniske
nicoburniske force-pushed the ql-v2 branch 2 times, most recently from c190916 to 44d63cc Compare April 20, 2026 13:42
Comment thread ql-codec/src/codec.rs
}
}

macro_rules! impl_codec {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this is kind of a weird way to do it, instead of having 3 macros.

Comment thread ql-codec/src/slice.rs Outdated
Comment thread ql-codec/src/varint.rs
Comment thread ql-wire/src/encrypted/stream_reset.rs Outdated
Comment thread QL_V2.md
@@ -0,0 +1,376 @@
# QuantumLink V2

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two md files should be updated to be consistent with the implementation, or dropped.

Comment thread ql-wire/src/handshake/xx.rs Outdated

impl Encode for Xx1 {
fn encoded_len(&self) -> usize {
HandshakeId::WIRE_SIZE

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not fond of these special cases, it would be better to self.handshake_id.encoded_len() + ..., and it would compile down to the same thing.

badicsalex and others added 11 commits July 22, 2026 20:33
Splitting through `&mut self` means the reader never has to move `B` out
of itself, so `ManuallyDrop` and the `Drop` impl go with it. Losing the
`Drop` impl ends the reader's borrow of `bytes` in `fsm::receive` at its
last use, making the `drop(reader)` there dead code.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The plain integer codecs are fixed width, so `decode::<u64>()` and
`decode_varint::<u64>()` are one word apart and produce different wire
formats, with nothing in a bare `u64` field to say which one applies.

The `VarInt` trait is renamed `Primitive` so it doesn't read as a typo
for the `Varint` struct.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Groundwork for generating these with a macro: `encoded_len` sums the
fields instead of restating a constant, discriminant enums all fail with
ql_codec::Error, and both byte-container encode bounds are now BufView.

Nothing checked `encoded_len` against `encode` before, since
encode_record_vec only uses it to size the buffer. The new test covers
every type and passes against the pre-change impls, so this is
byte-identical.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Most Encode/Decode impls just walked the fields in order. What stays
hand-written reads or writes something that isn't a field: a flags byte
(StreamData), a trailing optional (Ik1), a block count (RecordAck), or
the rest of the buffer (EncryptedMessage, EncryptedPeerBundle).

PairingInvite loses its codec entirely, since nothing ever called it, and
array_wrapper is gone because codec_newtype covers it without #[macro_use].

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
MIN_WIRE_SIZE was a sum of maximums subtracted from the remaining record
capacity, so the name had it backwards, and bounding the length prefixes as
usize made it 41 on the host but 31 on the 32-bit target, giving the
simulator and the device different framing.

Three other WIRE_SIZE constants lost their last caller when `encoded_len`
started summing fields; the survivors are the ones no value is in hand for.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A usize varint is capped at ten bytes on a 64-bit host and five on the
32-bit target, so a length a host emits can be rejected outright by the
device's decoder. Only per-record lengths and counts move; offsets,
sequence numbers and ack spans stay u64, since those accumulate.

Encoded bytes are unchanged for anything under 4 GiB, as a varint does not
depend on the width it was declared with.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The payload budget reserved room for the header's length prefix but not
the header itself, so a stream opened with a header larger than the
remaining record space built a frame that would not fit, and pushing it
tripped the "builder has capacity" assert.

Reserving stops once offset 0 is acked rather than once the header is
sent, because until then a loss there is retransmitted and carries the
header again.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants