Skip to content

Commit 8d75e81

Browse files
committed
initial commit
0 parents  commit 8d75e81

Some content is hidden

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

57 files changed

+4497
-0
lines changed

.github/workflows/tests.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: tests
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
9+
jobs:
10+
Test:
11+
name: Unit Test
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: actions/setup-go@v4
16+
with:
17+
go-version: '1.22'
18+
- name: Unit Test
19+
run: make tests

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
bin/
2+
3+
.env
4+
5+
**/operators/

.gitmodules

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[submodule "example/contracts/lib/forge-std"]
2+
path = example/contracts/lib/forge-std
3+
url = https://github.com/foundry-rs/forge-std
4+
[submodule "example/contracts/lib/openzeppelin-contracts"]
5+
path = example/contracts/lib/openzeppelin-contracts
6+
url = https://github.com/OpenZeppelin/openzeppelin-contracts
7+
[submodule "example/contracts/lib/openzeppelin-contracts-upgradeable"]
8+
path = example/contracts/lib/openzeppelin-contracts-upgradeable
9+
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
10+
[submodule "example/contracts/lib/eigenlayer-middleware"]
11+
path = example/contracts/lib/eigenlayer-middleware
12+
url = https://github.com/Layr-Labs/eigenlayer-middleware

LICENSE

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
Business Source License 1.1
2+
3+
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
4+
"Business Source License" is a trademark of MariaDB Corporation Ab.
5+
6+
-----------------------------------------------------------------------------
7+
8+
Parameters
9+
10+
Licensor: Layr Labs, Inc.
11+
12+
Licensed Work: Teal
13+
The Licensed Work is (c) 2023 Layr Labs, Inc.
14+
15+
Additional Use Grant:
16+
17+
You may additionally use any of the software included in the following repositories
18+
[here](https://docs.google.com/spreadsheets/d/1PlJRow5C0GMqXZlIxRm5CEnkhH-gMV1wIdq1pCfbZco/edit?usp=sharing)
19+
(“Additional Use Grant Software”) for production commercial uses, but only if such
20+
uses are (i) built on or using the EigenLayer Protocol or EigenDA, and (ii) not
21+
Competing Uses.
22+
23+
“Competing Use” means any use of the Additional Use Grant Software in any product,
24+
protocol, application or service that is made available to third parties and that
25+
(i) substitutes for use of EigenLayer Protocol or EigenDA, (ii) offers the same or
26+
substantially similar functionality as the EigenLayer Protocol or EigenDA or
27+
(iii) is built on or using a protocol with substantially similar functionality as
28+
the EigenLayer Protocol.
29+
30+
EigenLayer Protocol means the restaking protocol as further described in the
31+
documentation [here](https://docs.eigenlayer.xyz/), as updated from time to time.
32+
33+
EigenDA means the data availability protocol built on top of the EigenLayer
34+
Protocol as further described in the documentation
35+
[here](https://docs.eigenlayer.xyz/eigenda/overview), as updated from time to time.
36+
37+
Change Dates:
38+
39+
- All commits before have a change date of 2029-01-20 (January 20th, 2029)
40+
41+
Change License: MIT
42+
43+
-----------------------------------------------------------------------------
44+
45+
Terms
46+
47+
The Licensor hereby grants you the right to copy, modify, create derivative
48+
works, redistribute, and make non-production use of the Licensed Work. The
49+
Licensor may make an Additional Use Grant, above, permitting limited
50+
production use.
51+
52+
Effective on the Change Date, or the fourth anniversary of the first publicly
53+
available distribution of a specific version of the Licensed Work under this
54+
License, whichever comes first, the Licensor hereby grants you rights under
55+
the terms of the Change License, and the rights granted in the paragraph
56+
above terminate.
57+
58+
If your use of the Licensed Work does not comply with the requirements
59+
currently in effect as described in this License, you must purchase a
60+
commercial license from the Licensor, its affiliated entities, or authorized
61+
resellers, or you must refrain from using the Licensed Work.
62+
63+
All copies of the original and modified Licensed Work, and derivative works
64+
of the Licensed Work, are subject to this License. This License applies
65+
separately for each version of the Licensed Work and the Change Date may vary
66+
for each version of the Licensed Work released by Licensor.
67+
68+
You must conspicuously display this License on each original or modified copy
69+
of the Licensed Work. If you receive the Licensed Work in original or
70+
modified form from a third party, the terms and conditions set forth in this
71+
License apply to your use of that work.
72+
73+
Any use of the Licensed Work in violation of this License will automatically
74+
terminate your rights under this License for the current and all other
75+
versions of the Licensed Work.
76+
77+
This License does not grant you any right in any trademark or logo of
78+
Licensor or its affiliates (provided that you may use a trademark or logo of
79+
Licensor as expressly required by this License).
80+
81+
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
82+
AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
83+
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
84+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
85+
TITLE.
86+
87+
MariaDB hereby grants you permission to use this License’s text to license
88+
your works, and to refer to it using the trademark "Business Source License",
89+
as long as you comply with the Covenants of Licensor below.
90+
91+
-----------------------------------------------------------------------------
92+
93+
Covenants of Licensor
94+
95+
In consideration of the right to use this License’s text and the "Business
96+
Source License" name and trademark, Licensor covenants to MariaDB, and to all
97+
other recipients of the licensed work to be provided by Licensor:
98+
99+
1. To specify as the Change License the GPL Version 2.0 or any later version,
100+
or a license that is compatible with GPL Version 2.0 or a later version,
101+
where "compatible" means that software provided under the Change License can
102+
be included in a program with software provided under GPL Version 2.0 or a
103+
later version. Licensor may specify additional Change Licenses without
104+
limitation.
105+
106+
2. To either: (a) specify an additional grant of rights to use that does not
107+
impose any additional restriction on the right granted in this License, as
108+
the Additional Use Grant; or (b) insert the text "None".
109+
110+
3. To specify a Change Date.
111+
112+
4. Not to modify this License in any other way.
113+
114+
-----------------------------------------------------------------------------
115+
116+
Notice
117+
118+
The Business Source License (this document, or the "License") is not an Open
119+
Source license. However, the Licensed Work will eventually be made available
120+
under an Open Source License, as stated in this License.

Makefile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
.PHONY: install
2+
install-macos-linux:
3+
@echo "Installing dependencies"
4+
brew install bufbuild/buf/buf
5+
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
6+
go install github.com/golang/protobuf/protoc-gen-go@latest
7+
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest
8+
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@latest
9+
@echo "Done"
10+
11+
.PHONY: generate
12+
generate:
13+
@echo "Generating go bindings"
14+
cd api/proto && buf generate
15+
@echo "Done"
16+
17+
.PHONY: build-node
18+
build-node:
19+
@echo "Building node"
20+
go build -o bin/node node/cmd/main.go
21+
@echo "Done"
22+
23+
.PHONY: fmt
24+
fmt: ## formats all go files
25+
go fmt ./...
26+
27+
.PHONY: test
28+
tests:
29+
go test ./...

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# teal
2+
3+
## Install Dependencies
4+
5+
```
6+
make install-macos-linux
7+
```

aggregator/aggregator.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package aggregator
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"math/big"
7+
"sync"
8+
"time"
9+
10+
"github.com/Layr-Labs/eigensdk-go/crypto/bls"
11+
"github.com/Layr-Labs/eigensdk-go/logging"
12+
"github.com/Layr-Labs/eigensdk-go/services/avsregistry"
13+
blsagg "github.com/Layr-Labs/eigensdk-go/services/bls_aggregation"
14+
"github.com/Layr-Labs/eigensdk-go/types"
15+
operatorrequester "github.com/Layr-Labs/teal/aggregator/operator_requester"
16+
)
17+
18+
type AggregatorService struct {
19+
logger logging.Logger
20+
avsRegistryReader avsregistry.AvsRegistryService
21+
blsAggService blsagg.BlsAggregationService
22+
operatorRequester operatorrequester.OperatorRequester
23+
24+
mu sync.Mutex
25+
}
26+
27+
func NewAggregatorService(
28+
logger logging.Logger,
29+
avsRegistryReader avsregistry.AvsRegistryService,
30+
blsAggService blsagg.BlsAggregationService,
31+
operatorRequester operatorrequester.OperatorRequester,
32+
) *AggregatorService {
33+
return &AggregatorService{
34+
logger: logger,
35+
avsRegistryReader: avsRegistryReader,
36+
blsAggService: blsAggService,
37+
operatorRequester: operatorRequester,
38+
}
39+
}
40+
41+
// GetCertificate sends a task to all registered nodes and aggregates their responses
42+
// Only works for single quorum for simplicity
43+
func (s *AggregatorService) GetCertificate(
44+
ctx context.Context,
45+
taskIndex types.TaskIndex,
46+
taskCreatedBlock uint32,
47+
quorumNumber types.QuorumNum,
48+
quorumThresholdPercentage types.QuorumThresholdPercentage,
49+
data []byte,
50+
timeToExpiry time.Duration,
51+
) (*blsagg.BlsAggregationServiceResponse, error) {
52+
// Only allow one task at a time
53+
s.mu.Lock()
54+
defer s.mu.Unlock()
55+
56+
quorumNumbers := types.QuorumNums{quorumNumber}
57+
quorumThresholdPercentages := types.QuorumThresholdPercentages{quorumThresholdPercentage}
58+
59+
// Initialize task in BLS aggregation service
60+
err := s.blsAggService.InitializeNewTaskWithWindow(
61+
taskIndex,
62+
taskCreatedBlock,
63+
quorumNumbers,
64+
quorumThresholdPercentages,
65+
timeToExpiry,
66+
1*time.Second,
67+
)
68+
if err != nil {
69+
return nil, fmt.Errorf("failed to initialize task: %w", err)
70+
}
71+
72+
// Get operators from registry
73+
operators, err := s.avsRegistryReader.GetOperatorsAvsStateAtBlock(ctx, quorumNumbers, taskCreatedBlock)
74+
if err != nil {
75+
return nil, fmt.Errorf("failed to get operators: %w", err)
76+
}
77+
78+
// Send task to all operators in parallel
79+
for operatorId, operator := range operators {
80+
go func(operatorId types.OperatorId, operator types.OperatorAvsState) {
81+
s.logger.Info("Requesting certification from operator", "operatorId", operatorId, "socket", operator.OperatorInfo.Socket)
82+
// Create connection for this operator
83+
resp, err := s.operatorRequester.RequestCertification(ctx, operator, taskIndex, data)
84+
if err != nil {
85+
return
86+
}
87+
88+
signature := &bls.Signature{G1Point: bls.NewG1Point(big.NewInt(0), big.NewInt(0))}
89+
_, err = signature.SetBytes(resp.Signature)
90+
if err != nil {
91+
s.logger.Error("Failed to unmarshal signature",
92+
"operatorId", operatorId,
93+
"error", err)
94+
return
95+
}
96+
97+
s.logger.Info("Received signature from operator", "operatorId", operatorId)
98+
99+
// Process signature from node
100+
err = s.blsAggService.ProcessNewSignature(
101+
ctx,
102+
taskIndex,
103+
types.TaskResponse(resp.Data),
104+
signature,
105+
operatorId,
106+
)
107+
if err != nil {
108+
s.logger.Error("Failed to process signature",
109+
"operatorId", operatorId,
110+
"error", err)
111+
return
112+
}
113+
s.logger.Info("Processed signature from operator", "operatorId", operatorId)
114+
}(operatorId, operator)
115+
}
116+
117+
// Wait for aggregated response
118+
select {
119+
case resp := <-s.blsAggService.GetResponseChannel():
120+
if resp.Err != nil {
121+
return nil, fmt.Errorf("aggregation failed: %w", resp.Err)
122+
}
123+
return &resp, nil
124+
case <-ctx.Done():
125+
return nil, ctx.Err()
126+
}
127+
}

0 commit comments

Comments
 (0)