* migrate from anyhow to thiserror (#190). pending polish error msgs
* Add backtrace and compartmentalize errors
- Include backtraces in the errors we generate. To get this we can't
just return a literal enum, because the backtrace requires a call.
- Related to the previous point: add methods to create errors so
we can include the backtrace conveniently without changing too much
the syntax. So instead of `Err(Error::KeyNotFound(key))` (literal
enum) it will be `Err(Error::key_not_found(key))` (method call)
- Each error should be local to its scope, and each scope should
only return its own error.
- The merkle tree should return `TreeError` and not Error
- The middleware should return `MiddlewareError` and not Error
- With a global Error we can't easily include backend/frontend types in
the error fields, so declare a `BackendError` and a `FrontendError`
and follow the pattern from the previous point
- The Pod traits should be able to return backend errors and will be
used in the frontend; for that we change them to use trait object
Error: `dyn std::error::Error`
* fix error
* apply suggestions from @arnaucube
* rename XError and XResult to Error and Result
* reorg signature
* make frontend custom error more ergonomic
* remove unnecessary feature
---------
Co-authored-by: Eduard S. <eduardsanou@posteo.net>
* Serialization tests now pass again
* Tidy up and test more edge-cases
* Use attributes rather than custom serializer for arrays
* Add JSON Schema support
* Tests for JSON Schema generation and validation
* Add comments
* Support custom predicates
* Clippy fixes
* Make deserialization/constructor functions pub(crate)
* unify fe/be NativeOp and NativePred
* remove Origin in favour of PodId
* Combine string and hash in Key
* use middleware::AnchoredKey in frontend
* merge frontend/middleware types
* refactor custom predicates
* clean up a bit
* fix middleware custom tests
* clean up
* clean up 2
* add acronyms in typos list
* All test pass on middleware->frontend type refactor
* Convert frontend CustomPredicateRef to a named field struct
* Minor serialization improvements
* Set appropriate titles in JSON schemas
* Add names for custom predicates
* Remove PodClass from front-end Origin type
* Simplify value conversion
---------
Co-authored-by: Ahmad <root@ahmadafuni.com>
* limit the number of StatementTmpl in CustomPredicate:
- add constructor method for CustomPredicate
- make size checks at the CustomPredicate creation, so that once instantiated we can assume that contains valid data
This resolves#79
* Update tests to use new interface
---------
Co-authored-by: Ahmad <root@ahmadafuni.com>
At the middleware we were defining some types that actually are dependant on the
backend no matter how we define them in the middleware.
For example, we were hardcoding the `Hash` and `Value` types and their related
behaviour (eg. `.to_fields()`) to be based on the length of 4 field elements,
but that's not a choice of the middleware, and in fact this is determined by the
backend itself. On the same time, those types and related methods do not belong
to the backend, since conceptually they are part of the middleware reasoning.
The intention of this PR is not to prematurely abstract the library, but to
avoid inconsistencies where a type or parameter is defined in the middleware to
have certain carachteristic and later in the backend it gets used differently.
The idea is that those types and parameters (eg. lengths) have a single source
of truth in the code; and in the case of the "base types" (hash, value, etc)
this is determined by the backend being used under the hood, not by a choice of
the middleware parameters.
The idea with this approach, is that the frontend & middleware should not need
to import the proving library used by the backend (eg. plonky2, plonky3, etc).
As mentioned earlier, the `Hash` and `Value` types are types belonging at the
middleware, and is the middleware who reasons about them, but depending on the
backend being used, the `Hash` and `Value` types will have different sizes. So
it's the backend being used who actually defines their nature under the hood.
For example with a plonky2 backend, these types will have a length of 4 field
elements, whereas with a plonky3 backend they will have a length of 8 field
eleements.
Note that his approach does not introduce new traits or abstract code, just
makes use of rust features to define 'base types' that are being used in the
middleware.
* Print pods from SignedPodBuilder
* Add additional print to test printing SignedPodBuilder
* Mock-prove and print MainPod
* Implement ToFields for custom predicates and dependencies
* Test: print serialization of a recursive batch
* Rearrange serialization of CustomPredicate so args_len is always in the same position
* Serialize predicates with first entry nonzero to avoid collision with padding
* Off by one error in ethdos test BatchSelf(2)
* cargo fmt
* not a typo
* Typos, trying again
* add comments detailing logic, migrate middleware::custom::tests to frontend::custom
* simplify custom predicate's frontend interfaces, making it less verbose to define Statement Template arguments
The main idea is that when defining the arguments at a statement
template, it can be done from 3 different inputs:
i. `(&str, literal)`: this is to set a POD and a field, ie. `(POD, literal("field")`)
ii. `(&str, &str)`: this is to define a origin-key wildcard pair, ie. `(src_origin, src_dest)`
iii. `Value`: this is to define a literal value, ie. `0`