commit 9e005761f5b5678af99b274f3965e003cee0fff4
parent 9256d605e0a852bea498a33ac4bcec5db1c5e043
Author: nolash <dev@holbrook.no>
Date: Sat, 10 Apr 2021 15:09:30 +0200
Add test vectors from spec page
Diffstat:
7 files changed, 163 insertions(+), 8 deletions(-)
diff --git a/Makefile b/Makefile
@@ -6,9 +6,11 @@ build:
tests_build: build
gcc -I./src -g3 tests/check_rlp.c src/bits.o src/rlp.o src/endian.o -o tests/check_rlp -lcheck
gcc -I./src -g3 tests/check_bits.c src/bits.o src/rlp.o src/endian.o -o tests/check_bits -lcheck
+ gcc -I./src -g3 tests/check_vector.c src/bits.o src/rlp.o src/endian.o -o tests/check_vector -lcheck
check: tests_build
tests/check_rlp
tests/check_bits
+ tests/check_vector
.PHONY test: check
diff --git a/src/rlp.c b/src/rlp.c
@@ -64,17 +64,30 @@ int rlp_descend(rlp_encoder_t *encoder) {
}
int rlp_ascend(rlp_encoder_t *encoder) {
- size_t l;
+ size_t len;
char *ptr;
+ int lenlen;
ptr = encoder->list_ptr[encoder->depth];
- l = encoder->ptr - ptr;
- if (l < 56) {
- memcpy(ptr+1, ptr, l);
- *(ptr) = 0xc0 + l;
+ len = encoder->ptr - ptr;
+ if (len < 56) {
+ memcpy(ptr + 1, ptr, len);
+ *(ptr) = 0xc0 + len;
encoder->ptr++;
+ } else {
+ lenlen = intbytes_le(sizeof(size_t), (char*)&len);
+ memcpy(ptr + 1 + lenlen, ptr, len);
+ *ptr = lenlen + 0xf7;
+ to_endian(CONVERT_BIGENDIAN, lenlen, &len);
+ memcpy(ptr+1, &len, lenlen);
+ to_endian(CONVERT_PLATFORM, lenlen, &len);
+ encoder->ptr += (lenlen + 1);
}
encoder->depth--;
return encoder->depth + 1;
}
+
+size_t rlp_length(rlp_encoder_t *encoder) {
+ return encoder->ptr - encoder->buf;
+}
diff --git a/src/rlp.h b/src/rlp.h
@@ -2,6 +2,7 @@
#define RLP_T_
#include <stdint.h>
+#include <stdlib.h>
#ifndef RLP_MAX_LIST_DEPTH
#define RLP_MAX_LIST_DEPTH 1024
@@ -12,16 +13,14 @@ typedef struct rlp_encoder {
char *list_ptr[RLP_MAX_LIST_DEPTH];
char *buf;
char *ptr;
- size_t len;
} rlp_encoder_t;
int rlp_init(rlp_encoder_t *encoder, int buffer_capacity);
void rlp_free(rlp_encoder_t *encoder);
int rlp_descend(rlp_encoder_t *encoder);
-//static int list_register(rlp_encoder_t *encoder);
int rlp_ascend(rlp_encoder_t *encoder);
int rlp_add(rlp_encoder_t *encoder, int len, char *data);
-int rlp_finish(rlp_encoder_t *encoder);
+size_t rlp_length(rlp_encoder_t *encoder);
#endif
diff --git a/tests/check_bits b/tests/check_bits
Binary files differ.
diff --git a/tests/check_rlp b/tests/check_rlp
Binary files differ.
diff --git a/tests/check_rlp.c b/tests/check_rlp.c
@@ -219,6 +219,24 @@ START_TEST(rlp_encode_list_nested_test) {
rlp_free(&encoder);
}
END_TEST
+
+START_TEST(rlp_encode_list_long_test) {
+ char v[56];
+ char target[4] = {0xf8, 58, 0xb8, 56};
+ int r;
+
+ rlp_encoder_t encoder;
+ rlp_init(&encoder, 1024);
+
+ r = rlp_descend(&encoder);
+ rlp_add(&encoder, 56, (char*)v);
+ r = rlp_ascend(&encoder);
+ ck_assert_mem_eq(encoder.buf, target, 4);
+
+ rlp_free(&encoder);
+}
+END_TEST
+
Suite *rlp_suite(void) {
Suite *s;
TCase *tci;
@@ -246,6 +264,7 @@ Suite *rlp_suite(void) {
tcase_add_test(tcl, rlp_encode_list_single_depth_test);
tcase_add_test(tcl, rlp_encode_list_adjacent_test);
tcase_add_test(tcl, rlp_encode_list_nested_test);
+ tcase_add_test(tcl, rlp_encode_list_long_test);
suite_add_tcase(s, tcl);
return s;
diff --git a/tests/check_vector.c b/tests/check_vector.c
@@ -0,0 +1,122 @@
+#include <check.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rlp.h"
+
+START_TEST(rlp_dog_test) {
+ rlp_encoder_t encoder;
+
+ rlp_init(&encoder, 1024);
+ char *x_dog = "dog";
+ char r_dog[4] = {0x83, 'd', 'o', 'g'};
+ rlp_add(&encoder, 3, x_dog);
+ ck_assert_mem_eq(encoder.buf, r_dog, 4);
+
+ rlp_free(&encoder);
+}
+END_TEST
+
+START_TEST(rlp_catdog_test) {
+ rlp_encoder_t encoder;
+
+ rlp_init(&encoder, 1024);
+
+ char *x_dog = "dog";
+ char *x_cat = "cat";
+ char r_catdog[9] = {0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g'};
+ rlp_descend(&encoder);
+ rlp_add(&encoder, 3, x_cat);
+ rlp_add(&encoder, 3, x_dog);
+ rlp_ascend(&encoder);
+ ck_assert_mem_eq(encoder.buf, r_catdog, 9);
+
+ rlp_free(&encoder);
+}
+END_TEST
+
+START_TEST(rlp_lorem_test) {
+ rlp_encoder_t encoder;
+
+ rlp_init(&encoder, 1024);
+
+ char *lorem = "Lorem ipsum dolor sit amet, consectetur adipisicing elit";
+ char target[2] = {0xb8, 0x38};
+
+ rlp_add(&encoder, strlen(lorem), lorem);
+ ck_assert_mem_eq(encoder.buf, target, 2);
+ ck_assert_mem_eq(encoder.buf+2, lorem, strlen(lorem));
+
+ rlp_free(&encoder);
+}
+END_TEST
+
+START_TEST(rlp_set_theoretical_representation_of_three) {
+
+ char target[8] = {0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0};
+
+ rlp_encoder_t encoder;
+
+ rlp_init(&encoder, 1024);
+
+ // [ [] [ [] ] [ [] [ []] ] ]
+ rlp_descend(&encoder);
+
+ rlp_descend(&encoder);
+ rlp_ascend(&encoder);
+
+ rlp_descend(&encoder);
+ rlp_descend(&encoder);
+ rlp_ascend(&encoder);
+ rlp_ascend(&encoder);
+
+ rlp_descend(&encoder);
+ rlp_descend(&encoder);
+ rlp_ascend(&encoder);
+ rlp_descend(&encoder);
+ rlp_descend(&encoder);
+ rlp_ascend(&encoder);
+ rlp_ascend(&encoder);
+ rlp_ascend(&encoder);
+
+ rlp_ascend(&encoder);
+
+ ck_assert_mem_eq(encoder.buf, target, 8);
+
+ rlp_free(&encoder);
+}
+END_TEST
+
+
+Suite *rlp_vector_suite(void) {
+ Suite *s;
+ TCase *tcb;
+
+ s = suite_create("rlp_vector");
+ tcb = tcase_create("basic"); // examples from https://eth.wiki/fundamentals/rlp
+ tcase_add_test(tcb, rlp_dog_test);
+ tcase_add_test(tcb, rlp_catdog_test);
+ tcase_add_test(tcb, rlp_lorem_test);
+ tcase_add_test(tcb, rlp_set_theoretical_representation_of_three);
+ suite_add_tcase(s, tcb);
+
+
+ return s;
+}
+
+
+int main(void) {
+ int num_fail;
+
+ Suite *s;
+ SRunner *sr;
+
+ s = rlp_vector_suite();
+ sr = srunner_create(s);
+
+ srunner_run_all(sr, CK_VERBOSE);
+ num_fail = srunner_ntests_failed(sr);
+ srunner_free(sr);
+
+ return (num_fail == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}