Skip to content

Commit 276385f

Browse files
yiweichicolinlyguo
andauthored
feat: add blob storage service (#1672)
Co-authored-by: colin <102356659+colinlyguo@users.noreply.github.com> Co-authored-by: yiweichi <yiweichi@users.noreply.github.com>
1 parent 82fb15d commit 276385f

File tree

27 files changed

+894
-13
lines changed

27 files changed

+894
-13
lines changed

.github/workflows/docker.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,51 @@ jobs:
9999
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
100100
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:latest
101101
102+
blob_uploader:
103+
runs-on: ubuntu-latest
104+
steps:
105+
- name: Checkout code
106+
uses: actions/checkout@v4
107+
- name: Set up QEMU
108+
uses: docker/setup-qemu-action@v2
109+
- name: Set up Docker Buildx
110+
uses: docker/setup-buildx-action@v2
111+
- name: Login to Docker Hub
112+
uses: docker/login-action@v2
113+
with:
114+
username: ${{ secrets.DOCKERHUB_USERNAME }}
115+
password: ${{ secrets.DOCKERHUB_TOKEN }}
116+
- name: Configure AWS credentials
117+
uses: aws-actions/configure-aws-credentials@v4
118+
with:
119+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
120+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
121+
aws-region: ${{ env.AWS_REGION }}
122+
- name: Login to Amazon ECR
123+
id: login-ecr
124+
uses: aws-actions/amazon-ecr-login@v2
125+
- name: check repo and create it if not exist
126+
env:
127+
REPOSITORY: blob-uploader
128+
run: |
129+
aws --region ${{ env.AWS_REGION }} ecr describe-repositories --repository-names ${{ env.REPOSITORY }} && : || aws --region ${{ env.AWS_REGION }} ecr create-repository --repository-name ${{ env.REPOSITORY }}
130+
- name: Build and push
131+
uses: docker/build-push-action@v3
132+
env:
133+
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
134+
REPOSITORY: blob-uploader
135+
IMAGE_TAG: ${{ github.ref_name }}
136+
with:
137+
context: .
138+
file: ./build/dockerfiles/blob_uploader.Dockerfile
139+
platforms: linux/amd64,linux/arm64
140+
push: true
141+
tags: |
142+
scrolltech/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
143+
scrolltech/${{ env.REPOSITORY }}:latest
144+
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
145+
${{ env.ECR_REGISTRY }}/${{ env.REPOSITORY }}:latest
146+
102147
rollup-db-cli:
103148
runs-on: ubuntu-latest
104149
steps:
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Download Go dependencies
2+
FROM scrolltech/go-rust-builder:go-1.22-rust-nightly-2023-12-03 as base
3+
4+
WORKDIR /src
5+
COPY go.work* ./
6+
COPY ./rollup/go.* ./rollup/
7+
COPY ./common/go.* ./common/
8+
COPY ./coordinator/go.* ./coordinator/
9+
COPY ./database/go.* ./database/
10+
COPY ./tests/integration-test/go.* ./tests/integration-test/
11+
COPY ./bridge-history-api/go.* ./bridge-history-api/
12+
RUN go mod download -x
13+
14+
# Build blob_uploader
15+
FROM base as builder
16+
17+
RUN --mount=target=. \
18+
--mount=type=cache,target=/root/.cache/go-build \
19+
cd /src/rollup/cmd/blob_uploader/ && CGO_LDFLAGS="-ldl" go build -v -p 4 -o /bin/blob_uploader
20+
21+
# Pull blob_uploader into a second stage deploy ubuntu container
22+
FROM ubuntu:20.04
23+
24+
RUN apt update && apt install vim netcat-openbsd net-tools curl ca-certificates -y
25+
26+
ENV CGO_LDFLAGS="-ldl"
27+
28+
COPY --from=builder /bin/blob_uploader /bin/
29+
WORKDIR /app
30+
ENTRYPOINT ["blob_uploader"]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
assets/
2+
docs/
3+
l2geth/
4+
rpc-gateway/
5+
*target/*

common/testdata/blobdata.json

Lines changed: 4 additions & 0 deletions
Large diffs are not rendered by default.

common/types/db.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,53 @@ func (s TxStatus) String() string {
326326
return fmt.Sprintf("Unknown TxStatus (%d)", int32(s))
327327
}
328328
}
329+
330+
// BlobUploadStatus represents the status of a blob upload
331+
type BlobUploadStatus int
332+
333+
const (
334+
// BlobUploadStatusUndefined indicates an undefined status
335+
BlobUploadStatusUndefined BlobUploadStatus = iota
336+
// BlobUploadStatusPending indicates a pending upload status
337+
BlobUploadStatusPending
338+
// BlobUploadStatusUploaded indicates a successful upload status
339+
BlobUploadStatusUploaded
340+
// BlobUploadStatusFailed indicates a failed upload status
341+
BlobUploadStatusFailed
342+
)
343+
344+
func (s BlobUploadStatus) String() string {
345+
switch s {
346+
case BlobUploadStatusPending:
347+
return "BlobUploadStatusPending"
348+
case BlobUploadStatusUploaded:
349+
return "BlobUploadStatusUploaded"
350+
case BlobUploadStatusFailed:
351+
return "BlobUploadStatusFailed"
352+
default:
353+
return fmt.Sprintf("Unknown BlobUploadStatus (%d)", int32(s))
354+
}
355+
}
356+
357+
// BlobStoragePlatform represents the platform a blob upload to
358+
type BlobStoragePlatform int
359+
360+
const (
361+
// BlobStoragePlatformUndefined indicates an undefined platform
362+
BlobStoragePlatformUndefined BlobStoragePlatform = iota
363+
// BlobStoragePlatformS3 represents AWS S3
364+
BlobStoragePlatformS3
365+
// BlobStoragePlatformArweave represents storage blockchain Arweave
366+
BlobStoragePlatformArweave
367+
)
368+
369+
func (s BlobStoragePlatform) String() string {
370+
switch s {
371+
case BlobStoragePlatformS3:
372+
return "BlobStoragePlatformS3"
373+
case BlobStoragePlatformArweave:
374+
return "BlobStoragePlatformArweave"
375+
default:
376+
return fmt.Sprintf("Unknown BlobStoragePlatform (%d)", int32(s))
377+
}
378+
}

common/utils/blob.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package utils
2+
3+
import (
4+
"crypto/sha256"
5+
"fmt"
6+
7+
"github.com/scroll-tech/go-ethereum/crypto/kzg4844"
8+
)
9+
10+
// CalculateVersionedBlobHash calculate the kzg4844 versioned blob hash from a blob
11+
func CalculateVersionedBlobHash(blob kzg4844.Blob) ([32]byte, error) {
12+
// calculate kzg4844 commitment from blob
13+
commit, err := kzg4844.BlobToCommitment(&blob)
14+
if err != nil {
15+
return [32]byte{}, fmt.Errorf("failed to get blob commitment, err: %w", err)
16+
}
17+
18+
// calculate kzg4844 versioned blob hash from blob commitment
19+
hasher := sha256.New()
20+
vh := kzg4844.CalcBlobHashV1(hasher, &commit)
21+
22+
return vh, nil
23+
}

common/utils/blob_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package utils
2+
3+
import (
4+
"encoding/hex"
5+
"encoding/json"
6+
"os"
7+
"testing"
8+
9+
"github.com/scroll-tech/go-ethereum/crypto/kzg4844"
10+
)
11+
12+
type BlobData struct {
13+
VersionedBlobHash string `json:"versionedBlobHash"`
14+
BlobData string `json:"blobData"`
15+
}
16+
17+
// TestCalculateVersionedBlobHash tests the CalculateVersionedBlobHash function
18+
func TestCalculateVersionedBlobHash(t *testing.T) {
19+
// Read the test data
20+
data, err := os.ReadFile("../testdata/blobdata.json")
21+
if err != nil {
22+
t.Fatalf("Failed to read blobdata.json: %v", err)
23+
}
24+
25+
var blobData BlobData
26+
if err := json.Unmarshal(data, &blobData); err != nil {
27+
t.Fatalf("Failed to parse blobdata.json: %v", err)
28+
}
29+
30+
blobBytes, err := hex.DecodeString(blobData.BlobData)
31+
if err != nil {
32+
t.Fatalf("Failed to decode blob data: %v", err)
33+
}
34+
35+
// Convert []byte to kzg4844.Blob
36+
var blob kzg4844.Blob
37+
copy(blob[:], blobBytes)
38+
39+
// Calculate the hash
40+
calculatedHashBytes, err := CalculateVersionedBlobHash(blob)
41+
if err != nil {
42+
t.Fatalf("Failed to calculate versioned blob hash: %v", err)
43+
}
44+
45+
calculatedHash := hex.EncodeToString(calculatedHashBytes[:])
46+
47+
if calculatedHash != blobData.VersionedBlobHash {
48+
t.Fatalf("Hash mismatch: got %s, want %s", calculatedHash, blobData.VersionedBlobHash)
49+
}
50+
51+
}

common/version/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"runtime/debug"
66
)
77

8-
var tag = "v4.5.21"
8+
var tag = "v4.5.22"
99

1010
var commit = func() string {
1111
if info, ok := debug.ReadBuildInfo(); ok {

coordinator/internal/types/prover.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package types
22

33
import (
44
"fmt"
5+
56
"scroll-tech/common/types/message"
67
)
78

database/migrate/migrate_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,20 @@ func testResetDB(t *testing.T) {
5959
cur, err := Current(pgDB)
6060
assert.NoError(t, err)
6161
// total number of tables.
62-
assert.Equal(t, int64(26), cur)
62+
assert.Equal(t, int64(27), cur)
6363
}
6464

6565
func testMigrate(t *testing.T) {
6666
assert.NoError(t, Migrate(pgDB))
6767
cur, err := Current(pgDB)
6868
assert.NoError(t, err)
69-
assert.Equal(t, int64(26), cur)
69+
assert.Equal(t, int64(27), cur)
7070
}
7171

7272
func testRollback(t *testing.T) {
7373
version, err := Current(pgDB)
7474
assert.NoError(t, err)
75-
assert.Equal(t, int64(26), version)
75+
assert.Equal(t, int64(27), version)
7676

7777
assert.NoError(t, Rollback(pgDB, nil))
7878

0 commit comments

Comments
 (0)