add readme to vrlp, assertion about encode->decode roundtrip
This commit is contained in:
@@ -0,0 +1,61 @@
|
|||||||
|
# Vanillae RLP library
|
||||||
|
|
||||||
|
This implements [Ethereum's RLP codec](https://zxq9.com/archives/2749)
|
||||||
|
|
||||||
|
The decoded data ("decoded" from the perspective of the program using the data)
|
||||||
|
is arbitrary-depth arbitrary-length lists-of-lists-of-...-binaries (lists and
|
||||||
|
binaries are allowed to be empty). The encoded data is of course a single flat
|
||||||
|
binary string.
|
||||||
|
|
||||||
|
It has been tested against Ethereum's official Python implementation.
|
||||||
|
|
||||||
|
You can see the methodology in <tests/vrlp_testgen.erl>:
|
||||||
|
|
||||||
|
- 10,000 decoded data structures are generated at random
|
||||||
|
- the test generator calls `vrlp:encode/1` to generate an encode/decode pair
|
||||||
|
- assert that encode -> decode round trips properly in the `vrlp` module
|
||||||
|
- print out an encode-decode pair as a python term to stdout
|
||||||
|
- python program tests the encode-decode pairs against Ethereum's library
|
||||||
|
|
||||||
|
The heart of the methodology is here:
|
||||||
|
|
||||||
|
```erl
|
||||||
|
% input: decoded_data
|
||||||
|
% format a case as
|
||||||
|
% {'decoded_data': <python term for rlist>,
|
||||||
|
% 'encoded_bytes': bytes([B1, B2, B3, ...])}
|
||||||
|
format_case_py(DecodedData_rlist) ->
|
||||||
|
% EncodedData_bytes = rlp:encode(
|
||||||
|
% DD_js = format_data_js(DecodedData_rlist),
|
||||||
|
EncodedData_bytes = vrlp:encode(DecodedData_rlist),
|
||||||
|
% assert encode -> decode round trips
|
||||||
|
{DecodedData_rlist, <<>>} = vrlp:decode(EncodedData_bytes),
|
||||||
|
EncodedBytes_py = format_bytes_py(EncodedData_bytes),
|
||||||
|
DecodedData_py = format_data_py(DecodedData_rlist),
|
||||||
|
[" {'decoded': ", DecodedData_py, ",\n",
|
||||||
|
" 'encoded': ", EncodedBytes_py, "}"].
|
||||||
|
```
|
||||||
|
|
||||||
|
The Python side:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def main():
|
||||||
|
all_encode_work = True
|
||||||
|
all_decode_work = True
|
||||||
|
for case in cases:
|
||||||
|
decoded_data = case['decoded']
|
||||||
|
encoded_bytes = case['encoded']
|
||||||
|
real_encoded_bytes = rlp.encode(decoded_data)
|
||||||
|
real_decoded_data = rlp.decode(encoded_bytes)
|
||||||
|
# check if encode/decode works
|
||||||
|
encode_works = (real_encoded_bytes == encoded_bytes)
|
||||||
|
decode_works = (real_decoded_data == decoded_data)
|
||||||
|
print('encode works: %s' % (encode_works))
|
||||||
|
print('decode works: %s' % (decode_works))
|
||||||
|
# update globals
|
||||||
|
all_encode_work = all_encode_work and encode_works
|
||||||
|
all_decode_work = all_decode_work and decode_works
|
||||||
|
# print globals
|
||||||
|
print('all encode work: %s' % (all_encode_work))
|
||||||
|
print('all decode work: %s' % (all_decode_work))
|
||||||
|
```
|
||||||
@@ -8,7 +8,8 @@ main([]) ->
|
|||||||
% Decoded cases
|
% Decoded cases
|
||||||
DecodedCases = rand_decode_datas(10_000),
|
DecodedCases = rand_decode_datas(10_000),
|
||||||
%io:format("~p~n", [DecodedCases]),
|
%io:format("~p~n", [DecodedCases]),
|
||||||
io:format("~s~n", [format_cases_py(DecodedCases)]),
|
%io:format("~s~n", [format_cases_py(DecodedCases)]),
|
||||||
|
_ = format_cases_py(DecodedCases),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
|
||||||
@@ -115,7 +116,9 @@ slcommas([Item | Rest], Acc) ->
|
|||||||
format_case_py(DecodedData_rlist) ->
|
format_case_py(DecodedData_rlist) ->
|
||||||
% EncodedData_bytes = rlp:encode(
|
% EncodedData_bytes = rlp:encode(
|
||||||
% DD_js = format_data_js(DecodedData_rlist),
|
% DD_js = format_data_js(DecodedData_rlist),
|
||||||
EncodedData_bytes = vrlp:encode(DecodedData_rlist),
|
EncodedData_bytes = vrlp:encode(DecodedData_rlist),
|
||||||
|
% assert encode -> decode round trips
|
||||||
|
{DecodedData_rlist, <<>>} = vrlp:decode(EncodedData_bytes),
|
||||||
EncodedBytes_py = format_bytes_py(EncodedData_bytes),
|
EncodedBytes_py = format_bytes_py(EncodedData_bytes),
|
||||||
DecodedData_py = format_data_py(DecodedData_rlist),
|
DecodedData_py = format_data_py(DecodedData_rlist),
|
||||||
[" {'decoded': ", DecodedData_py, ",\n",
|
[" {'decoded': ", DecodedData_py, ",\n",
|
||||||
|
|||||||
Reference in New Issue
Block a user