Hello everyone!
As you might know from the other topics I have recently been posting, I am building a library to interact with the Ethereum Blockchain. Requests/responses to code that lives in Ethereum are done using a special encoded format, known as the ‘Ethereum ABI Encoding’.
It is quite some work to make sure that this encoding/decoding happens properly (But Elm’s strong typing definitely helps to ensure that the implementation is reasonably likely to be correct and at least not break at runtime )
In any case, this means I am creating my own Encode
rs and Decode
rs, which in functionality are very similar to the built-in JSON ones.
Now I want to create some fuzz tests that test the encoding/decoding process. To be exact:
- Create an arbitrary data structure made out of Eth ABI types.
- Use the matching encoder for that datastructure to encode it to a
Hexstring
. - Use the matching decoder for that datastructure to (if all goes well) decode it back to the data structure.
To be more exact:
- Creating arbitrary datastructures is done using functions of type
a -> Result String b
, since there is not for every type a 1:1 mapping between Elm’s built-in types and Ethereum’s types. - The encoder function needs to be picked based on what datastructure we chose in the previous step. These are functions of type
b -> Encoder
(and there is anencode
function that turns anEncoder
into aHexstring
) - The decoder function needs to be picked based on what datastructure we chose in the first step. These are of the opaque type
Decoder t
(they have to keep track of some internal offsets etc. when chaining multiple decoders), but they can be used together withdecodeString
which has the typeDecoder b -> Hexstring -> Result String b
to regain theb
we put in.
So, seems fine: We can just write the Fuzzer function to create a triple with the type: Fuzzer (Result String b, b -> Hexstring, Hexstring -> b)
, and for this (x, y, z) call Expect.equals (x |> Result.andThen (y >> z))
?
But this is where I am stuck:
- How can such a triple be used as input for
Fuzz.oneOf
? Each of the triples would have a differentb
in there, so how can I combine them in one list? - How can I combine these fuzzers such that I can create a recursive data structure fuzzer? (It is possible to create/represent arrays (of arrays of arrays …) with different dimensions and types in the Ethereum ABI, and I’d like to be able to fuzz-test not only
bool
,int256
anduint256
, but alsoint256[8]
,uint[8][2]
andbool[3][][42][][]
.
Your help is greatly appreciated!