TLV testcases#631
Conversation
cfromknecht
left a comment
There was a problem hiding this comment.
Thanks for getting the ball rolling on the test vectors @rustyrussell! I'm about half way through, but the main thing i'm noticing so far is a discrepancy in the way that the varints are being encoded. CompactSize encodes any multi-byte values using little endian, while the tests are using big-endian.
| 1. Invalid stream: 0xfd01 | ||
| 2. Reason: type truncated | ||
|
|
||
| 1. Invalid stream: 0xfd0001 01 |
There was a problem hiding this comment.
| 1. Invalid stream: 0xfd0001 01 | |
| 1. Invalid stream: 0xfd0100 |
the current value is minimally encoded, remove trailing 0x01
There was a problem hiding this comment.
Thanks for getting the ball rolling on the test vectors @rustyrussell! I'm about half way through, but the main thing i'm noticing so far is a discrepancy in the way that the varints are being encoded.
CompactSizeencodes any multi-byte values using little endian, while the tests are using big-endian.
You're right :( Bitcoin strikes again...
I assume we should follow (and document!) Bitcoin CompactSize endian here, since that was the rationale for not inventing our own?
There was a problem hiding this comment.
It should be implicit from the test vectors, but if we want to be more specific fine by me :)
fwiw I have a series of varint test vectors, should I make a separate pr with those?
There was a problem hiding this comment.
Good catch @cfromknecht !
That shows I went too quickly when comparing my test suite and this PR, I'll spend more time on it today.
There was a problem hiding this comment.
Unfortunately, my tests passed after I fixed the endian without fixing the data. I'll add some test vectors which only work in the correct endian.
There was a problem hiding this comment.
And we need the trailing 01, otherwise it is invalid for a different reason: no length field. Though that should be 00 not 01.
There was a problem hiding this comment.
shouldn't the check for whether the type is minimally encoded be applied before attempting to parse the length?
| 1. Invalid stream: 0x1f 00 0f 01 2a | ||
| 2. Reason: valid (ignored) tlv records but invalid ordering | ||
|
|
||
| 1. Invalid stream: 0x02 08 0000000000000231 02 08 0000000000000451 |
There was a problem hiding this comment.
I think this is a duplicate of line 613.
Maybe replace by 0x0f 01 2a 0f 01 2b to disallow duplicate of unknown odd types?
There was a problem hiding this comment.
Next line tests duplicate ignored. I'll just remove this one, good spotting!
|
would also be useful to add this to the decoding failures: |
I'm confused, why is that an overflow? That's just the max possible type, no? Which is odd, so that is valid (assuming unknown)? |
|
Please test the New Hotness, which contains all the fixes and some new vectors. |
The type is max uint64 and has length 0, which is optional and so we ignore it. The following type is 0, which wraps around and breaks monotonicity, and so is not canonical |
|
@rustyrussell here's how we detect this case https://github.com/lightningnetwork/lnd/pull/3061/files#diff-b776b065cfabb730273c018554f81204R218 |
I agree, but the error message shouldn't be |
|
@t-bast sure not married to the name |
t-bast
left a comment
There was a problem hiding this comment.
I integrated all of those in my test suite and everything is green!
ACK 99d3440 (and good luck with the annoying spell-checking failures)
|
Please, let's not mix endianness in the protocol. There's no reason to inherit this wart of Bitcoin which makes it that much harder to understand. |
|
I made a PR that adds test vectors for the varint scheme. Given the recent discussion i made them using a big-endian encoding, but either way it's probably good to have something like this: #640 |
|
OK, I'm about to add @cfromknecht 's max-then-min type test, and then rebase on top of #640... |
|
OK, so @cfromknecht 's ffff to 0 test fails for other reasons: 0 is even and unknown, and there's no length field. I prefer tests which test one thing at a time; I'll change |
99d3440 to
d70fe60
Compare
|
"This time for sure!" Please re-retest! |
The way i have it implemented, we check that the types are canonically ordered before parsing the length (or checking if the type is known). I think this is also relevant to my other comment where the canonical varint check for the type is being applied after parsing the length. In our implementation we check that each varint is canonical at the time it is parsed (I think this last bit might be resolved if the varint also passed the BigSize test vectors?) |
|
I'll proceed in updating to the latest test vectors and report back :) |
Ah, OK. We run our checks in the following order instead (kinda arbitrary, really):
It's nice to have implementations do it in different orders, though... |
|
That makes sense then :) We do
The check that there's enough data for length is applied while decoding or discarding the value |
lightning/bolts#631 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
|
Tested-ACK |
cfromknecht
left a comment
There was a problem hiding this comment.
@rustyrussell @t-bast updated our implementation with the latest test vectors, I think we're about ready! Noticed a few small things, but as is our implementation is all green 🚀
| 1. Invalid stream: 0x1f 00 1f 01 2a | ||
| 2. Reason: duplicate TLV type (ignored) | ||
|
|
||
| The following TLV stream in namespace `n2` should trigger a decoding |
There was a problem hiding this comment.
i'm wondering, should this produce an error in either namespace? sending a non-canonical stream is more severe than sending an unknown required type, so failing with unknown required type on n1 would effectively downgrade the error. if we were to standardize something like:
- if stream is not canonical:
- close channel
- if stream has unknown required type:
- disconnect
our implementations will behave differently
There was a problem hiding this comment.
The purpose of the toy example was to just to highlight that we might need take different actions when encountering a parsing failure vs a negotiation failure.
With the current proposal feature negotiation is bundled alongside message deserialization, so we are forced to differentiate the errors at the tlv encoding level and be consistent across implementations.
|
It's probably a nit, but I'm not a big fan of the name |
It's supposed to be a somewhat of a pun :P
Was hoping for something a little less bland tbh
I'd prefer not to have this verbose description everywhere we want to reference it, I think we need some name just to make it easy to refer to in the spec. It was already painful enough to write it twice. Didn't want to waste too much time on a name when drafting the proposal, and so just went with |
lightning/bolts#631 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
lightning/bolts#631 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
|
I don't feel very strongly about the name and don't have a better choice than either |
For some reason (typo?) we only allowed "2", not other numbers! Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
We were swallowing the unused line after `data`, but it's
normal to do:
```
1. tlvs: `n1`
2. types:
1. type: 1 (`tlv1`)
2. data:
* [`tu64`:`amount_msat`]
1. type: 2 (`tlv2`)
2. data:
* [`short_channel_id`:`scid`]
```
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
We didn't explicitly say that the TLV is bad if length exceeds the message length! We didn't specify whether to ignore extra bytes: we should. Similarly, contents of values must be minimal (i.e. tu64 etc). Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
dd7893b to
c499db4
Compare
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
These are based on @t-bast's vectors from lightning#607, with a few more cases: 1. Explicitly test encodings for 253, 254 and 255. 2. Use BigSize and make sure tests break badly if endian parsing is wrong.' 3. Test wrap-around of type encodings in stream. Many thanks to @t-bast and @cfromknecht for their contributions and testing Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
c499db4 to
fa09bfe
Compare
|
Rebased and squashed commits ready for merge. |
Came across some new requirements and a few tool fixes along the way...