Skip to content

Commit 3343d98

Browse files
committed
feat(availda): add DAVerifier and avail bridge contract bindings (#9)
* feat(availda): add DAVerifier and avail bridge contract bindings * chore: forge init * forge install: forge-std v1.8.2 * feat(availda): add customer verifier contracts * feat(availda): deploy and test with sepolia contract * refactor: clean up typos, methods, files * refactor: separate client and verifier - add constant mapping * add better error response * chore: fix typo and smol refactor
1 parent d62ad82 commit 3343d98

File tree

19 files changed

+5638
-104
lines changed

19 files changed

+5638
-104
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@
44
[submodule "celestiada/verify/contracts/lib/blobstream-contracts"]
55
path = celestiada/verify/contracts/lib/blobstream-contracts
66
url = https://github.com/celestiaorg/blobstream-contracts
7+
[submodule "availda/verify/contracts/lib/forge-std"]
8+
path = availda/verify/contracts/lib/forge-std
9+
url = https://github.com/foundry-rs/forge-std

availda/availda.go

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,32 +27,26 @@ type AccountNextIndexRPCResponse struct {
2727
Result uint `json:"result"`
2828
}
2929
type DataProofRPCResponse struct {
30+
ID int64 `json:"id"`
3031
Jsonrpc string `json:"jsonrpc"`
3132
Result struct {
32-
DataProof struct {
33-
DataRoot string `json:"dataRoot"`
34-
BlobRoot string `json:"blobRoot"`
35-
BridgeRoot string `json:"bridgeRoot"`
36-
Proof []string `json:"proof"`
37-
NumberOfLeaves int `json:"numberOfLeaves"`
38-
LeafIndex int `json:"leafIndex"`
39-
Leaf string `json:"leaf"`
40-
} `json:"dataProof"`
33+
DataProof `json:"dataProof"`
4134
} `json:"result"`
42-
ID int `json:"id"`
4335
}
4436
type DataProof struct {
45-
Root string `json:"dataRoot"`
46-
BlobRoot string `json:"blobRoot"`
47-
BridgeRoot string `json:"bridgeRoot"`
48-
Proof []string `json:"proof"`
49-
NumberOfLeaves uint32 `json:"numberOfLeaves"`
50-
LeafIndex uint32 `json:"leafIndex"`
5137
Leaf string `json:"leaf"`
38+
LeafIndex int64 `json:"leafIndex"`
39+
NumberOfLeaves int64 `json:"numberOfLeaves"`
40+
Proof []string `json:"proof"`
41+
Roots struct {
42+
BlobRoot string `json:"blobRoot"`
43+
BridgeRoot string `json:"bridgeRoot"`
44+
DataRoot string `json:"dataRoot"`
45+
} `json:"roots"`
5246
}
5347

5448
type DAClient struct {
55-
config Config
49+
Config Config
5650
API *gsrpc.SubstrateAPI
5751
Meta *types.Metadata
5852
AppID int
@@ -66,12 +60,12 @@ type DAClient struct {
6660
// Returns a newly initalised Avail DA client
6761
func New(configPath string) (*DAClient, error) {
6862
a := DAClient{}
69-
err := a.config.GetConfig(configPath)
63+
err := a.Config.GetConfig(configPath)
7064
if err != nil {
7165
return nil, fmt.Errorf("cannot get config", err)
7266
}
7367

74-
a.API, err = gsrpc.NewSubstrateAPI(a.config.WsRpcURL)
68+
a.API, err = gsrpc.NewSubstrateAPI(a.Config.WsRpcURL)
7569
if err != nil {
7670
// log.Error("cannot get api:%w", zap.Error(err))
7771
return nil, fmt.Errorf("cannot get api", err)
@@ -86,8 +80,8 @@ func New(configPath string) (*DAClient, error) {
8680
a.AppID = 0
8781

8882
// if app id is greater than 0 then it must be created before submitting data
89-
if a.config.AppID != 0 {
90-
a.AppID = a.config.AppID
83+
if a.Config.AppID != 0 {
84+
a.AppID = a.Config.AppID
9185
}
9286

9387
a.GenesisHash, err = a.API.RPC.Chain.GetBlockHash(0)
@@ -102,7 +96,7 @@ func New(configPath string) (*DAClient, error) {
10296
return nil, fmt.Errorf("cannot get runtime version", err)
10397
}
10498

105-
a.KeyringPair, err = signature.KeyringPairFromSecret(a.config.Seed, 42)
99+
a.KeyringPair, err = signature.KeyringPairFromSecret(a.Config.Seed, 42)
106100
if err != nil {
107101
// log.Error("cannot get keyring pair:%w", zap.Error(err))
108102
return nil, fmt.Errorf("cannot get keyring pair", err)
@@ -167,7 +161,7 @@ func (a *DAClient) Submit(ctx context.Context, daBlobs []da.Blob, gasPrice float
167161
}
168162

169163
defer sub.Unsubscribe()
170-
timeout := time.After(time.Duration(a.config.Timeout) * time.Second)
164+
timeout := time.After(time.Duration(a.Config.Timeout) * time.Second)
171165
var blockHash types.Hash
172166
out:
173167
for {
@@ -223,7 +217,7 @@ out:
223217
eBytes = []byte(strings.Trim(string(eBytes), "\""))
224218
if string(extBytes) == string(eBytes) {
225219
extIndex = idx
226-
resp, err := http.Post(a.config.HttpApiURL, "application/json",
220+
resp, err := http.Post(a.Config.HttpApiURL, "application/json",
227221
strings.NewReader(fmt.Sprintf("{\"id\":1,\"jsonrpc\":\"2.0\",\"method\":\"kate_queryDataProofV2\",\"params\":[%d, \"%#x\"]}", idx+1, blockHash))) //nolint: noctx
228222
if err != nil {
229223
break
@@ -249,7 +243,7 @@ out:
249243
}
250244
dataProof := dataProofResp.Result.DataProof
251245
// NOTE: Substrate's BlockNumber type is an alias for u32 type, which is uint32
252-
blobID := makeID(uint32(block.Block.Header.Number), extIndex)
246+
blobID := MakeID(uint32(block.Block.Header.Number), extIndex)
253247
blobIDs := make([]da.ID, 1)
254248
blobIDs[0] = blobID
255249

@@ -286,6 +280,36 @@ func (a *DAClient) Commit(ctx context.Context, daBlobs []da.Blob) ([]da.Commitme
286280
return nil, nil
287281
}
288282

283+
// GetProofs returns the proofs for the given IDs
284+
func (a *DAClient) GetProof(ctx context.Context, blockHeight uint32, extIdx int) (DataProofRPCResponse, error) {
285+
var dataProofResp DataProofRPCResponse
286+
blockHash, err := a.API.RPC.Chain.GetBlockHash(uint64(blockHeight))
287+
if err != nil {
288+
return dataProofResp, fmt.Errorf("cannot get block hash:%w", err)
289+
}
290+
resp, err := http.Post(a.Config.HttpApiURL, "application/json",
291+
strings.NewReader(fmt.Sprintf("{\"id\":1,\"jsonrpc\":\"2.0\",\"method\":\"kate_queryDataProof\",\"params\":[%d, \"%#x\"]}", extIdx, blockHash)))
292+
293+
if err != nil {
294+
return dataProofResp, fmt.Errorf("cannot get data proof:%w", err)
295+
}
296+
data, err := io.ReadAll(resp.Body)
297+
if err != nil {
298+
return dataProofResp, fmt.Errorf("cannot read data:%w", err)
299+
}
300+
err = resp.Body.Close()
301+
if err != nil {
302+
return dataProofResp, fmt.Errorf("cannot close body:%w", err)
303+
}
304+
fmt.Println("raw proof data", string(data))
305+
err = json.Unmarshal(data, &dataProofResp)
306+
if err != nil {
307+
return dataProofResp, fmt.Errorf("cannot unmarshal data:%w", err)
308+
}
309+
fmt.Println("dataProofResp", dataProofResp)
310+
return dataProofResp, nil
311+
}
312+
289313
// Validate validates Commitments against the corresponding Proofs. This should be possible without retrieving the Blobs.
290314
func (c *DAClient) Validate(ctx context.Context, ids []da.ID, daProofs []da.Proof) ([]bool, error) {
291315
// TODO: Need to implement this
@@ -305,7 +329,7 @@ func (b BatchDAData) IsEmpty() bool {
305329

306330
func (a *DAClient) GetAccountNextIndex() (types.UCompact, error) {
307331
// TODO: Add context to the request
308-
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
332+
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
309333
if err != nil {
310334
return types.NewUCompactFromUInt(0), fmt.Errorf("cannot post account next index request", err)
311335
}
@@ -325,7 +349,7 @@ func (a *DAClient) GetAccountNextIndex() (types.UCompact, error) {
325349
}
326350

327351
// makeID creates a unique ID to reference a blob on Avail
328-
func makeID(blockHeight uint32, extIndex int) da.ID {
352+
func MakeID(blockHeight uint32, extIndex int) da.ID {
329353
// Serialise height and leaf index to binary
330354
heightLen := 4
331355
heightBytes := make([]byte, heightLen)
@@ -353,6 +377,7 @@ type Config struct {
353377
DestinationDomain int `json:"destination_domain"`
354378
DestinationAddress string `json:"destination_address"`
355379
Timeout int `json:"timeout"`
380+
Network string `json:"network"`
356381
}
357382

358383
func (c *Config) GetConfig(configFileName string) error {

availda/verify/bindings/AvailBridge/AvailBridge.go

Lines changed: 3170 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)