Skip to content

Commit 2d4d31d

Browse files
authored
feat: add architecture doc (#73)
* feat: add architecture doc * fix: typos
1 parent 1b6e0c9 commit 2d4d31d

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

book/src/SUMMARY.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
- [SignedPOD](./signedpod.md)
1818
- [MainPOD](./mainpod.md)
1919
- [MockPOD](./mockpod.md)
20-
- [Examples](./examples.md)
20+
- [Examples](./examples.md)
21+
22+
# Architecture
23+
- [Architecture](./architecture.md)

book/src/architecture.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Architecture
2+
3+
This document explains the architecture of the current implementation.
4+
5+
The main logic of the POD2 implementation is divided into three modules:
6+
- frontend
7+
- compiles user-friendly pod declarations into intermediate representations to be consumed by the backend
8+
- internally connects to the backend to get pods built (signed / proved).
9+
- presents pods to the user
10+
- middleware
11+
- defines the intermediate representation of Statements, Operations and interfaces of PODs
12+
- Statements and Operations are strongly typed here
13+
- Both frontend and backend use types defined in the middleware
14+
- Does not import types from frontend nor backend
15+
- backend
16+
- takes a middleware POD request representation, signs/proves it and returns a generic POD object
17+
18+
If this was the Rust language compiler:
19+
- frontend: takes a Rust code and compiles it to LLVM-IR
20+
- middleware: defines LLVM-IR instructions and blocks
21+
- backend: Takes LLVM-IR instructions and emits assembly code for a particular CPU
22+
23+
The following diagram shows visually how the components interact with each other:
24+
25+
![](img/frontend-backend.png)
26+
27+
In this organization, the middleware could be defined at arbitrary points:
28+
- closer to the user would be more high level
29+
- closer to the target would be more low level
30+
31+
All these positions are OK. We just need to choose one, and we can try to choose a point that simplifies the implementation.
32+
33+
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).
34+
35+
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.
36+
37+
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.
38+
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.
39+
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.
40+
3. The target (proof system) generates a proof from some circuit description and witness data and gives it back to the backend.
41+
4. The backend receives the proof and encapsulates it in an object that adheres to the Pod trait and passes it to the frontend
42+
5. The frontend receives a "blackbox" Pod object and wraps it in a presentation layer in order to show it to the user.

book/src/img/frontend-backend.png

31.8 KB
Loading

0 commit comments

Comments
 (0)