Skip to content

Commit

Permalink
refactor: switch to custom DA client interface (#11)
Browse files Browse the repository at this point in the history
* refactor: switch to custom DA client interface

- <daName>.go -> client.go for consistency

* chore: add docker-compose and smol tweaks

* refactor: remove 'da' suffix and rename to `client.go`

* forge install: blobstream-contracts

v4.1.0

* refactor: DABuilder -> ClientBuilder
  • Loading branch information
0xRampey committed May 27, 2024
1 parent 3343d98 commit 71fe78f
Show file tree
Hide file tree
Showing 39 changed files with 392 additions and 194 deletions.
14 changes: 7 additions & 7 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[submodule "celestiada/verify/contracts/lib/forge-std"]
path = celestiada/verify/contracts/lib/forge-std
[submodule "celestia/verify/contracts/lib/forge-std"]
path = celestia/verify/contracts/lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "celestiada/verify/contracts/lib/blobstream-contracts"]
path = celestiada/verify/contracts/lib/blobstream-contracts
url = https://github.com/celestiaorg/blobstream-contracts
[submodule "availda/verify/contracts/lib/forge-std"]
path = availda/verify/contracts/lib/forge-std
[submodule "avail/verify/contracts/lib/forge-std"]
path = avail/verify/contracts/lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "celestia/verify/contracts/lib/blobstream-contracts"]
path = celestia/verify/contracts/lib/blobstream-contracts
url = https://github.com/celestiaorg/blobstream-contracts
63 changes: 24 additions & 39 deletions availda/availda.go → avail/client.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package availda
package avail

import (
"context"
Expand All @@ -13,12 +13,10 @@ import (

"log"

"encoding/binary"

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"
"github.com/rollkit/go-da"
"github.com/stackrlabs/go-daash/da"
"go.uber.org/zap"
"golang.org/x/crypto/sha3"
)
Expand All @@ -45,7 +43,7 @@ type DataProof struct {
} `json:"roots"`
}

type DAClient struct {
type Client struct {
Config Config
API *gsrpc.SubstrateAPI
Meta *types.Metadata
Expand All @@ -58,8 +56,8 @@ type DAClient struct {
}

// Returns a newly initalised Avail DA client
func New(configPath string) (*DAClient, error) {
a := DAClient{}
func NewClient(configPath string) (*Client, error) {
a := Client{}
err := a.Config.GetConfig(configPath)
if err != nil {
return nil, fmt.Errorf("cannot get config", err)
Expand Down Expand Up @@ -112,14 +110,14 @@ func New(configPath string) (*DAClient, error) {
}

// MaxBlobSize returns the max blob size
func (c *DAClient) MaxBlobSize(ctx context.Context) (uint64, error) {
func (c *Client) 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 *DAClient) Submit(ctx context.Context, daBlobs []da.Blob, gasPrice float64) ([]da.ID, []da.Proof, error) {
func (a *Client) 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 @@ -243,7 +241,7 @@ out:
}
dataProof := dataProofResp.Result.DataProof
// NOTE: Substrate's BlockNumber type is an alias for u32 type, which is uint32
blobID := MakeID(uint32(block.Block.Header.Number), extIndex)
blobID := ID{Height: uint64(block.Block.Header.Number), ExtIndex: uint32(extIndex)}
blobIDs := make([]da.ID, 1)
blobIDs[0] = blobID

Expand All @@ -257,7 +255,7 @@ out:
}

// Get returns Blob for each given ID, or an error.
func (a *DAClient) Get(ctx context.Context, ids []da.ID) ([]da.Blob, error) {
func (a *Client) 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.
ext, err := a.GetExtrinsic(ids[0])
if err != nil {
Expand All @@ -269,19 +267,19 @@ func (a *DAClient) Get(ctx context.Context, ids []da.ID) ([]da.Blob, error) {
}

// GetIDs returns IDs of all Blobs located in DA at given height.
func (a *DAClient) GetIDs(ctx context.Context, height uint64) ([]da.ID, error) {
func (a *Client) 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 *DAClient) Commit(ctx context.Context, daBlobs []da.Blob) ([]da.Commitment, error) {
func (a *Client) Commit(ctx context.Context, daBlobs []da.Blob) ([]da.Commitment, error) {
// TODO: Need to implement this
return nil, nil
}

// GetProofs returns the proofs for the given IDs
func (a *DAClient) GetProof(ctx context.Context, blockHeight uint32, extIdx int) (DataProofRPCResponse, error) {
func (a *Client) GetProof(ctx context.Context, blockHeight uint32, extIdx int) (DataProofRPCResponse, error) {
var dataProofResp DataProofRPCResponse
blockHash, err := a.API.RPC.Chain.GetBlockHash(uint64(blockHeight))
if err != nil {
Expand Down Expand Up @@ -311,7 +309,7 @@ func (a *DAClient) GetProof(ctx context.Context, blockHeight uint32, extIdx int)
}

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

func (a *DAClient) GetAccountNextIndex() (types.UCompact, error) {
func (a *Client) GetAccountNextIndex() (types.UCompact, error) {
// TODO: Add context to the request
resp, err := http.Post(a.Config.HttpApiURL, "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 @@ -348,25 +346,9 @@ func (a *DAClient) GetAccountNextIndex() (types.UCompact, error) {
return types.NewUCompactFromUInt(uint64(accountNextIndex.Result)), nil
}

// makeID creates a unique ID to reference a blob on Avail
func MakeID(blockHeight uint32, extIndex int) da.ID {
// Serialise height and leaf index to binary
heightLen := 4
heightBytes := make([]byte, heightLen)
binary.LittleEndian.PutUint32(heightBytes, blockHeight)
extIndexBytes := make([]byte, 4)
binary.LittleEndian.PutUint32(extIndexBytes, uint32(extIndex))
return da.ID(append(heightBytes, extIndexBytes...))
}

// SplitID returns the block height and leaf index from a unique ID
func SplitID(id da.ID) (uint32, uint32) {
heightLen := 4
heightBytes := id[:heightLen]
extIdxBytes := id[heightLen:]
blockHeight := binary.LittleEndian.Uint32(heightBytes)
extIdx := binary.LittleEndian.Uint32(extIdxBytes)
return blockHeight, extIdx
type ID struct {
Height uint64 `json:"blockHeight"`
ExtIndex uint32 `json:"extIdx"`
}

type Config struct {
Expand Down Expand Up @@ -400,15 +382,18 @@ func (c *Config) GetConfig(configFileName string) error {
return nil
}

func (a *DAClient) GetExtrinsic(id da.ID) (types.Extrinsic, error) {
blockHeight, extIdx := SplitID(id)
blockHash, err := a.API.RPC.Chain.GetBlockHash(uint64(blockHeight))
func (a *Client) GetExtrinsic(id da.ID) (types.Extrinsic, error) {
availID, ok := id.(ID)
if !ok {
return types.Extrinsic{}, fmt.Errorf("invalid ID")
}
blockHash, err := a.API.RPC.Chain.GetBlockHash(uint64(availID.Height))
if err != nil {
log.Fatalf("cannot get block hash:%w", err)
}
block, err := a.API.RPC.Chain.GetBlock(blockHash)
if err != nil {
log.Fatalf("cannot get block:%w", err)
}
return block.Block.Extrinsics[extIdx], nil
return block.Block.Extrinsics[availID.ExtIndex], nil
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
19 changes: 9 additions & 10 deletions availda/verify/verifier.go → avail/verify/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/rollkit/go-da"
"github.com/stackrlabs/go-daash/availda"
"github.com/stackrlabs/go-daash/availda/verify/bindings/vectorverifier"
"github.com/stackrlabs/go-daash/avail"
"github.com/stackrlabs/go-daash/avail/verify/bindings/vectorverifier"
"github.com/stackrlabs/go-daash/da"
)

const (
Expand All @@ -21,7 +21,7 @@ const (

// Verfifier is used to verify availability of Avail blobs on EVM chains
type Verifier struct {
daClient *availda.DAClient
daClient *avail.Client
ethClient *ethclient.Client
vectorXContract common.Address
bridgeContract common.Address
Expand All @@ -43,7 +43,7 @@ type SuccinctAPIResponse struct {
} `json:"data"`
}

func NewVerifier(client *availda.DAClient, ethEndpoint string, bridgeContract string, verifierContract string, vectorXContract string, availNetwork string) (*Verifier, error) {
func NewVerifier(client *avail.Client, ethEndpoint string, bridgeContract string, verifierContract string, vectorXContract string, availNetwork string) (*Verifier, error) {
ethClient, err := ethclient.Dial(ethEndpoint)
if err != nil {
return nil, fmt.Errorf("failed to create eth client: %w", err)
Expand Down Expand Up @@ -79,19 +79,18 @@ func (d *Verifier) IsDataAvailable(blockHeight uint64, extIndex uint64) (bool, e
}

// IsDataIncluded verifies that the blob data corresponding to the given block height and external index is available on DA
func (d *Verifier) IsDataIncluded(blockHeight uint64, extIndex uint64) (bool, error) {
id := availda.MakeID(uint32(blockHeight), int(extIndex))
func (d *Verifier) IsDataIncluded(id avail.ID) (bool, error) {
blobs, err := d.daClient.Get(context.Background(), []da.ID{id})
if err != nil {
return false, fmt.Errorf("failed to get blob data: %w", err)
}
fmt.Println("size of blob data:", len(blobs[0]))

dataProof, err := d.daClient.GetProof(context.Background(), uint32(blockHeight), int(extIndex))
dataProof, err := d.daClient.GetProof(context.Background(), uint32(id.Height), int(id.ExtIndex))
if err != nil {
return false, fmt.Errorf("failed to get data proof: %w", err)
}
proof, err := d.GetAggregatedProof(dataProof, blockHeight)
proof, err := d.GetAggregatedProof(dataProof, id.Height)
if err != nil {
return false, fmt.Errorf("failed to get aggregated proof: %w", err)
}
Expand All @@ -106,7 +105,7 @@ func (d *Verifier) IsDataIncluded(blockHeight uint64, extIndex uint64) (bool, er
return success, nil
}

func (d *Verifier) GetAggregatedProof(dataProof availda.DataProofRPCResponse, blockHeight uint64) (*vectorverifier.IAvailBridgeMerkleProofInput, error) {
func (d *Verifier) GetAggregatedProof(dataProof avail.DataProofRPCResponse, blockHeight uint64) (*vectorverifier.IAvailBridgeMerkleProofInput, error) {
chainID, err := d.ethClient.ChainID(context.Background())
if err != nil {
return nil, fmt.Errorf("cannot get chain id:%w", err)
Expand Down
1 change: 0 additions & 1 deletion availda/verify/contracts/lib/forge-std
Submodule forge-std deleted from 978ac6
Loading

0 comments on commit 71fe78f

Please sign in to comment.