-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Sequence Sender & Aggregator (#10)
* feat: sequence sender and aggregator
- Loading branch information
1 parent
f256553
commit 26e7139
Showing
86 changed files
with
15,442 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
**/.DS_Store | ||
.vscode | ||
.env | ||
/dist/ | ||
cmd/__debug_bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# CONTAINER FOR BUILDING BINARY | ||
FROM golang:1.22.4 AS build | ||
|
||
# INSTALL DEPENDENCIES | ||
RUN go install github.com/gobuffalo/packr/v2/[email protected] | ||
COPY go.mod go.sum /src/ | ||
RUN cd /src && go mod download | ||
|
||
# BUILD BINARY | ||
COPY . /src | ||
RUN cd /src/aggregator/db && packr2 | ||
RUN cd /src && make build | ||
|
||
# CONTAINER FOR RUNNING BINARY | ||
FROM alpine:3.18.4 | ||
COPY --from=build /src/dist/cdk /app/cdk | ||
RUN apk update && apk add postgresql15-client | ||
EXPOSE 8123 | ||
CMD ["/bin/sh", "-c", "/app/cdk run"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
include version.mk | ||
|
||
ARCH := $(shell arch) | ||
|
||
ifeq ($(ARCH),x86_64) | ||
ARCH = amd64 | ||
else | ||
ifeq ($(ARCH),aarch64) | ||
ARCH = arm64 | ||
endif | ||
endif | ||
GOBASE := $(shell pwd) | ||
GOBIN := $(GOBASE)/dist | ||
GOENVVARS := GOBIN=$(GOBIN) CGO_ENABLED=0 GOOS=linux GOARCH=$(ARCH) | ||
GOBINARY := cdk | ||
GOCMD := $(GOBASE)/cmd | ||
|
||
LDFLAGS += -X 'github.com/0xPolygon/cdk.Version=$(VERSION)' | ||
LDFLAGS += -X 'github.com/0xPolygon/cdk.GitRev=$(GITREV)' | ||
LDFLAGS += -X 'github.com/0xPolygon/cdk.GitBranch=$(GITBRANCH)' | ||
LDFLAGS += -X 'github.com/0xPolygon/cdk.BuildDate=$(DATE)' | ||
|
||
# Variables | ||
VENV = .venv | ||
VENV_PYTHON = $(VENV)/bin/python | ||
SYSTEM_PYTHON = $(or $(shell which python3), $(shell which python)) | ||
PYTHON = $(or $(wildcard $(VENV_PYTHON)), "install_first_venv") | ||
GENERATE_SCHEMA_DOC = $(VENV)/bin/generate-schema-doc | ||
GENERATE_DOC_PATH = "docs/config-file/" | ||
GENERATE_DOC_TEMPLATES_PATH = "docs/config-file/templates/" | ||
|
||
# Check dependencies | ||
# Check for Go | ||
.PHONY: check-go | ||
check-go: | ||
@which go > /dev/null || (echo "Error: Go is not installed" && exit 1) | ||
|
||
# Check for Docker | ||
.PHONY: check-docker | ||
check-docker: | ||
@which docker > /dev/null || (echo "Error: docker is not installed" && exit 1) | ||
|
||
# Check for Docker-compose | ||
.PHONY: check-docker-compose | ||
check-docker-compose: | ||
@which docker-compose > /dev/null || (echo "Error: docker-compose is not installed" && exit 1) | ||
|
||
# Check for Protoc | ||
.PHONY: check-protoc | ||
check-protoc: | ||
@which protoc > /dev/null || (echo "Error: Protoc is not installed" && exit 1) | ||
|
||
# Check for Curl | ||
.PHONY: check-curl | ||
check-curl: | ||
@which curl > /dev/null || (echo "Error: curl is not installed" && exit 1) | ||
|
||
# Targets that require the checks | ||
build: check-go | ||
lint: check-go | ||
build-docker: check-docker | ||
build-docker-nc: check-docker | ||
stop: check-docker check-docker-compose | ||
install-linter: check-go check-curl | ||
generate-code-from-proto: check-protoc | ||
|
||
.PHONY: build | ||
build: ## Builds the binary locally into ./dist | ||
$(GOENVVARS) go build -ldflags "all=$(LDFLAGS)" -o $(GOBIN)/$(GOBINARY) $(GOCMD) | ||
|
||
.PHONY: build-docker | ||
build-docker: ## Builds a docker image with the cdk binary | ||
docker build -t cdk -f ./Dockerfile . | ||
|
||
.PHONY: build-docker-nc | ||
build-docker-nc: ## Builds a docker image with the cdk binary - but without build cache | ||
docker build --no-cache=true -t cdk -f ./Dockerfile . | ||
|
||
.PHONY: stop | ||
stop: ## Stops all services | ||
docker-compose down | ||
|
||
.PHONY: test | ||
test: | ||
go test -count=1 -short -race -p 1 -timeout 60s ./... | ||
|
||
.PHONY: install-linter | ||
install-linter: ## Installs the linter | ||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $$(go env GOPATH)/bin v1.54.2 | ||
|
||
.PHONY: lint | ||
lint: ## Runs the linter | ||
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/golangci-lint run | ||
|
||
$(VENV_PYTHON): | ||
rm -rf $(VENV) | ||
$(SYSTEM_PYTHON) -m venv $(VENV) | ||
|
||
venv: $(VENV_PYTHON) | ||
|
||
.PHONY: generate-code-from-proto | ||
generate-code-from-proto: ## Generates code from proto files | ||
cd proto/src/proto/aggregator/v1 && protoc --proto_path=. --proto_path=../../../../include --go_out=../../../../../aggregator/prover --go-grpc_out=../../../../../aggregator/prover --go-grpc_opt=paths=source_relative --go_opt=paths=source_relative aggregator.proto | ||
cd proto/src/proto/datastream/v1 && protoc --proto_path=. --proto_path=../../../../include --go_out=../../../../../state/datastream --go-grpc_out=../../../../../state/datastream --go-grpc_opt=paths=source_relative --go_opt=paths=source_relative datastream.proto | ||
|
||
|
||
## Help display. | ||
## Pulls comments from beside commands and prints a nicely formatted | ||
## display with the commands and their usage information. | ||
.DEFAULT_GOAL := help | ||
|
||
.PHONY: help | ||
help: ## Prints this help | ||
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \ | ||
| sort \ | ||
| awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package aggregator | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"strings" | ||
"time" | ||
|
||
"github.com/0xPolygon/cdk-rpc/rpc" | ||
"github.com/0xPolygon/cdk-rpc/types" | ||
"github.com/ethereum/go-ethereum/common" | ||
) | ||
|
||
// AgglayerClientInterface is the interface that defines the methods that the AggLayerClient will implement | ||
type AgglayerClientInterface interface { | ||
SendTx(signedTx SignedTx) (common.Hash, error) | ||
WaitTxToBeMined(hash common.Hash, ctx context.Context) error | ||
} | ||
|
||
// AggLayerClient is the client that will be used to interact with the AggLayer | ||
type AggLayerClient struct { | ||
url string | ||
} | ||
|
||
// NewAggLayerClient returns a client ready to be used | ||
func NewAggLayerClient(url string) *AggLayerClient { | ||
return &AggLayerClient{ | ||
url: url, | ||
} | ||
} | ||
|
||
// SendTx sends a signed transaction to the AggLayer | ||
func (c *AggLayerClient) SendTx(signedTx SignedTx) (common.Hash, error) { | ||
response, err := rpc.JSONRPCCall(c.url, "interop_sendTx", signedTx) | ||
if err != nil { | ||
return common.Hash{}, err | ||
} | ||
|
||
if response.Error != nil { | ||
return common.Hash{}, fmt.Errorf("%v %v", response.Error.Code, response.Error.Message) | ||
} | ||
|
||
var result types.ArgHash | ||
err = json.Unmarshal(response.Result, &result) | ||
if err != nil { | ||
return common.Hash{}, err | ||
} | ||
|
||
return result.Hash(), nil | ||
} | ||
|
||
// WaitTxToBeMined waits for a transaction to be mined | ||
func (c *AggLayerClient) WaitTxToBeMined(hash common.Hash, ctx context.Context) error { | ||
ticker := time.NewTicker(time.Second) | ||
for { | ||
select { | ||
case <-ctx.Done(): | ||
return errors.New("context finished before tx was mined") | ||
case <-ticker.C: | ||
response, err := rpc.JSONRPCCall(c.url, "interop_getTxStatus", hash) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if response.Error != nil { | ||
return fmt.Errorf("%v %v", response.Error.Code, response.Error.Message) | ||
} | ||
|
||
var result string | ||
err = json.Unmarshal(response.Result, &result) | ||
if err != nil { | ||
return err | ||
} | ||
if strings.ToLower(result) == "done" { | ||
return nil | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package aggregator | ||
|
||
import ( | ||
"crypto/ecdsa" | ||
|
||
"github.com/0xPolygon/cdk-rpc/types" | ||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/crypto" | ||
) | ||
|
||
// ZKP is the struct that contains the zero-knowledge proof | ||
type ZKP struct { | ||
NewStateRoot common.Hash `json:"newStateRoot"` | ||
NewLocalExitRoot common.Hash `json:"newLocalExitRoot"` | ||
Proof types.ArgBytes `json:"proof"` | ||
} | ||
|
||
// Tx is the struct that contains the verified batch transaction | ||
type Tx struct { | ||
RollupID uint32 | ||
LastVerifiedBatch types.ArgUint64 `json:"lastVerifiedBatch"` | ||
NewVerifiedBatch types.ArgUint64 `json:"newVerifiedBatch"` | ||
ZKP ZKP `json:"ZKP"` | ||
} | ||
|
||
// Hash returns a hash that uniquely identifies the tx | ||
func (t *Tx) Hash() common.Hash { | ||
return common.BytesToHash(crypto.Keccak256( | ||
[]byte(t.LastVerifiedBatch.Hex()), | ||
[]byte(t.NewVerifiedBatch.Hex()), | ||
t.ZKP.NewStateRoot[:], | ||
t.ZKP.NewLocalExitRoot[:], | ||
[]byte(t.ZKP.Proof.Hex()), | ||
)) | ||
} | ||
|
||
// Sign returns a signed batch by the private key | ||
func (t *Tx) Sign(privateKey *ecdsa.PrivateKey) (*SignedTx, error) { | ||
hashToSign := t.Hash() | ||
sig, err := crypto.Sign(hashToSign.Bytes(), privateKey) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &SignedTx{ | ||
Tx: *t, | ||
Signature: sig, | ||
}, nil | ||
} | ||
|
||
// SignedTx is the struct that contains the signed batch transaction | ||
type SignedTx struct { | ||
Tx Tx `json:"tx"` | ||
Signature types.ArgBytes `json:"signature"` | ||
} | ||
|
||
// Signer returns the address of the signer | ||
func (s *SignedTx) Signer() (common.Address, error) { | ||
pubKey, err := crypto.SigToPub(s.Tx.Hash().Bytes(), s.Signature) | ||
if err != nil { | ||
return common.Address{}, err | ||
} | ||
return crypto.PubkeyToAddress(*pubKey), nil | ||
} |
Oops, something went wrong.