Browse Source
Based on: https://github.com/lightningnetwork/lightning-rfc/pull/640 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>pull/2938/head
Rusty Russell
6 years ago
1 changed files with 282 additions and 0 deletions
@ -0,0 +1,282 @@ |
|||||
|
#include <ccan/array_size/array_size.h> |
||||
|
#include <ccan/str/hex/hex.h> |
||||
|
#include <ccan/tal/grab_file/grab_file.h> |
||||
|
#include <ccan/tal/str/str.h> |
||||
|
#include <common/json.c> |
||||
|
#include <common/utils.h> |
||||
|
|
||||
|
static const char *reason; |
||||
|
#define SUPERVERBOSE(r) do { if (!reason) reason = (r); } while(0) |
||||
|
|
||||
|
#include <wire/fromwire.c> |
||||
|
#include <wire/towire.c> |
||||
|
|
||||
|
/* AUTOGENERATED MOCKS START */ |
||||
|
/* AUTOGENERATED MOCKS END */ |
||||
|
|
||||
|
/* BOLT-EXPERIMENTAL #1:
|
||||
|
* |
||||
|
* A correct implementation should pass against these test vectors: |
||||
|
* ```json |
||||
|
* [ |
||||
|
* { |
||||
|
* "name": "zero", |
||||
|
* "value": 0, |
||||
|
* "bytes": "00" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "one byte high", |
||||
|
* "value": 252, |
||||
|
* "bytes": "fc" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "two byte low", |
||||
|
* "value": 253, |
||||
|
* "bytes": "fd00fd" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "two byte high", |
||||
|
* "value": 65535, |
||||
|
* "bytes": "fdffff" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "four byte low", |
||||
|
* "value": 65536, |
||||
|
* "bytes": "fe00010000" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "four byte high", |
||||
|
* "value": 4294967295, |
||||
|
* "bytes": "feffffffff" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "eight byte low", |
||||
|
* "value": 4294967296, |
||||
|
* "bytes": "ff0000000100000000" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "eight byte high", |
||||
|
* "value": 18446744073709551615, |
||||
|
* "bytes": "ffffffffffffffffff" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "two byte not canonical", |
||||
|
* "value": 0, |
||||
|
* "bytes": "fd00fc", |
||||
|
* "exp_error": "decoded varint is not canonical" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "four byte not canonical", |
||||
|
* "value": 0, |
||||
|
* "bytes": "fe0000ffff", |
||||
|
* "exp_error": "decoded varint is not canonical" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "eight byte not canonical", |
||||
|
* "value": 0, |
||||
|
* "bytes": "ff00000000ffffffff", |
||||
|
* "exp_error": "decoded varint is not canonical" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "two byte short read", |
||||
|
* "value": 0, |
||||
|
* "bytes": "fd00", |
||||
|
* "exp_error": "unexpected EOF" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "four byte short read", |
||||
|
* "value": 0, |
||||
|
* "bytes": "feffff", |
||||
|
* "exp_error": "unexpected EOF" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "eight byte short read", |
||||
|
* "value": 0, |
||||
|
* "bytes": "ffffffffff", |
||||
|
* "exp_error": "unexpected EOF" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "one byte no read", |
||||
|
* "value": 0, |
||||
|
* "bytes": "", |
||||
|
* "exp_error": "EOF" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "two byte no read", |
||||
|
* "value": 0, |
||||
|
* "bytes": "fd", |
||||
|
* "exp_error": "unexpected EOF" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "four byte no read", |
||||
|
* "value": 0, |
||||
|
* "bytes": "fe", |
||||
|
* "exp_error": "unexpected EOF" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "eight byte no read", |
||||
|
* "value": 0, |
||||
|
* "bytes": "ff", |
||||
|
* "exp_error": "unexpected EOF" |
||||
|
* } |
||||
|
* ] |
||||
|
* ``` |
||||
|
*/ |
||||
|
static void test_decode(const char *json, const jsmntok_t toks[]) |
||||
|
{ |
||||
|
size_t i; |
||||
|
const jsmntok_t *t; |
||||
|
|
||||
|
json_for_each_arr(i, t, toks) { |
||||
|
const jsmntok_t *err = json_get_member(json, t, "exp_error"); |
||||
|
const jsmntok_t *bytes = json_get_member(json, t, "bytes"); |
||||
|
u64 num, expect; |
||||
|
const u8 *b; |
||||
|
size_t max; |
||||
|
|
||||
|
if (!json_to_u64(json, json_get_member(json, t, "value"), |
||||
|
&expect)) |
||||
|
abort(); |
||||
|
b = tal_hexdata(tmpctx, json + bytes->start, |
||||
|
bytes->end - bytes->start); |
||||
|
|
||||
|
max = tal_bytelen(b); |
||||
|
reason = NULL; |
||||
|
num = fromwire_bigsize(&b, &max); |
||||
|
if (err) { |
||||
|
assert(b == NULL); |
||||
|
assert(max == 0); |
||||
|
/* Map our errors to the test strings. */ |
||||
|
if (json_tok_streq(json, err, |
||||
|
"decoded varint is not canonical")) |
||||
|
assert(streq(reason, "not minimal encoded")); |
||||
|
else if (json_tok_streq(json, err, "unexpected EOF") |
||||
|
|| json_tok_streq(json, err, "EOF")) |
||||
|
assert(streq(reason, "less than encoding length")); |
||||
|
else |
||||
|
abort(); |
||||
|
} else { |
||||
|
assert(b != NULL); |
||||
|
assert(num == expect); |
||||
|
assert(max == 0); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* BOLT-EXPERIMENTAL #1:
|
||||
|
* |
||||
|
* A correct implementation should pass against the following test vectors: |
||||
|
* ```json |
||||
|
* [ |
||||
|
* { |
||||
|
* "name": "zero", |
||||
|
* "value": 0, |
||||
|
* "bytes": "00" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "one byte high", |
||||
|
* "value": 252, |
||||
|
* "bytes": "fc" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "two byte low", |
||||
|
* "value": 253, |
||||
|
* "bytes": "fd00fd" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "two byte high", |
||||
|
* "value": 65535, |
||||
|
* "bytes": "fdffff" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "four byte low", |
||||
|
* "value": 65536, |
||||
|
* "bytes": "fe00010000" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "four byte high", |
||||
|
* "value": 4294967295, |
||||
|
* "bytes": "feffffffff" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "eight byte low", |
||||
|
* "value": 4294967296, |
||||
|
* "bytes": "ff0000000100000000" |
||||
|
* }, |
||||
|
* { |
||||
|
* "name": "eight byte high", |
||||
|
* "value": 18446744073709551615, |
||||
|
* "bytes": "ffffffffffffffffff" |
||||
|
* } |
||||
|
* ] |
||||
|
* ``` |
||||
|
*/ |
||||
|
static void test_encode(const char *json, const jsmntok_t toks[]) |
||||
|
{ |
||||
|
size_t i; |
||||
|
const jsmntok_t *t; |
||||
|
|
||||
|
json_for_each_arr(i, t, toks) { |
||||
|
const jsmntok_t *bytes = json_get_member(json, t, "bytes"); |
||||
|
u64 num; |
||||
|
const u8 *expect; |
||||
|
u8 *b; |
||||
|
|
||||
|
if (!json_to_u64(json, json_get_member(json, t, "value"), |
||||
|
&num)) |
||||
|
abort(); |
||||
|
expect = tal_hexdata(tmpctx, json + bytes->start, |
||||
|
bytes->end - bytes->start); |
||||
|
|
||||
|
b = tal_arr(tmpctx, u8, 0); |
||||
|
towire_bigsize(&b, num); |
||||
|
assert(memeq(b, tal_bytelen(b), expect, tal_bytelen(expect))); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
int main(int argc, char *argv[]) |
||||
|
{ |
||||
|
char **lines, *json = NULL; |
||||
|
int test_count = 0; |
||||
|
|
||||
|
setup_locale(); |
||||
|
setup_tmpctx(); |
||||
|
|
||||
|
lines = tal_strsplit(tmpctx, grab_file(tmpctx, tal_fmt(tmpctx, "%s.c", |
||||
|
argv[0])), |
||||
|
"\n", STR_NO_EMPTY); |
||||
|
|
||||
|
for (size_t i = 0; lines[i]; i++) { |
||||
|
const char *l = lines[i]; |
||||
|
if (!strstarts(l, " * ")) |
||||
|
continue; |
||||
|
l += 3; |
||||
|
if (streq(l, "```json")) |
||||
|
json = tal_strdup(tmpctx, ""); |
||||
|
else if (streq(l, "```")) { |
||||
|
jsmn_parser parser; |
||||
|
jsmntok_t toks[500]; |
||||
|
|
||||
|
jsmn_init(&parser); |
||||
|
if (jsmn_parse(&parser, json, strlen(json), |
||||
|
toks, ARRAY_SIZE(toks)) < 0) |
||||
|
abort(); |
||||
|
|
||||
|
switch (test_count) { |
||||
|
case 0: |
||||
|
test_decode(json, toks); |
||||
|
break; |
||||
|
case 1: |
||||
|
test_encode(json, toks); |
||||
|
break; |
||||
|
default: |
||||
|
abort(); |
||||
|
} |
||||
|
test_count++; |
||||
|
json = NULL; |
||||
|
} else if (json) |
||||
|
tal_append_fmt(&json, "%s", l); |
||||
|
} |
||||
|
assert(test_count == 2); |
||||
|
tal_free(tmpctx); |
||||
|
} |
Loading…
Reference in new issue