Skip to content

Commit aa52896

Browse files
taturosatiglpecileNicolasRampoldientropidelic
authored
docs: batcher payment system (#692)
Co-authored-by: Gian <[email protected]> Co-authored-by: NicolasRampoldi <[email protected]> Co-authored-by: Mariano Nicolini <[email protected]>
1 parent 94d907c commit aa52896

File tree

7 files changed

+217
-49
lines changed

7 files changed

+217
-49
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ OS := $(shell uname -s)
55
CONFIG_FILE?=config-files/config.yaml
66
AGG_CONFIG_FILE?=config-files/config-aggregator.yaml
77

8-
OPERATOR_VERSION=v0.3.0
8+
OPERATOR_VERSION=v0.4.0
99

1010
ifeq ($(OS),Linux)
1111
BUILD_ALL_FFI = $(MAKE) build_all_ffi_linux

batcher/aligned-sdk/src/sdk.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use futures_util::{
3939
/// * `chain` - The chain on which the verification will be done.
4040
/// * `verification_data` - An array of verification data of each proof.
4141
/// * `wallet` - The wallet used to sign the proof.
42-
/// * `batcher_payment_service_addr` - The address of the batcher payment service.
42+
/// * `nonce` - The nonce to use.
4343
/// # Returns
4444
/// * An array of aligned verification data obtained when submitting the proof.
4545
/// # Errors
@@ -52,6 +52,12 @@ use futures_util::{
5252
/// * `EthereumProviderError` if there is an error in the connection with the RPC provider.
5353
/// * `HexDecodingError` if there is an error decoding the Aligned service manager contract address.
5454
/// * `BatchVerificationTimeout` if there is a timeout waiting for the batch verification.
55+
/// * `InvalidSignature` if the signature is invalid.
56+
/// * `InvalidNonce` if the nonce is invalid.
57+
/// * `InvalidProof` if the proof is invalid.
58+
/// * `ProofTooLarge` if the proof is too large.
59+
/// * `InsufficientBalance` if the sender balance is insufficient or unlocked
60+
/// * `ProofQueueFlushed` if there is an error in the batcher and the proof queue is flushed.
5561
/// * `GenericError` if the error doesn't match any of the previous ones.
5662
pub async fn submit_multiple_and_wait(
5763
batcher_addr: &str,
@@ -87,7 +93,7 @@ pub async fn submit_multiple_and_wait(
8793
/// * `eth_rpc_url` - The URL of the Ethereum RPC node.
8894
/// * `verification_data` - An array of verification data of each proof.
8995
/// * `wallet` - The wallet used to sign the proof.
90-
/// * `batcher_payment_service_addr` - The address of the batcher payment service.
96+
/// * `nonce` - The nonce to use.
9197
/// # Returns
9298
/// * An array of aligned verification data obtained when submitting the proof.
9399
/// # Errors
@@ -97,6 +103,12 @@ pub async fn submit_multiple_and_wait(
97103
/// * `SerializationError` if there is an error deserializing the message sent from the batcher.
98104
/// * `WebSocketConnectionError` if there is an error connecting to the batcher.
99105
/// * `WebSocketClosedUnexpectedlyError` if the connection with the batcher is closed unexpectedly.
106+
/// * `InvalidSignature` if the signature is invalid.
107+
/// * `InvalidNonce` if the nonce is invalid.
108+
/// * `InvalidProof` if the proof is invalid.
109+
/// * `ProofTooLarge` if the proof is too large.
110+
/// * `InsufficientBalance` if the sender balance is insufficient or unlocked.
111+
/// * `ProofQueueFlushed` if there is an error in the batcher and the proof queue is flushed.
100112
/// * `GenericError` if the error doesn't match any of the previous ones.
101113
pub async fn submit_multiple(
102114
batcher_addr: &str,
@@ -179,7 +191,7 @@ async fn _submit_multiple(
179191
/// * `chain` - The chain on which the verification will be done.
180192
/// * `verification_data` - The verification data of the proof.
181193
/// * `wallet` - The wallet used to sign the proof.
182-
/// * `batcher_payment_service_addr` - The address of the batcher payment service.
194+
/// * `nonce` - The nonce to use
183195
/// # Returns
184196
/// * The aligned verification data obtained when submitting the proof.
185197
/// # Errors
@@ -192,6 +204,12 @@ async fn _submit_multiple(
192204
/// * `EthereumProviderError` if there is an error in the connection with the RPC provider.
193205
/// * `HexDecodingError` if there is an error decoding the Aligned service manager contract address.
194206
/// * `BatchVerificationTimeout` if there is a timeout waiting for the batch verification.
207+
/// * `InvalidSignature` if the signature is invalid.
208+
/// * `InvalidNonce` if the nonce is invalid.
209+
/// * `InvalidProof` if the proof is invalid.
210+
/// * `ProofTooLarge` if the proof is too large.
211+
/// * `InsufficientBalance` if the sender balance is insufficient or unlocked
212+
/// * `ProofQueueFlushed` if there is an error in the batcher and the proof queue is flushed.
195213
/// * `GenericError` if the error doesn't match any of the previous ones.
196214
pub async fn submit_and_wait(
197215
batcher_addr: &str,
@@ -235,6 +253,12 @@ pub async fn submit_and_wait(
235253
/// * `SerializationError` if there is an error deserializing the message sent from the batcher.
236254
/// * `WebSocketConnectionError` if there is an error connecting to the batcher.
237255
/// * `WebSocketClosedUnexpectedlyError` if the connection with the batcher is closed unexpectedly.
256+
/// * `InvalidSignature` if the signature is invalid.
257+
/// * `InvalidNonce` if the nonce is invalid.
258+
/// * `InvalidProof` if the proof is invalid.
259+
/// * `ProofTooLarge` if the proof is too large.
260+
/// * `InsufficientBalance` if the sender balance is insufficient or unlocked
261+
/// * `ProofQueueFlushed` if there is an error in the batcher and the proof queue is flushed.
238262
/// * `GenericError` if the error doesn't match any of the previous ones.
239263
pub async fn submit(
240264
batcher_addr: &str,
@@ -333,6 +357,16 @@ pub fn get_commitment(content: &[u8]) -> [u8; 32] {
333357
hasher.finalize().into()
334358
}
335359

360+
/// Returns the next nonce for a given address.
361+
/// # Arguments
362+
/// * `eth_rpc_url` - The URL of the Ethereum RPC node.
363+
/// * `address` - The address for which the nonce will be retrieved.
364+
/// * `batcher_contract_address` - The address of the batcher payment service contract.
365+
/// # Returns
366+
/// * The next nonce.
367+
/// # Errors
368+
/// * `EthereumProviderError` if there is an error in the connection with the RPC provider.
369+
/// * `EthereumCallError` if there is an error in the Ethereum call.
336370
pub async fn get_next_nonce(
337371
eth_rpc_url: &str,
338372
address: Address,

docs/architecture/1_fast_mode.md

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,39 @@
11
## Fast mode in a nutshell
22

33
## Architecture
4+
45
Aligned’s architecture is shown in the figure below:
56

67
![Figure 1: Architecture fast mode](../images/aligned_architecture.png)
78

8-
Here, the validators/AVS operators are the ones responsible for proof verification. They fetch the proof data from the data service and verify it using the different proving systems supported by Aligned.
9+
Here, the validators/AVS operators are the ones responsible for proof verification.
10+
They fetch the proof data from the data service and verify it using the different proving systems supported by Aligned.
11+
12+
### What happens when sending a proof and publishing the result on Ethereum?
913

10-
### Flow for sending a proof and publishing the result on Ethereum
1114
The flow for sending a proof and having the results on Ethereum is as follows:
12-
1. The user uses a provided CLI or SDK to send one proof or many to the batcher, and waits.
13-
2. The batcher answers with a BatchInclusionData for each proof.
14-
3. The user invokes the VerifyBatchInclusion function in the ServiceManager contract with this data to check that the proof has been verified in Aligned and is included in the batch.
15-
4. Then, it is checked that the commitment of the proven program matches the expected one.
15+
16+
1. The user uses a provided CLI or SDK to send one or many proofs to the batcher, and waits.
17+
2. The batcher answers with a ValidityResponse for each proof (if proof, nonce and signature are valid).
18+
3. The batcher answers with a BatchInclusionData for each proof.
19+
4. The user invokes the VerifyBatchInclusion function in the ServiceManager contract with this data to check that the
20+
proof has been verified in Aligned and is included in the batch.
21+
5. Then, it is checked that the commitment of the proven program matches the expected one.
1622

1723
### Full flow with internals of the proof
1824

19-
1. The user uses a provided CLI or SDK to send one proof or many to the batcher, and waits (Alternatively, the user can run a batcher or interact directly with Ethereum).
20-
2. The batcher accumulates proofs of many users for a small number of blocks (typically 1-3).
21-
3. The batcher creates a Merkle Tree with commitments of all the data submitted by users, uploads the proofs to the Data Service, and creates the verification task in the ServiceManager.
22-
4. The operators, using the data in Ethereum, download the proofs from the DataService. They then verify that the Merkle root is equal to the one in Ethereum, and verifies all the proofs.
23-
5. If the proofs are valid, they sign the root and send this to the BLS signature aggregator.
24-
6. The signature aggregator accumulates the signed responses until reaching the quorum, then sends the aggregated signature to Ethereum.
25-
7. Ethereum verifies the aggregated signatures and changes the state of the batch to verified.
25+
1. The user uses a provided CLI or SDK to send one or more proofs to the batcher, and waits (Alternatively, the user can
26+
run a batcher or interact directly with Ethereum).
27+
2. The batcher accumulates proofs of many users for a small number of blocks (typically 1–3).
28+
3. The batcher creates a Merkle Tree with commitments of all the data submitted by users, uploads the proofs to the Data
29+
Service,
30+
and submits it to the [Batcher Payment Service](./components/2_payment_service_contract.md)
31+
4. The Batcher Payment Service rebuilds the merkle tree, and then verifies user signatures and nonce's.
32+
5. The Batcher Payment Service sends the batch to
33+
the [Aligned Service Manager](./components/3_service_manager_contract.md).
34+
6. The operators, using the data in Ethereum, download the proofs from the DataService.
35+
They then verify that the Merkle root is equal to the one in Ethereum, and verifies all the proofs.
36+
7. If the proofs are valid, they sign the root and send this to the BLS signature aggregator.
37+
8. The signature aggregator accumulates the signed responses until reaching the quorum, then sends the aggregated
38+
signature to Ethereum.
39+
9. Ethereum verifies the aggregated signatures and changes the state of the batch from pending to verified.
Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,44 @@
11
# Payment Service
22

3-
The Payment Service handles User's payments to fund the verification of their proofs.
3+
The Payment Service handles User's payments to fund the verification of their proofs.
44

5-
To be able to use the batcher, a user must fund its transactions. For this, there is a simple Batcher Payment System.
5+
To be able to use the batcher, a user must fund its transactions.
6+
For this, there is a simple Batcher Payment System.
67

7-
The Batcher has an associated Batcher Payments smart contract, which is in charge of receiving user's payments, and it guarantees that it can only spend these funds to send users' proofs to Aligned.
8+
The Batcher has an associated Batcher Payments smart contract,
9+
which is in charge of receiving user's payments,
10+
and it guarantees that it can only spend these funds to send users' proofs to Aligned.
811

9-
Users must first deposit into this contract, via a normal transfer to its address, where the Batcher Payment System will update the User's balance.
12+
Users must first deposit into this contract, via a normal transfer to its address,
13+
where the Batcher Payment System will update the User's balance.
1014

11-
Then, users can send proofs to the Batcher, the Batcher will preemptively check if the user has funds for this, and once the whole batch is assembled, the Batcher will call its smart contract with the data it has received from the users.
15+
Users send proofs to the Batcher, which checks for sufficient funds.
16+
Once a batch is complete, the Batcher calls its smart contract with the collected user data
1217

13-
The smart contract will then discount the corresponding amount of funds from each of the senders' balances, and create a new Batch in [Aligned Service Manager](./3_service_manager_contract.md), sending with it the corresponding amount of tokens for the batch verification to be paid to the [Aggregator](./5_aggregator.md).
18+
The smart contract deducts funds from senders' balances and creates a new Batch in
19+
the [Aligned Service Manager](./3_service_manager_contract.md),
20+
including tokens for batch verification payment to the [Aggregator](./5_aggregator.md).
1421

15-
Users can then withdraw extra funds deposited to the Batcher Payments smart contract, or leave them to fund future proofs.
22+
Users can then withdraw extra funds deposited to the Batcher Payments smart contract,
23+
or leave them to fund future proofs.
1624

1725
This way, the Batcher can only use User funds to pay for the verification of the User's proofs.
1826

27+
The Batcher Payment Service guarantees that the Batcher
28+
will not be able to spend the user funds for anything other than submitting the user's proofs to Aligned.
29+
30+
The way it does is:
31+
32+
- When the batcher calls the smart contract to create a new batch,
33+
it gets the batch merkle tree leaves, with each leaf, signed by the user.
34+
- The contract then rebuilds the merkle tree to check the
35+
batch merkle root and verifies the user signatures.
36+
- Each signature also contains a nonce that can only be used once per user,
37+
to avoid the batcher being able to reuse the same signature.
38+
- Only if the merkle root and the signatures are valid, the contract will
39+
discount the corresponding funds from the user's balance and
40+
create a new batch in the [Aligned Service Manager](./3_service_manager_contract.md).
41+
1942
## Details of the contract
2043

2144
### API
@@ -26,27 +49,53 @@ This way, the Batcher can only use User funds to pay for the verification of the
2649
receive() external payable
2750
```
2851

29-
This function will be called every time a User transfers funds to the smart contract. It will not only receive the funds, but it will also register internally how much the User deposited, to keep track of each User's funds separately.
30-
52+
This function will be called every time a User transfers funds to the smart contract.
53+
It will not only receive the funds, but it will also register internally how much the User deposited,
54+
to keep track of each User's funds separately.
3155

3256
#### Create New Task
3357

3458
```solidity
3559
function createNewTask(
3660
bytes32 batchMerkleRoot,
3761
string calldata batchDataPointer,
38-
address[] calldata proofSubmitters,
62+
bytes32[] calldata leaves, // padded to the next power of 2
63+
SignatureData[] calldata signatures, // actual length (proof sumbitters == proofs submitted)
3964
uint256 gasForAggregator,
4065
uint256 gasPerProof
4166
) external onlyBatcher
4267
```
4368

44-
This function will be executed only by the Batcher, when it has a batch to post to Aligned. It contains all the information needed to post the batch in [Aligned Service Manager](./3_service_manager_contract.md) (`batchMerkleRoot` and `batchDataPointer`), plus an array containing which are the `proofSubmitters`, so as to discount `gasPerProof` from these, and also the `gasForAggregator`, declaring how much will need to go pay for the response of the batch.
69+
This function will be executed only by the Batcher when it has a batch to post to Aligned.
70+
It contains all the information needed to post the batch
71+
in [Aligned Service Manager](./3_service_manager_contract.md) (`batchMerkleRoot`
72+
and `batchDataPointer`), plus an array containing which are the `proofSubmitters`, to discount `gasPerProof` from
73+
these, and also the `gasForAggregator`, declaring how much will need to go pay for the response of the batch.
74+
75+
#### Unlock
76+
77+
```solidity
78+
function unlock() external
79+
```
80+
81+
Any user can call this function to unlock its funds for withdrawal after 100 blocks.
82+
83+
Note that if the user funds are unlocked, the batcher will reject any new proofs from this user until the funds are
84+
locked again.
85+
86+
#### Lock
87+
88+
```solidity
89+
function lock() external
90+
```
91+
92+
Any user can call this function to lock its funds again after unlocking.
4593

4694
#### Withdraw
4795

4896
```solidity
4997
function withdraw(uint256 amount) external
5098
```
5199

52-
This function can be called by any User, to freely withdraw any amount of their available balance from the contract.
100+
Any User can call this function to withdraw any amount of their available balance from the contract,
101+
only when their funds are unlocked.

0 commit comments

Comments
 (0)