Skip to content

Commit 0140460

Browse files
authored
feat(da): weave vm da integration (#1328)
1 parent bd2214e commit 0140460

14 files changed

Lines changed: 1998 additions & 3 deletions

File tree

config/toml.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,10 @@ da_config = "{{ .DAConfig }}"
9090
# da_config = "{\"base_url\":\"http:\/\/127.0.0.1:26658\",\"timeout\":30000000000,\"gas_prices\":0.1,\"auth_token\":\"TOKEN\",\"backoff\":{\"initial_delay\":6000000000,\"max_delay\":6000000000,\"growth_factor\":2},\"retry_attempts\":4,\"retry_delay\":3000000000}"
9191
# Avail config example:
9292
# da_config = "{\"seed\": \"MNEMONIC\", \"api_url\": \"wss://kate.avail.tools/ws\", \"app_id\": 0, \"tip\":10}"
93-
93+
# WeaveVM config example:
94+
# da_config = "{\"endpoint\":\"https://testnet-rpc.wvm.dev\",\"chain_id\":9496,\"timeout\":\"30s\",\"private_key_hex\":\"PRIVATE_KEY_HEX\"}"
95+
# Or with web3signer:
96+
# da_config = "{\"endpoint\":\"https://testnet-rpc.wvm.dev\",\"chain_id\":9496,\"timeout\":\"30s\",\"web3_signer_endpoint\":\"http://localhost:9000\"}"
9497
9598
### p2p config ###
9699

da/da.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const (
4444
Celestia Client = "celestia"
4545
Avail Client = "avail"
4646
Grpc Client = "grpc"
47+
WeaveVM Client = "weavevm"
4748
)
4849

4950
// Option is a function that sets a parameter on the da layer.
@@ -75,6 +76,12 @@ type DASubmitMetaData struct {
7576
Length int
7677
// any NMT root for the specific height, necessary for non-inclusion proof
7778
Root []byte
79+
// WeaveVM arweave block hash means data stored permanently in Arweave block
80+
WvmArweaveBlockHash string
81+
// WeaveVM tx hash
82+
WvmTxHash string
83+
// WeaveVM block hash
84+
WvmBlockHash string
7885
}
7986

8087
type Balance struct {
@@ -176,6 +183,12 @@ type DACheckMetaData struct {
176183
RowProofs []*merkle.Proof
177184
// any NMT root for the specific height, necessary for non-inclusion proof
178185
Root []byte
186+
// WeaveVM arweave block hash means data stored permanently in Arweave block
187+
WvmArweaveBlockHash string
188+
// WeaveVM tx hash
189+
WvmTxHash string
190+
// WeaveVM block hash
191+
WvmBlockHash string
179192
}
180193

181194
// ResultSubmitBatch contains information returned from DA layer after block submission.

da/registry/registry.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/dymensionxyz/dymint/da/celestia"
77
"github.com/dymensionxyz/dymint/da/grpc"
88
"github.com/dymensionxyz/dymint/da/local"
9+
weavevm "github.com/dymensionxyz/dymint/da/weave_vm"
910
)
1011

1112
// this is a central registry for all Data Availability Layer Clients
@@ -14,6 +15,7 @@ var clients = map[string]func() da.DataAvailabilityLayerClient{
1415
"grpc": func() da.DataAvailabilityLayerClient { return &grpc.DataAvailabilityLayerClient{} },
1516
"celestia": func() da.DataAvailabilityLayerClient { return &celestia.DataAvailabilityLayerClient{} },
1617
"avail": func() da.DataAvailabilityLayerClient { return &avail.DataAvailabilityLayerClient{} },
18+
"weavevm": func() da.DataAvailabilityLayerClient { return &weavevm.DataAvailabilityLayerClient{} },
1719
}
1820

1921
// GetClient returns client identified by name.

da/registry/registry_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
func TestRegistery(t *testing.T) {
1111
assert := assert.New(t)
1212

13-
expected := []string{"mock", "grpc", "celestia", "avail"}
13+
expected := []string{"mock", "grpc", "celestia", "avail", "weavevm"}
1414
actual := registry.RegisteredClients()
1515

1616
assert.ElementsMatch(expected, actual)

da/weave_vm/gateway/client.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package gateway
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"io"
8+
"net/http"
9+
"strings"
10+
11+
weaveVMtypes "github.com/dymensionxyz/dymint/da/weave_vm/types"
12+
"github.com/dymensionxyz/dymint/types"
13+
"github.com/ethereum/go-ethereum/common/hexutil"
14+
)
15+
16+
type Gateway struct {
17+
config *weaveVMtypes.Config
18+
logger types.Logger
19+
}
20+
21+
func NewGatewayClient(config *weaveVMtypes.Config, logger types.Logger) *Gateway {
22+
return &Gateway{config, logger}
23+
}
24+
25+
const weaveVMGatewayURL = "https://gateway.wvm.dev/v1/calldata/%s"
26+
27+
// Modified get function with improved error handling
28+
func (g *Gateway) RetrieveFromGateway(ctx context.Context, txHash string) (*weaveVMtypes.WvmDymintBlob, error) {
29+
type WvmRetrieverResponse struct {
30+
ArweaveBlockHash string `json:"arweave_block_hash"`
31+
Calldata string `json:"calldata"`
32+
WarDecodedCalldata string `json:"war_decoded_calldata"`
33+
WvmBlockHash string `json:"weavevm_block_hash"`
34+
WvmBlockNumber uint64 `json:"wvm_block_id"`
35+
}
36+
r, err := http.NewRequestWithContext(ctx, http.MethodGet,
37+
fmt.Sprintf(weaveVMGatewayURL,
38+
txHash), nil)
39+
if err != nil {
40+
return nil, fmt.Errorf("failed to create request: %w", err)
41+
}
42+
43+
r.Header.Set("Accept", "application/json")
44+
client := &http.Client{
45+
Timeout: g.config.Timeout,
46+
}
47+
48+
g.logger.Debug("sending request to WeaveVM data retriever",
49+
"url", r.URL.String(),
50+
"headers", r.Header)
51+
52+
resp, err := client.Do(r)
53+
if err != nil {
54+
return nil, fmt.Errorf("failed to call weaveVM-data-retriever: %w", err)
55+
}
56+
defer resp.Body.Close()
57+
58+
body, err := io.ReadAll(resp.Body)
59+
if err != nil {
60+
return nil, fmt.Errorf("failed to read response body: %w", err)
61+
}
62+
63+
if err := validateResponse(resp, body); err != nil {
64+
g.logger.Error("invalid response from WeaveVM data retriever",
65+
"status", resp.Status,
66+
"content_type", resp.Header.Get("Content-Type"),
67+
"body", string(body))
68+
return nil, fmt.Errorf("invalid response: %w", err)
69+
}
70+
71+
var weaveVMData WvmRetrieverResponse
72+
if err = json.Unmarshal(body, &weaveVMData); err != nil {
73+
g.logger.Error("failed to unmarshal response",
74+
"error", err,
75+
"body", string(body),
76+
"content_type", resp.Header.Get("Content-Type"))
77+
return nil, fmt.Errorf("failed to unmarshal response: %w, body: %s", err, string(body))
78+
}
79+
80+
g.logger.Info("weaveVM backend: get data from weaveVM",
81+
"arweave_block_hash", weaveVMData.ArweaveBlockHash,
82+
"weavevm_block_hash", weaveVMData.WvmBlockHash,
83+
"calldata_length", len(weaveVMData.Calldata))
84+
85+
blob, err := hexutil.Decode(weaveVMData.Calldata)
86+
if err != nil {
87+
return nil, fmt.Errorf("failed to decode calldata: %w", err)
88+
}
89+
90+
if len(blob) == 0 {
91+
return nil, fmt.Errorf("decoded blob has length zero")
92+
}
93+
94+
return &weaveVMtypes.WvmDymintBlob{ArweaveBlockHash: weaveVMData.ArweaveBlockHash, WvmBlockHash: weaveVMData.WvmBlockHash, WvmTxHash: txHash, Blob: blob}, nil
95+
}
96+
97+
func validateResponse(resp *http.Response, body []byte) error {
98+
if resp.StatusCode != http.StatusOK {
99+
return fmt.Errorf("unexpected status code: %d, body: %s", resp.StatusCode, string(body))
100+
}
101+
102+
contentType := resp.Header.Get("Content-Type")
103+
if !strings.Contains(contentType, "application/json") {
104+
return fmt.Errorf("unexpected content type: %s, body: %s", contentType, string(body))
105+
}
106+
107+
return nil
108+
}

0 commit comments

Comments
 (0)