Skip to content

Commit

Permalink
Major refactor into library + server (#3)
Browse files Browse the repository at this point in the history
* refactor: into library pkgs with a command pkg

* fix: celestia dependency mismatch

* refactor: availda for external use

* feat(daash): Add DA Manager to manage/init clients

* fix(daash): map allocation

* docs(cmd): Add run instructions

- go mod tidy
  • Loading branch information
0xRampey committed Mar 16, 2024
1 parent 410786f commit 53e55fa
Show file tree
Hide file tree
Showing 11 changed files with 323 additions and 257 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
.env
/.env
./cmd/blob-server/avail-config.json

19 changes: 8 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,14 @@ Each micro-rollup should be easily able to switch

### Steps to run

1. Clone the repository
2.
```bash
git clone https://github.com/stackrlabs/go-daash # clone the repository
cd go-daash/cmd/blob-server
go run . # run the server
curl --location 'localhost:8080/eigen' \
--header 'Content-Type: application/json' \
--data 'gm' # DAash away!
```

### Additional requirements

Expand All @@ -53,12 +59,3 @@ You need an auth token to run your Celestia light node. Copy the `.env.example`
cp .env.example .env
```

## Installation/Running

```bash
go build .
go run .
curl --location 'localhost:8080/Celestia' \
--header 'Content-Type: application/json' \
--data 'gm'
```
41 changes: 19 additions & 22 deletions avail.go → availda/availda.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package availda

import (
"context"
Expand All @@ -23,10 +23,6 @@ import (
"golang.org/x/crypto/sha3"
)

type DAClient interface {
PostData(txData []byte) (*BatchDAData, error)
}

type AccountNextIndexRPCResponse struct {
Result uint `json:"result"`
}
Expand Down Expand Up @@ -55,7 +51,7 @@ type DataProof struct {
Leaf string `json:"leaf"`
}

type AvailDA struct {
type DAClient struct {
config Config
API *gsrpc.SubstrateAPI
Meta *types.Metadata
Expand All @@ -67,9 +63,10 @@ type AvailDA struct {
DestinationDomain types.UCompact
}

func NewAvailDA() (*AvailDA, error) {
a := AvailDA{}
err := a.config.GetConfig("./avail-config.json")
// Returns a newly initalised Avail DA client
func New(configPath string) (*DAClient, error) {
a := DAClient{}
err := a.config.GetConfig(configPath)
if err != nil {
return nil, fmt.Errorf("cannot get config", err)
}
Expand Down Expand Up @@ -122,14 +119,14 @@ func NewAvailDA() (*AvailDA, error) {
}

// MaxBlobSize returns the max blob size
func (c *AvailDA) MaxBlobSize(ctx context.Context) (uint64, error) {
func (c *DAClient) MaxBlobSize(ctx context.Context) (uint64, error) {
var maxBlobSize uint64 = 64 * 64 * 500
return maxBlobSize, nil
}

// Submit a list of blobs to Avail DA
// Currently, we submit to a trusted RPC Avail node. In the future, we will submit via an Avail light client.
func (a *AvailDA) Submit(ctx context.Context, daBlobs []da.Blob, gasPrice float64) ([]da.ID, []da.Proof, error) {
func (a *DAClient) Submit(ctx context.Context, daBlobs []da.Blob, gasPrice float64) ([]da.ID, []da.Proof, error) {
// TODO: Add support for multiple blobs
daBlob := daBlobs[0]
log.Println("data", zap.Any("data", daBlob))
Expand Down Expand Up @@ -241,7 +238,7 @@ out:
dataProof := dataProofResp.Result.DataProof

// NOTE: Substrate's BlockNumber type is an alias for u32 type, which is uint32
blobID := a.makeID(uint32(block.Block.Header.Number), uint32(dataProof.LeafIndex))
blobID := makeID(uint32(block.Block.Header.Number), uint32(dataProof.LeafIndex))
blobIDs := make([]da.ID, 1)
blobIDs[0] = blobID

Expand All @@ -255,9 +252,9 @@ out:
}

// Get returns Blob for each given ID, or an error.
func (a *AvailDA) Get(ctx context.Context, ids []da.ID) ([]da.Blob, error) {
func (a *DAClient) Get(ctx context.Context, ids []da.ID) ([]da.Blob, error) {
// TODO: We are dealing with single blobs for now. We will need to handle multiple blobs in the future.
blockHeight, leafIndex := a.splitID(ids[0])
blockHeight, leafIndex := SplitID(ids[0])
data, err := a.GetData(uint64(blockHeight), uint(leafIndex))
if err != nil {
return nil, fmt.Errorf("cannot get data", err)
Expand All @@ -267,19 +264,19 @@ func (a *AvailDA) Get(ctx context.Context, ids []da.ID) ([]da.Blob, error) {
}

// GetIDs returns IDs of all Blobs located in DA at given height.
func (a *AvailDA) GetIDs(ctx context.Context, height uint64) ([]da.ID, error) {
func (a *DAClient) GetIDs(ctx context.Context, height uint64) ([]da.ID, error) {
// TODO: Need to implement this
return nil, nil
}

// Commit creates a Commitment for each given Blob.
func (a *AvailDA) Commit(ctx context.Context, daBlobs []da.Blob) ([]da.Commitment, error) {
func (a *DAClient) Commit(ctx context.Context, daBlobs []da.Blob) ([]da.Commitment, error) {
// TODO: Need to implement this
return nil, nil
}

// Validate validates Commitments against the corresponding Proofs. This should be possible without retrieving the Blobs.
func (c *AvailDA) Validate(ctx context.Context, ids []da.ID, daProofs []da.Proof) ([]bool, error) {
func (c *DAClient) Validate(ctx context.Context, ids []da.ID, daProofs []da.Proof) ([]bool, error) {
// TODO: Need to implement this
return nil, nil
}
Expand All @@ -295,7 +292,7 @@ func (b BatchDAData) IsEmpty() bool {
return reflect.DeepEqual(b, BatchDAData{})
}

func (a AvailDA) GetAccountNextIndex() (types.UCompact, error) {
func (a *DAClient) GetAccountNextIndex() (types.UCompact, error) {
// TODO: Add context to the request
resp, err := http.Post("https://goldberg.avail.tools/api", "application/json", strings.NewReader(fmt.Sprintf("{\"id\":1,\"jsonrpc\":\"2.0\",\"method\":\"system_accountNextIndex\",\"params\":[\"%v\"]}", a.KeyringPair.Address))) //nolint: noctx
if err != nil {
Expand All @@ -318,7 +315,7 @@ func (a AvailDA) GetAccountNextIndex() (types.UCompact, error) {
}

// makeID creates a unique ID to reference a blob on Avail
func (a *AvailDA) makeID(blockHeight uint32, leafIndex uint32) da.ID {
func makeID(blockHeight uint32, leafIndex uint32) da.ID {
// Serialise height and leaf index to binary
heightLen := 4
leafIndexLen := 4
Expand All @@ -330,8 +327,8 @@ func (a *AvailDA) makeID(blockHeight uint32, leafIndex uint32) da.ID {
return da.ID(idBytes)
}

// splitID returns the block height and leaf index from a unique ID
func (a *AvailDA) splitID(id da.ID) (uint32, uint32) {
// SplitID returns the block height and leaf index from a unique ID
func SplitID(id da.ID) (uint32, uint32) {
heightLen := 4
leafIndexLen := 4
heightBytes := id[:heightLen]
Expand All @@ -341,7 +338,7 @@ func (a *AvailDA) splitID(id da.ID) (uint32, uint32) {
return blockHeight, leafIndex
}

func (a AvailDA) GetData(blockNumber uint64, index uint) ([]byte, error) {
func (a *DAClient) GetData(blockNumber uint64, index uint) ([]byte, error) {
blockHash, err := a.API.RPC.Chain.GetBlockHash(blockNumber)
if err != nil {
return nil, fmt.Errorf("cannot get block hash", err)
Expand Down
6 changes: 2 additions & 4 deletions celestia.go → celestiada/celestia.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package celestiada

import (
"context"
Expand Down Expand Up @@ -28,7 +28,7 @@ type CelestiaDA struct {
}

// NewCelestiaDA returns an instance of CelestiaDA
func NewCelestiaDA(client *rpc.Client, namespace share.Namespace, gasPrice float64, ctx context.Context) *CelestiaDA {
func NewClient(client *rpc.Client, namespace share.Namespace, gasPrice float64, ctx context.Context) *CelestiaDA {
return &CelestiaDA{
client: client,
namespace: namespace,
Expand Down Expand Up @@ -181,5 +181,3 @@ func splitID(id da.ID) (uint64, da.Commitment) {
}
return binary.LittleEndian.Uint64(id[:heightLen]), id[heightLen:]
}

var _ da.DA = &CelestiaDA{}
15 changes: 9 additions & 6 deletions main.go → cmd/blob-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ import (
rpc "github.com/celestiaorg/celestia-node/api/rpc/client"
"github.com/celestiaorg/celestia-node/share"
"github.com/joho/godotenv"
"github.com/rollkit/go-da"

"github.com/cenkalti/backoff/v4"
"github.com/gin-gonic/gin"
"github.com/rollkit/go-da"
"github.com/stackrlabs/go-daash/availda"
"github.com/stackrlabs/go-daash/celestiada"
"github.com/stackrlabs/go-daash/eigenda"
)

// Constants
Expand All @@ -28,15 +31,15 @@ func main() {
router := gin.Default()
ctx := context.Background()

envFile, err := godotenv.Read(".env")
envFile, err := godotenv.Read("../../.env") // read from root
if err != nil {
fmt.Println("Error reading .env file")

return
}

// Initialise Avail DA client
avail, err := NewAvailDA()
avail, err := availda.New("./avail-config.json")
if err != nil {
fmt.Printf("failed to create avail client: %v", err)
}
Expand All @@ -60,10 +63,10 @@ func main() {
log.Fatalln("invalid hex value of a namespace:", err)
}
namespace, err := share.NewBlobNamespaceV0(nsBytes)
celestia := NewCelestiaDA(client, namespace, -1, ctx)
celestia := celestiada.NewClient(client, namespace, -1, ctx)

// Initalise EigenDA client
eigen, err := NewEigendaDAClient(EigenDaRpcUrl, time.Second*90, time.Second*5)
eigen, err := eigenda.New(EigenDaRpcUrl, time.Second*90, time.Second*5)
if err != nil {
fmt.Printf("failed to create eigen client: %v", err)
}
Expand Down Expand Up @@ -103,7 +106,7 @@ func main() {
return
}
c.JSON(http.StatusOK, gin.H{
"message": "DAaaaSh",
"message": "Blob daashed and posted to " + daName + " 🏃",
"ids": ids,
"proofs": proofs,
})
Expand Down
48 changes: 48 additions & 0 deletions daash.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package daash

import (
"time"

"github.com/cenkalti/backoff"
"github.com/rollkit/go-da"
"github.com/stackrlabs/go-daash/availda"
"github.com/stackrlabs/go-daash/eigenda"
)

type DAType string

const (
Avail DAType = "avail"
Eigen DAType = "eigen"
)

type DAManager struct {
Clients map[DAType]da.DA
}

// Initialize all the DA clients
func (d *DAManager) Init(availConfigPath string) error {
d.Clients = make(map[DAType]da.DA)
var err error
// Initialize Avail
var avail da.DA
err = backoff.Retry(func() error {
avail, err = availda.New(availConfigPath)
return err //nolint: wrapcheck
}, backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 5))
if err != nil {
return err
}
d.Clients[Avail] = avail

// Initialize Eigen
eigen, err := eigenda.New("disperser-goerli.eigenda.xyz:443", time.Second*90, time.Second*5)
if err != nil {
return err
}
d.Clients[Eigen] = eigen

// TODO: Initialize Celestia

return nil
}
2 changes: 1 addition & 1 deletion disperser.pb.go → eigenda/disperser.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion disperser_grpc.pb.go → eigenda/disperser_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 53e55fa

Please sign in to comment.