From 2d4d31dce9cd84ef46e3d1717c1dbc5b289362ab Mon Sep 17 00:00:00 2001 From: "Eduard S." Date: Tue, 18 Feb 2025 16:31:39 +0100 Subject: [PATCH] feat: add architecture doc (#73) * feat: add architecture doc * fix: typos --- book/src/SUMMARY.md | 5 +++- book/src/architecture.md | 42 ++++++++++++++++++++++++++++++ book/src/img/frontend-backend.png | Bin 0 -> 32564 bytes 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 book/src/architecture.md create mode 100644 book/src/img/frontend-backend.png diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 739c672..f6b9546 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -17,4 +17,7 @@ - [SignedPOD](./signedpod.md) - [MainPOD](./mainpod.md) - [MockPOD](./mockpod.md) -- [Examples](./examples.md) \ No newline at end of file +- [Examples](./examples.md) + +# Architecture +- [Architecture](./architecture.md) diff --git a/book/src/architecture.md b/book/src/architecture.md new file mode 100644 index 0000000..bb5e8f3 --- /dev/null +++ b/book/src/architecture.md @@ -0,0 +1,42 @@ +# Architecture + +This document explains the architecture of the current implementation. + +The main logic of the POD2 implementation is divided into three modules: +- frontend + - compiles user-friendly pod declarations into intermediate representations to be consumed by the backend + - internally connects to the backend to get pods built (signed / proved). + - presents pods to the user +- middleware + - defines the intermediate representation of Statements, Operations and interfaces of PODs + - Statements and Operations are strongly typed here + - Both frontend and backend use types defined in the middleware + - Does not import types from frontend nor backend +- backend + - takes a middleware POD request representation, signs/proves it and returns a generic POD object + +If this was the Rust language compiler: +- frontend: takes a Rust code and compiles it to LLVM-IR +- middleware: defines LLVM-IR instructions and blocks +- backend: Takes LLVM-IR instructions and emits assembly code for a particular CPU + +The following diagram shows visually how the components interact with each other: + +![](img/frontend-backend.png) + +In this organization, the middleware could be defined at arbitrary points: +- closer to the user would be more high level +- closer to the target would be more low level + +All these positions are OK. We just need to choose one, and we can try to choose a point that simplifies the implementation. + +For example in the middleware we could define `Value = 4 x Goldilock` (making it slightly low level); or `Value = BigUint` and letting the backend choose the maximum representable value, the field encoding, etc. (making it slightly higher level). + +In the current iteration we choose `Value = 4 x Goldilock`, but we can revisit it in a future iteration (eg. if we want to support plonky3) by either moving the middleware to a higher level, or by keeping it the same and replacing the `Value` definition. + +The diagram above includes an arrow that would show the typical flow followed by a user making a POD. This is a simplified description of the process. +1. The user interacts with the frontend API and passes a list of Operations. The frontend takes those operations and generates the corresponding Statements. The list of Operations and Statements are transformed into middleware types. This process can be seen as a compilation step. The frontend sends this middleware data as a request to the Backend. +2. The backend receives a request to build a POD from a list of Statements and Operations. It takes that bundle of data and lays it out in the appropriate format to be proved by a circuit, padding unused slots, etc. Then it calls a proof system API to generate a proof. +3. The target (proof system) generates a proof from some circuit description and witness data and gives it back to the backend. +4. The backend receives the proof and encapsulates it in an object that adheres to the Pod trait and passes it to the frontend +5. The frontend receives a "blackbox" Pod object and wraps it in a presentation layer in order to show it to the user. diff --git a/book/src/img/frontend-backend.png b/book/src/img/frontend-backend.png new file mode 100644 index 0000000000000000000000000000000000000000..9fceba0b5d9ad2d13bfaf4fd8fd37b991cdf1736 GIT binary patch literal 32564 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 literal 0 HcmV?d00001