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 Encoders and Decoders, 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 anencodefunction that turns anEncoderinto 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 withdecodeStringwhich has the typeDecoder b -> Hexstring -> Result String bto regain thebwe 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 differentbin 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,int256anduint256, but alsoint256[8],uint[8][2]andbool[3][][42][][].
Your help is greatly appreciated!