Skip to content

Commit

Permalink
added avail da
Browse files Browse the repository at this point in the history
  • Loading branch information
chandiniv1 committed Aug 23, 2023
1 parent 3ae761f commit 869ddff
Show file tree
Hide file tree
Showing 5 changed files with 367 additions and 7 deletions.
227 changes: 227 additions & 0 deletions da/avail/avail.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
package avail

import (
"context"
"encoding/json"
"fmt"
"io/ioutil"

Check failure on line 7 in da/avail/avail.go

View workflow job for this annotation

GitHub Actions / lint / golangci-lint

SA1019: "io/ioutil" has been deprecated since Go 1.19: As of Go 1.16, the same functionality is now provided by package io or package os, and those implementations should be preferred in new code. See the specific function documentation for details. (staticcheck)
"net/http"
"strings"

ds "github.com/ipfs/go-datastore"

Check failure on line 11 in da/avail/avail.go

View workflow job for this annotation

GitHub Actions / lint / golangci-lint

File is not `goimports`-ed with -local github.com/rollkit (goimports)
"github.com/rollkit/rollkit/da"
"github.com/rollkit/rollkit/da/avail/datasubmit"
"github.com/rollkit/rollkit/log"
"github.com/rollkit/rollkit/types"
)

type Config struct {
BaseURL string `json:"base_url"`
Seed string `json:"seed"`
ApiURL string `json:"api_url"`
AppID int `json:"app_id"`
confidence float64 `json:"confidence"`

Check failure on line 23 in da/avail/avail.go

View workflow job for this annotation

GitHub Actions / lint / golangci-lint

structtag: struct field confidence has json tag but is not exported (govet)

Check failure on line 23 in da/avail/avail.go

View workflow job for this annotation

GitHub Actions / test / Run Unit Tests

struct field confidence has json tag but is not exported
}

type DataAvailabilityLayerClient struct {
namespace types.NamespaceID

Check failure on line 27 in da/avail/avail.go

View workflow job for this annotation

GitHub Actions / lint / golangci-lint

`namespace` is unused (structcheck)
config Config
logger log.Logger
}

type Confidence struct {
Block uint32 `json:"block"`
Confidence float64 `json:"confidence"`
SerialisedConfidence *string `json:"serialised_confidence,omitempty"`
}

type AppData struct {
Block uint32 `json:"block"`
Extrinsics []string `json:"extrinsics"`
}

var _ da.DataAvailabilityLayerClient = &DataAvailabilityLayerClient{}
var _ da.BlockRetriever = &DataAvailabilityLayerClient{}

// Init initializes DataAvailabilityLayerClient instance.
func (c *DataAvailabilityLayerClient) Init(namespaceID types.NamespaceID, config []byte, kvStore ds.Datastore, logger log.Logger) error {
c.logger = logger

if len(config) > 0 {
return json.Unmarshal(config, &c.config)
}

return nil
}

// Start prepares DataAvailabilityLayerClient to work.
func (c *DataAvailabilityLayerClient) Start() error {

c.logger.Info("starting avail Data Availability Layer Client", "baseURL", c.config.ApiURL)

return nil
}

// Stop stops DataAvailabilityLayerClient.
func (c *DataAvailabilityLayerClient) Stop() error {

c.logger.Info("stopping Avail Data Availability Layer Client")

return nil
}

// SubmitBlock submits a block to DA layer.
func (c *DataAvailabilityLayerClient) SubmitBlocks(ctx context.Context, blocks []*types.Block) da.ResultSubmitBlocks {

for _, block := range blocks {
data, err := block.MarshalBinary()
if err != nil {
return da.ResultSubmitBlocks{
BaseResult: da.BaseResult{
Code: da.StatusError,
Message: err.Error(),
},
}
}
err = datasubmit.SubmitData(c.config.ApiURL, c.config.Seed, c.config.AppID, data)

if err != nil {
return da.ResultSubmitBlocks{
BaseResult: da.BaseResult{
Code: da.StatusError,
Message: err.Error(),
},
}
}
}

return da.ResultSubmitBlocks{
BaseResult: da.BaseResult{
Code: da.StatusSuccess,
Message: "data submitted succesfully",

Check failure on line 101 in da/avail/avail.go

View workflow job for this annotation

GitHub Actions / lint / golangci-lint

`succesfully` is a misspelling of `successfully` (misspell)
DAHeight: 1,
},
}

}

// CheckBlockAvailability queries DA layer to check data availability of block.
func (c *DataAvailabilityLayerClient) CheckBlockAvailability(ctx context.Context, dataLayerHeight uint64) da.ResultCheckBlock {

blockNumber := dataLayerHeight
confidenceURL := fmt.Sprintf(c.config.BaseURL+"/confidence/%d", blockNumber)

response, err := http.Get(confidenceURL)

Check failure on line 114 in da/avail/avail.go

View workflow job for this annotation

GitHub Actions / lint / golangci-lint

G107: Potential HTTP request made with variable url (gosec)

if err != nil {
return da.ResultCheckBlock{
BaseResult: da.BaseResult{
Code: da.StatusError,
Message: err.Error(),
},
}
}

responseData, err := ioutil.ReadAll(response.Body)
if err != nil {
return da.ResultCheckBlock{
BaseResult: da.BaseResult{
Code: da.StatusError,
Message: err.Error(),
},
}
}

var confidenceObject Confidence
err = json.Unmarshal(responseData, &confidenceObject)
if err != nil {
return da.ResultCheckBlock{
BaseResult: da.BaseResult{
Code: da.StatusError,
Message: err.Error(),
},
}
}

return da.ResultCheckBlock{
BaseResult: da.BaseResult{
Code: da.StatusSuccess,
DAHeight: uint64(confidenceObject.Block),
},
DataAvailable: confidenceObject.Confidence > float64(c.config.confidence),
}
}

//RetrieveBlocks gets the block from DA layer.

func (c *DataAvailabilityLayerClient) RetrieveBlocks(ctx context.Context, dataLayerHeight uint64) da.ResultRetrieveBlocks {

blocks := []*types.Block{}

blockNumber := dataLayerHeight

appDataURL := fmt.Sprintf(c.config.BaseURL+"/appdata/%d?decode=true", blockNumber)

response, err := http.Get(appDataURL)

Check failure on line 165 in da/avail/avail.go

View workflow job for this annotation

GitHub Actions / lint / golangci-lint

G107: Potential HTTP request made with variable url (gosec)
if err != nil {
return da.ResultRetrieveBlocks{
BaseResult: da.BaseResult{
Code: da.StatusError,
Message: err.Error(),
},
}
}

responseData, err := ioutil.ReadAll(response.Body)
if err != nil {
return da.ResultRetrieveBlocks{
BaseResult: da.BaseResult{
Code: da.StatusError,
Message: err.Error(),
},
}
}

var appDataObject AppData
err = json.Unmarshal(responseData, &appDataObject)
if err != nil {
return da.ResultRetrieveBlocks{
BaseResult: da.BaseResult{
Code: da.StatusError,
Message: err.Error(),
},
}
}

txnsByteArray := []byte{}
for _, extrinsic := range appDataObject.Extrinsics {
txnsByteArray = append(txnsByteArray, []byte(extrinsic)...)
}

block := &types.Block{
SignedHeader: types.SignedHeader{
Header: types.Header{
BaseHeader: types.BaseHeader{
Height: blockNumber,
},
AggregatorsHash: make([]byte, 32),
}},
Data: types.Data{
Txs: types.Txs{txnsByteArray},
IntermediateStateRoots: types.IntermediateStateRoots{
RawRootsList: nil,
},
},
}

blocks = append(blocks, block)

return da.ResultRetrieveBlocks{
BaseResult: da.BaseResult{
Code: da.StatusSuccess,
DAHeight: uint64(appDataObject.Block),
Message: "block data: " + strings.Join(appDataObject.Extrinsics, " "),
},
Blocks: blocks,
}
}
89 changes: 89 additions & 0 deletions da/avail/datasubmit/submitdata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package datasubmit

import (
"errors"

gsrpc "github.com/centrifuge/go-substrate-rpc-client/v4"
"github.com/centrifuge/go-substrate-rpc-client/v4/signature"
"github.com/centrifuge/go-substrate-rpc-client/v4/types"
)

// submit data submits the extrinsic through substrate api
func SubmitData(apiURL string, seed string, appID int, data []byte) error {
api, err := gsrpc.NewSubstrateAPI(apiURL)
if err != nil {
return err
}

meta, err := api.RPC.State.GetMetadataLatest()
if err != nil {
return err
}

//if app id is greater than 0 then it must be created before submitting data
err = errors.New("AppID cant be 0")
if appID == 0 {
return err
}

c, err := types.NewCall(meta, "DataAvailability.submit_data", data)
if err != nil {
return err
}

//Create the extrinsic
ext := types.NewExtrinsic(c)

genesisHash, err := api.RPC.Chain.GetBlockHash(0)
if err != nil {
return err
}

rv, err := api.RPC.State.GetRuntimeVersionLatest()
if err != nil {
return err
}

keyringPair, err := signature.KeyringPairFromSecret(seed, 42)
if err != nil {
return err
}

key, err := types.CreateStorageKey(meta, "System", "Account", keyringPair.PublicKey)
if err != nil {
return err
}

var accountInfo types.AccountInfo
ok, err := api.RPC.State.GetStorageLatest(key, &accountInfo)
if err != nil || !ok {
return err
}

nonce := uint32(accountInfo.Nonce)
o := types.SignatureOptions{
BlockHash: genesisHash,
Era: types.ExtrinsicEra{IsMortalEra: false},
GenesisHash: genesisHash,
Nonce: types.NewUCompactFromUInt(uint64(nonce)),
SpecVersion: rv.SpecVersion,
Tip: types.NewUCompactFromUInt(0),
AppID: types.NewUCompactFromUInt(uint64(appID)),
TransactionVersion: rv.TransactionVersion,
}

// Sign the transaction using Alice's default account
err = ext.Sign(keyringPair, o)
if err != nil {
return err
}

// Send the extrinsic
_, err = api.RPC.Author.SubmitExtrinsic(ext)
if err != nil {
return err
}

return nil

}
3 changes: 3 additions & 0 deletions da/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"fmt"

"github.com/rollkit/rollkit/da"
"github.com/rollkit/rollkit/da/avail"
"github.com/rollkit/rollkit/da/celestia"

"github.com/rollkit/rollkit/da/grpc"
"github.com/rollkit/rollkit/da/mock"
)
Expand All @@ -23,6 +25,7 @@ var clients = map[string]func() da.DataAvailabilityLayerClient{
"mock": func() da.DataAvailabilityLayerClient { return &mock.DataAvailabilityLayerClient{} },
"grpc": func() da.DataAvailabilityLayerClient { return &grpc.DataAvailabilityLayerClient{} },
"celestia": func() da.DataAvailabilityLayerClient { return &celestia.DataAvailabilityLayerClient{} },
"avail": func() da.DataAvailabilityLayerClient { return &avail.DataAvailabilityLayerClient{} },
}

// GetClient returns client identified by name.
Expand Down
Loading

0 comments on commit 869ddff

Please sign in to comment.