Skip to content

Commit e4bc95d

Browse files
committed
Merge branch 'main' into mina
2 parents e0e42d2 + d32af8f commit e4bc95d

108 files changed

Lines changed: 9251 additions & 2747 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build-rust.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: build-rust-projects
2+
3+
on:
4+
merge_group:
5+
push:
6+
branches: [main]
7+
pull_request:
8+
branches: ["*"]
9+
10+
jobs:
11+
build:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Set up Rust
18+
uses: actions-rs/toolchain@v1
19+
with:
20+
toolchain: stable
21+
components: rustfmt, clippy
22+
override: true
23+
- name: Cache Rust dependencies
24+
uses: actions/cache@v3
25+
with:
26+
path: |
27+
~/.cargo/registry
28+
~/.cargo/git
29+
batcher/target
30+
key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }}
31+
restore-keys: |
32+
${{ runner.os }}-rust-
33+
- name: Check formatting of Rust projects
34+
run: |
35+
cd batcher
36+
cargo fmt --all -- --check
37+
- name: Run Clippy
38+
run: |
39+
cd batcher
40+
cargo clippy --all -- -D warnings
41+
- name: Build Rust projects
42+
run: |
43+
cd batcher
44+
cargo build --all

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ scripts/test_files/gnark_groth16_bn254_infinite_script/infinite_proofs/**
1010
batcher/aligned/batch_inclusion_responses/*
1111
**/aligned_verification_data
1212
**/broadcast
13+
volume
1314

1415
nonce_*.bin

Makefile

Lines changed: 12 additions & 19 deletions
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
@@ -173,10 +173,6 @@ operator_deposit_and_register: operator_deposit_into_strategy operator_register_
173173

174174
operator_full_registration: operator_get_eth operator_register_with_eigen_layer operator_mint_mock_tokens operator_deposit_into_mock_strategy operator_whitelist_devnet operator_register_with_aligned_layer
175175

176-
operator_start_docker:
177-
@echo "Starting Operator..."
178-
@docker-compose -f operator/docker/compose.yaml up
179-
180176
__BATCHER__:
181177

182178
BURST_SIZE=5
@@ -191,6 +187,11 @@ batcher_start: ./batcher/aligned-batcher/.env user_fund_payment_service
191187
@echo "Starting Batcher..."
192188
@cargo +nightly-2024-04-17 run --manifest-path ./batcher/aligned-batcher/Cargo.toml --release -- --config ./config-files/config-batcher.yaml --env-file ./batcher/aligned-batcher/.env
193189

190+
batcher_start_local: ./batcher/aligned-batcher/.env user_fund_payment_service
191+
@echo "Starting Batcher..."
192+
@$(MAKE) run_storage &
193+
@cargo +nightly-2024-04-17 run --manifest-path ./batcher/aligned-batcher/Cargo.toml --release -- --config ./config-files/config-batcher.yaml --env-file ./batcher/aligned-batcher/.env.dev
194+
194195
install_batcher:
195196
@cargo +nightly-2024-04-17 install --path batcher/aligned-batcher
196197

@@ -234,7 +235,6 @@ batcher_send_sp1_burst:
234235
--rpc $(RPC_URL) \
235236
--batcher_addr $(BATCHER_CONTRACT_ADDRESS)
236237

237-
238238
batcher_send_infinite_sp1:
239239
@echo "Sending infinite SP1 fibonacci task to Batcher..."
240240
@./batcher/aligned/send_infinite_sp1_tasks/send_infinite_sp1_tasks.sh
@@ -319,18 +319,6 @@ batcher_send_groth16_bn254_task: batcher/target/release/aligned
319319
--rpc $(RPC_URL) \
320320
--batcher_addr $(BATCHER_CONTRACT_ADDRESS)
321321

322-
batcher_send_groth16_burst: batcher/target/release/aligned
323-
@echo "Sending Groth16Bn254 1!=0 task to Batcher..."
324-
@cd batcher/aligned/ && cargo run --release -- submit \
325-
--proving_system Groth16Bn254 \
326-
--proof ../../scripts/test_files/gnark_groth16_bn254_infinite_script/infinite_proofs/ineq_1_groth16.proof \
327-
--public_input ../../scripts/test_files/gnark_groth16_bn254_infinite_script/infinite_proofs/ineq_1_groth16.pub \
328-
--vk ../../scripts/test_files/gnark_groth16_bn254_infinite_script/infinite_proofs/ineq_1_groth16.vk \
329-
--repetitions 15 \
330-
--proof_generator_addr 0x66f9664f97F2b50F62D13eA064982f936dE76657 \
331-
--rpc $(RPC_URL) \
332-
--batcher_addr $(BATCHER_CONTRACT_ADDRESS)
333-
334322
batcher_send_infinite_groth16: batcher/target/release/aligned ## Send a different Groth16 BN254 proof using the client every 3 seconds
335323
@mkdir -p scripts/test_files/gnark_groth16_bn254_infinite_script/infinite_proofs
336324
@echo "Sending a different GROTH16 BN254 proof in a loop every n seconds..."
@@ -440,7 +428,12 @@ generate_groth16_ineq_proof: ## Run the gnark_plonk_bn254_script
440428
__METRICS__:
441429
run_metrics: ## Run metrics using metrics-docker-compose.yaml
442430
@echo "Running metrics..."
443-
@docker-compose -f metrics-docker-compose.yaml up
431+
@docker compose -f metrics-docker-compose.yaml up
432+
433+
__STORAGE__:
434+
run_storage: ## Run storage using storage-docker-compose.yaml
435+
@echo "Running storage..."
436+
@docker compose -f storage-docker-compose.yaml up
444437

445438
__DEPLOYMENT__:
446439
deploy_aligned_contracts: ## Deploy Aligned Contracts

README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@
1111
- [How to use the testnet](#how-to-use-the-testnet)
1212
- [Operator Guide](#operator-guide)
1313
- [Aligned Infrastructure Guide](#aligned-infrastructure-guide)
14-
- [FAQ](https://docs.alignedlayer.com/guides/4_faq)
1514

1615
## The Project
1716

18-
Aligned is a decentralized network of nodes that verifies Zero-Knowledge and Validity proofs, and post the results in Ethereum.
17+
Aligned is a decentralized network of nodes that verifies Zero-Knowledge and Validity proofs, and post the results in Ethereum.
1918

2019
These proofs can be generated and used for a tenth of the price, and with extremely low latency, allowing novel types of applications that weren't possible before in Ethereum.
2120

@@ -47,7 +46,9 @@ aligned submit \
4746
--proof ~/.aligned/test_files/sp1_fibonacci.proof \
4847
--vm_program ~/.aligned/test_files/sp1_fibonacci.elf \
4948
--aligned_verification_data_path ~/.aligned/aligned_verification_data \
50-
--conn wss://batcher.alignedlayer.com
49+
--conn wss://batcher.alignedlayer.com \
50+
--rpc https://ethereum-holesky-rpc.publicnode.com \
51+
--batcher_addr 0x815aeCA64a974297942D2Bbf034ABEe22a38A003
5152
```
5253

5354
5. You should get a response like this:
@@ -60,7 +61,7 @@ aligned submit \
6061
[2024-07-01T19:19:18Z INFO aligned] https://explorer.alignedlayer.com/batches/0xe367d76e832edec893d3a9027b3c231b2e3994c47acfac2e67197c13c9be0c4c
6162
```
6263
63-
You can use the link to the explorer to check the status of your transaction.
64+
You can use the link to the explorer to check the status of your transaction.
6465
6566
6. After three Ethereum blocks, you can check if it has been verified with:
6667
@@ -137,10 +138,10 @@ python3 -m pip install -r examples/verify/requirements.txt
137138
```bash
138139
python3 examples/verify/encode_verification_data.py --aligned-verification-data ~/.aligned/aligned_verification_data/*.json
139140
```
140-
141+
141142
If your verification data is in another path, just change the `--aligned-verification-data` parameter.
142143
143-
#### Using a caller contract
144+
#### Using a caller contract
144145
145146
To verify a proof in your own contract, use a static call to the Aligned contract. You can use the following [Caller Contract](examples/verify/src/VerifyBatchInclusionCaller.sol) as an example. The code will look like this:
146147
@@ -166,4 +167,4 @@ If you want to run an operator, check our [Operator Guide](./docs/operator_guide
166167
167168
## Aligned Infrastructure Guide
168169
169-
If you are developing in Aligned, or want to run your own devnet, check our [setup Aligned guide](docs/guides/3_setup_aligned.md)
170+
If you are developing in Aligned, or want to run your own devnet, check our [setup Aligned guide](docs/guides/5_setup_aligned.md)

aggregator/internal/pkg/aggregator.go

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ package pkg
33
import (
44
"context"
55
"encoding/hex"
6-
gethtypes "github.com/ethereum/go-ethereum/core/types"
6+
"fmt"
77
"sync"
88
"time"
99

10+
gethtypes "github.com/ethereum/go-ethereum/core/types"
11+
1012
"github.com/prometheus/client_golang/prometheus"
1113
"github.com/yetanotherco/aligned_layer/metrics"
1214

@@ -15,7 +17,7 @@ import (
1517
"github.com/Layr-Labs/eigensdk-go/logging"
1618
"github.com/Layr-Labs/eigensdk-go/services/avsregistry"
1719
blsagg "github.com/Layr-Labs/eigensdk-go/services/bls_aggregation"
18-
oppubkeysserv "github.com/Layr-Labs/eigensdk-go/services/operatorpubkeys"
20+
oppubkeysserv "github.com/Layr-Labs/eigensdk-go/services/operatorsinfo"
1921
eigentypes "github.com/Layr-Labs/eigensdk-go/types"
2022
"github.com/ethereum/go-ethereum/event"
2123
servicemanager "github.com/yetanotherco/aligned_layer/contracts/bindings/AlignedLayerServiceManager"
@@ -56,6 +58,12 @@ type Aggregator struct {
5658
// Stores the taskCreatedBlock for each batch bt batch index
5759
batchCreatedBlockByIdx map[uint32]uint64
5860

61+
// Stores if an operator already submitted a response for a batch
62+
// This is to avoid double submissions
63+
// struct{} is used as a placeholder because it is the smallest type
64+
// go does not have a set type
65+
operatorRespondedBatch map[uint32]map[eigentypes.Bytes32]struct{}
66+
5967
// This task index is to communicate with the local BLS
6068
// Service.
6169
// Note: In case of a reboot it can start from 0 again
@@ -113,9 +121,24 @@ func NewAggregator(aggregatorConfig config.AggregatorConfig) (*Aggregator, error
113121
return nil, err
114122
}
115123

116-
operatorPubkeysService := oppubkeysserv.NewOperatorPubkeysServiceInMemory(context.Background(), clients.AvsRegistryChainSubscriber, clients.AvsRegistryChainReader, logger)
117-
avsRegistryService := avsregistry.NewAvsRegistryServiceChainCaller(avsReader.AvsRegistryReader, operatorPubkeysService, logger)
118-
blsAggregationService := blsagg.NewBlsAggregatorService(avsRegistryService, logger)
124+
// This is a dummy "hash function" made to fulfill the BLS aggregator service API requirements.
125+
// When operators respond to a task, a call to `ProcessNewSignature` is made. In `v0.1.6` of the eigensdk,
126+
// this function required an argument `TaskResponseDigest`, which has changed to just `TaskResponse` in v0.1.9.
127+
// The digest we used in v0.1.6 was just the batch merkle root. To continue with the same idea, the hashing
128+
// function is set as the following one, which does nothing more than output the input it receives, which in
129+
// our case will be the batch merkle root. If wanted, we could define a real hash function here but there should
130+
// not be any need to re-hash the batch merkle root.
131+
hashFunction := func(taskResponse eigentypes.TaskResponse) (eigentypes.TaskResponseDigest, error) {
132+
taskResponseDigest, ok := taskResponse.([32]byte)
133+
if !ok {
134+
return eigentypes.TaskResponseDigest{}, fmt.Errorf("TaskResponse is not a 32-byte value")
135+
}
136+
return taskResponseDigest, nil
137+
}
138+
139+
operatorPubkeysService := oppubkeysserv.NewOperatorsInfoServiceInMemory(context.Background(), clients.AvsRegistryChainSubscriber, clients.AvsRegistryChainReader, nil, logger)
140+
avsRegistryService := avsregistry.NewAvsRegistryServiceChainCaller(avsReader.ChainReader, operatorPubkeysService, logger)
141+
blsAggregationService := blsagg.NewBlsAggregatorService(avsRegistryService, hashFunction, logger)
119142

120143
// Metrics
121144
reg := prometheus.NewRegistry()
@@ -133,6 +156,7 @@ func NewAggregator(aggregatorConfig config.AggregatorConfig) (*Aggregator, error
133156
batchesRootByIdx: batchesRootByIdx,
134157
batchesIdxByRoot: batchesIdxByRoot,
135158
batchCreatedBlockByIdx: batchCreatedBlockByIdx,
159+
operatorRespondedBatch: make(map[uint32]map[eigentypes.Bytes32]struct{}),
136160
nextBatchIndex: nextBatchIndex,
137161
taskMutex: &sync.Mutex{},
138162
walletMutex: &sync.Mutex{},
@@ -182,7 +206,16 @@ const MaxSentTxRetries = 5
182206

183207
func (agg *Aggregator) handleBlsAggServiceResponse(blsAggServiceResp blsagg.BlsAggregationServiceResponse) {
184208
if blsAggServiceResp.Err != nil {
185-
agg.logger.Warn("BlsAggregationServiceResponse contains an error", "err", blsAggServiceResp.Err)
209+
agg.taskMutex.Lock()
210+
batchMerkleRoot := agg.batchesRootByIdx[blsAggServiceResp.TaskIndex]
211+
agg.logger.Error("BlsAggregationServiceResponse contains an error", "err", blsAggServiceResp.Err, "merkleRoot", hex.EncodeToString(batchMerkleRoot[:]))
212+
agg.logger.Info("- Locking task mutex: Delete task from operator map", "taskIndex", blsAggServiceResp.TaskIndex)
213+
214+
// Remove task from the list of tasks
215+
delete(agg.operatorRespondedBatch, blsAggServiceResp.TaskIndex)
216+
217+
agg.logger.Info("- Unlocking task mutex: Delete task from operator map", "taskIndex", blsAggServiceResp.TaskIndex)
218+
agg.taskMutex.Unlock()
186219
return
187220
}
188221
nonSignerPubkeys := []servicemanager.BN254G1Point{}
@@ -209,13 +242,16 @@ func (agg *Aggregator) handleBlsAggServiceResponse(blsAggServiceResp blsagg.BlsA
209242
agg.AggregatorConfig.BaseConfig.Logger.Info("- Locked Resources: Fetching merkle root")
210243
batchMerkleRoot := agg.batchesRootByIdx[blsAggServiceResp.TaskIndex]
211244
taskCreatedBlock := agg.batchCreatedBlockByIdx[blsAggServiceResp.TaskIndex]
245+
246+
// Delete the task from the map
247+
delete(agg.operatorRespondedBatch, blsAggServiceResp.TaskIndex)
248+
212249
agg.AggregatorConfig.BaseConfig.Logger.Info("- Unlocked Resources: Fetching merkle root")
213250
agg.taskMutex.Unlock()
214251

215252
agg.logger.Info("Threshold reached", "taskIndex", blsAggServiceResp.TaskIndex,
216253
"merkleRoot", hex.EncodeToString(batchMerkleRoot[:]))
217254

218-
219255
currentBlock, err := agg.AggregatorConfig.BaseConfig.EthRpcClient.BlockNumber(context.Background())
220256
if err != nil {
221257
agg.logger.Error("Error getting current block number", "err", err)
@@ -270,10 +306,8 @@ func (agg *Aggregator) handleBlsAggServiceResponse(blsAggServiceResp blsagg.BlsA
270306
"merkleRoot", hex.EncodeToString(batchMerkleRoot[:]))
271307
}
272308

273-
274-
275-
/// Sends response to contract and waits for transaction receipt
276-
/// Returns error if it fails to send tx or receipt is not found
309+
// / Sends response to contract and waits for transaction receipt
310+
// / Returns error if it fails to send tx or receipt is not found
277311
func (agg *Aggregator) sendAggregatedResponse(batchMerkleRoot [32]byte, nonSignerStakesAndSignature servicemanager.IBLSSignatureCheckerNonSignerStakesAndSignature) (*gethtypes.Receipt, error) {
278312
agg.walletMutex.Lock()
279313
agg.logger.Infof("- Locked Wallet Resources: Sending aggregated response for batch %s", hex.EncodeToString(batchMerkleRoot[:]))
@@ -299,7 +333,6 @@ func (agg *Aggregator) sendAggregatedResponse(batchMerkleRoot [32]byte, nonSigne
299333
return receipt, nil
300334
}
301335

302-
303336
func (agg *Aggregator) AddNewTask(batchMerkleRoot [32]byte, taskCreatedBlock uint32) {
304337
agg.AggregatorConfig.BaseConfig.Logger.Info("Adding new task",
305338
"Batch merkle root", hex.EncodeToString(batchMerkleRoot[:]))

aggregator/internal/pkg/server.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"net/rpc"
88
"time"
99

10+
eigentypes "github.com/Layr-Labs/eigensdk-go/types"
11+
1012
"github.com/yetanotherco/aligned_layer/core/types"
1113
)
1214

@@ -73,6 +75,26 @@ func (agg *Aggregator) ProcessOperatorSignedTaskResponse(signedTaskResponse *typ
7375
return nil
7476
}
7577

78+
// Note: we already have lock here
79+
agg.logger.Debug("- Checking if operator already responded")
80+
batchResponses, ok := agg.operatorRespondedBatch[taskIndex]
81+
if !ok {
82+
batchResponses = make(map[eigentypes.Bytes32]struct{})
83+
agg.operatorRespondedBatch[taskIndex] = batchResponses
84+
}
85+
86+
if _, ok := batchResponses[signedTaskResponse.OperatorId]; ok {
87+
*reply = 0
88+
agg.logger.Warn("Operator already responded, ignoring",
89+
"operatorId", hex.EncodeToString(signedTaskResponse.OperatorId[:]),
90+
"taskIndex", taskIndex, "batchMerkleRoot", hex.EncodeToString(signedTaskResponse.BatchMerkleRoot[:]))
91+
92+
agg.taskMutex.Unlock()
93+
return nil
94+
}
95+
96+
batchResponses[signedTaskResponse.OperatorId] = struct{}{}
97+
7698
// Don't wait infinitely if it can't answer
7799
// Create a context with a timeout of 5 seconds
78100
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
@@ -90,6 +112,9 @@ func (agg *Aggregator) ProcessOperatorSignedTaskResponse(signedTaskResponse *typ
90112

91113
if err != nil {
92114
agg.logger.Warnf("BLS aggregation service error: %s", err)
115+
// remove operator from the list of operators that responded
116+
// so that it can try again
117+
delete(batchResponses, signedTaskResponse.OperatorId)
93118
} else {
94119
agg.logger.Info("BLS process succeeded")
95120
}

0 commit comments

Comments
 (0)