WAVS design considerations
The WAVS approach to AVS design focuses on the lightweight and agile nature of components, with an emphasis on performance and security.
WAVS works best with the "serverless function" approach, wherein the priority of service component logic is to process data from external sources rather than store it locally. In this model, a component can receive input data from external sources, process it, and submit the verifiable outputs to external sources.
Aggregation and deterministic queries
WAVS currently supports "exact match" aggregation, meaning that consensus is reached if 2/3 of submitted responses from operators are identical. This approach fits many common use cases, but it means that developers must build their components to receive and process data only from deterministic or immutable sources, such as:
- Data from the input event trigger
- Ethereum queries at a given block height
- IPFS data or other Content-Addressable Storage
- Web2 APIs that are trusted to return the same result on every query
For example, when designing a price oracle, a blockheight or timestamp should be specified in the query logic. This ensures that the query is deterministic and that the same data point is retrieved by all operators.
Conversely, a component that is designed to fetch "current price" would be non-deterministic and may result in a consensus error. Operators may run components at slightly different times, leading to discrepancies in the data they receive. This design should be avoided, as aggregation for this would require custom BFT averaging logic which is not currently supported. However, adding custom logic to process non-exact matches will be available in future releases.
State
Persistent state introduces additional challenges in AVS design with WAVS: operators may execute triggers at different times or, in some cases, not run them at all if they join an AVS after it has been running for some time. Components that rely on operator-local mutable state risk failing consensus due to inconsistencies in execution. For these reasons, it is best practice to avoid storing operator-local mutable state within your components.
This functionality would require features such as state synchronization, guaranteed execution ordering, and Merkle-proof validation which are not yet supported.
Caching
WAVS provides components with an optional local data directory that can be used for caching. This storage method should only be used to cache data as a performance optimization and not as a replacement for external state stores.
It is best practice when using a cache to reference external data from deterministic immutable sources to avoid consensus failures.
Keep the following points in mind when using cached data:
- Caching should be used as a performance optimization only.
- Use immutable or deterministic external data sources with specific time stamps or block heights.
- Design your component logic to work even if the cache is cleared. Cache state is not shared among operators, and any operator should be able to rebuild the cache from scratch.
- Don't use caching to store state that depends on previous executions or mutable data.