Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,30 @@ on:
workflow_call:

jobs:
build_testapp:
name: Build Test App
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: set up go
uses: actions/setup-go@v5
with:
go-version-file: ./go.mod
- name: Build test app
run: make build

build_evm-single:
name: Build EVM Single App
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: set up go
uses: actions/setup-go@v5
with:
go-version-file: ./go.mod
- name: Build evm single sequencer app
run: make build-evm-single

go_mod_tidy_check:
name: Go Mod Tidy Check
runs-on: ubuntu-latest
Expand All @@ -13,7 +37,7 @@ jobs:
- uses: actions/setup-go@v5
with:
go-version-file: ./go.mod
- run: go mod tidy
- run: make tidy-all
- name: check for diff
run: git diff --exit-code

Expand Down
2 changes: 1 addition & 1 deletion block/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -1034,7 +1034,7 @@ func (m *Manager) processNextDAHeader(ctx context.Context) error {
}
err = header.FromProto(&headerPb)
if err != nil {
m.logger.Error("failed to unmarshal header", "error", err)
m.logger.Error("failed to create local header", "error", err)
continue
}
// early validation to reject junk headers
Expand Down
36 changes: 31 additions & 5 deletions da/cmd/local-da/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"sync"
"time"

"cosmossdk.io/log"
coreda "github.com/rollkit/rollkit/core/da"
"github.com/rollkit/rollkit/da"
)
Expand All @@ -31,51 +32,60 @@ type LocalDA struct {
height uint64
privKey ed25519.PrivateKey
pubKey ed25519.PublicKey

logger log.Logger
}

type kvp struct {
key, value []byte
}

// NewLocalDA create new instance of DummyDA
func NewLocalDA(opts ...func(*LocalDA) *LocalDA) *LocalDA {
func NewLocalDA(logger log.Logger, opts ...func(*LocalDA) *LocalDA) *LocalDA {
da := &LocalDA{
mu: new(sync.Mutex),
data: make(map[uint64][]kvp),
timestamps: make(map[uint64]time.Time),
maxBlobSize: DefaultMaxBlobSize,
logger: logger.With("module", "local-da"),
}
for _, f := range opts {
da = f(da)
}
da.pubKey, da.privKey, _ = ed25519.GenerateKey(rand.Reader)
da.logger.Info("NewLocalDA: initialized LocalDA")
return da
}

var _ coreda.DA = &LocalDA{}

// MaxBlobSize returns the max blob size in bytes.
func (d *LocalDA) MaxBlobSize(ctx context.Context) (uint64, error) {
d.logger.Debug("MaxBlobSize called", "maxBlobSize", d.maxBlobSize)
return d.maxBlobSize, nil
}

// GasMultiplier returns the gas multiplier.
func (d *LocalDA) GasMultiplier(ctx context.Context) (float64, error) {
d.logger.Debug("GasMultiplier called")
return 1.0, nil
}

// GasPrice returns the gas price.
func (d *LocalDA) GasPrice(ctx context.Context) (float64, error) {
d.logger.Debug("GasPrice called")
return 0.0, nil
}

// Get returns Blobs for given IDs.
func (d *LocalDA) Get(ctx context.Context, ids []coreda.ID, _ []byte) ([]coreda.Blob, error) {
d.logger.Debug("Get called", "ids", ids)
d.mu.Lock()
defer d.mu.Unlock()
blobs := make([]coreda.Blob, len(ids))
for i, id := range ids {
if len(id) < 8 {
d.logger.Error("Get: invalid ID length", "id", id)
return nil, errors.New("invalid ID")
}
height := binary.LittleEndian.Uint64(id)
Expand All @@ -87,60 +97,72 @@ func (d *LocalDA) Get(ctx context.Context, ids []coreda.ID, _ []byte) ([]coreda.
}
}
if !found {
d.logger.Warn("Get: blob not found", "id", id, "height", height)
return nil, da.ErrBlobNotFound
}
}
d.logger.Debug("Get successful", "count", len(blobs))
return blobs, nil
}

// GetIDs returns IDs of Blobs at given DA height.
func (d *LocalDA) GetIDs(ctx context.Context, height uint64, _ []byte) (*coreda.GetIDsResult, error) {
d.logger.Debug("GetIDs called", "height", height)
d.mu.Lock()
defer d.mu.Unlock()

if height > d.height {
d.logger.Error("GetIDs: height in future", "requested", height, "current", d.height)
return nil, fmt.Errorf("height %d is in the future: %w", height, da.ErrFutureHeight)
}

kvps, ok := d.data[height]
if !ok {
d.logger.Debug("GetIDs: no data for height", "height", height)
return nil, nil
}

ids := make([]coreda.ID, len(kvps))
for i, kv := range kvps {
ids[i] = kv.key
}
d.logger.Debug("GetIDs successful", "count", len(ids))
return &coreda.GetIDsResult{IDs: ids, Timestamp: d.timestamps[height]}, nil
}

// GetProofs returns inclusion Proofs for all Blobs located in DA at given height.
func (d *LocalDA) GetProofs(ctx context.Context, ids []coreda.ID, _ []byte) ([]coreda.Proof, error) {
d.logger.Debug("GetProofs called", "ids", ids)
blobs, err := d.Get(ctx, ids, nil)

d.mu.Lock()
defer d.mu.Unlock()
if err != nil {
d.logger.Error("GetProofs: failed to get blobs", "error", err)
return nil, err
}

d.mu.Lock()
defer d.mu.Unlock()
proofs := make([]coreda.Proof, len(blobs))
for i, blob := range blobs {
proofs[i] = d.getProof(ids[i], blob)
}
d.logger.Debug("GetProofs successful", "count", len(proofs))
return proofs, nil
}

// Commit returns cryptographic Commitments for given blobs.
func (d *LocalDA) Commit(ctx context.Context, blobs []coreda.Blob, _ []byte) ([]coreda.Commitment, error) {
d.logger.Debug("Commit called", "numBlobs", len(blobs))
commits := make([]coreda.Commitment, len(blobs))
for i, blob := range blobs {
commits[i] = d.getHash(blob)
}
d.logger.Debug("Commit successful", "count", len(commits))
return commits, nil
}

// SubmitWithOptions stores blobs in DA layer (options are ignored).
func (d *LocalDA) Submit(ctx context.Context, blobs []coreda.Blob, gasPrice float64, _ []byte, _ []byte) ([]coreda.ID, error) {
d.logger.Info("Submit called", "numBlobs", len(blobs), "gasPrice", gasPrice)
d.mu.Lock()
defer d.mu.Unlock()
ids := make([]coreda.ID, len(blobs))
Expand All @@ -151,19 +173,23 @@ func (d *LocalDA) Submit(ctx context.Context, blobs []coreda.Blob, gasPrice floa

d.data[d.height] = append(d.data[d.height], kvp{ids[i], blob})
}

d.logger.Info("Submit successful", "newHeight", d.height, "count", len(ids))
return ids, nil
}

// Validate checks the Proofs for given IDs.
func (d *LocalDA) Validate(ctx context.Context, ids []coreda.ID, proofs []coreda.Proof, _ []byte) ([]bool, error) {
d.logger.Debug("Validate called", "numIDs", len(ids), "numProofs", len(proofs))
if len(ids) != len(proofs) {
d.logger.Error("Validate: id/proof count mismatch", "ids", len(ids), "proofs", len(proofs))
return nil, errors.New("number of IDs doesn't equal to number of proofs")
}
results := make([]bool, len(ids))
for i := 0; i < len(ids); i++ {
results[i] = ed25519.Verify(d.pubKey, ids[i][8:], proofs[i])
d.logger.Debug("Validate result", "id", ids[i], "result", results[i])
}
d.logger.Debug("Validate finished", "results", results)
return results, nil
}

Expand Down
12 changes: 8 additions & 4 deletions da/cmd/local-da/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import (
"context"
"flag"
"fmt"
"log"

"os"
"os/signal"
"syscall"

"cosmossdk.io/log"

proxy "github.com/rollkit/rollkit/da/proxy/jsonrpc"
)

Expand All @@ -32,12 +34,14 @@ func main() {
host = "0.0.0.0"
}

da := NewLocalDA()
// create logger
logger := log.NewLogger(os.Stdout).With("module", "da")
da := NewLocalDA(logger)

srv := proxy.NewServer(host, port, da)
log.Printf("Listening on: %s:%s", host, port)
logger.Info("Listening on: %s:%s", host, port)
if err := srv.Start(context.Background()); err != nil {
log.Fatal("error while serving:", err)
logger.Info("error while serving:", err)
}

interrupt := make(chan os.Signal, 1)
Expand Down
6 changes: 3 additions & 3 deletions da/da.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (dac *DAClient) Submit(ctx context.Context, data [][]byte, maxBlobSize uint
return coreda.ResultSubmit{
BaseResult: coreda.BaseResult{
Code: coreda.StatusError,
Message: "failed to submit headers: no blobs generated " + message,
Message: "failed to submit blobs: no blobs generated " + message,
},
}
}
Expand All @@ -96,7 +96,7 @@ func (dac *DAClient) Submit(ctx context.Context, data [][]byte, maxBlobSize uint
return coreda.ResultSubmit{
BaseResult: coreda.BaseResult{
Code: status,
Message: "failed to submit headers: " + err.Error(),
Message: "failed to submit blobs: " + err.Error(),
},
}
}
Expand All @@ -105,7 +105,7 @@ func (dac *DAClient) Submit(ctx context.Context, data [][]byte, maxBlobSize uint
return coreda.ResultSubmit{
BaseResult: coreda.BaseResult{
Code: coreda.StatusError,
Message: "failed to submit headers: unexpected len(ids): 0",
Message: "failed to submit blobs: unexpected len(ids): 0",
},
}
}
Expand Down
Loading
Loading