From 87ccf172bf2006e0ff42a399b2344199d6d1112f Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 19 Jan 2024 19:59:54 -0600 Subject: [PATCH 1/5] base --- examples/cosmos/rollkit_test.go | 125 ++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 examples/cosmos/rollkit_test.go diff --git a/examples/cosmos/rollkit_test.go b/examples/cosmos/rollkit_test.go new file mode 100644 index 000000000..bdc722a15 --- /dev/null +++ b/examples/cosmos/rollkit_test.go @@ -0,0 +1,125 @@ +package cosmos_test + +import ( + "context" + "fmt" + "path" + "testing" + + "github.com/strangelove-ventures/interchaintest/v8" + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v8/ibc" + "github.com/strangelove-ventures/interchaintest/v8/testutil" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zaptest" +) + +// https://rollkit.dev/tutorials/gm-world +const ( + // TODO: get https://github.com/rollkit/local-celestia-devnet/blob/main/entrypoint.sh into interchaintest + // 26650:26650 -p 26657:26657 -p 26658:26658 -p 26659:26659 -p 9090:9090 // 26650 runs th celestia-da server + // DockerImage = "ghcr.io/celestiaorg/celestia-app" + DockerImage = "ghcr.io/strangelove-ventures/heighliner/celestia" + DockerVersion = "v1.6.0" + + DADockerImage = "ghcr.io/rollkit/celestia-da" + DADockerVersion = "v0.12.6" + + // App & node has a celestia user with home dir /home/celestia + APP_PATH = ".celestia-app" + NODE_PATH = "bridge" +) + +func TestRollkitCelestia(t *testing.T) { + if testing.Short() { + t.Skip("skipping in short mode") + } + + t.Parallel() + + numVals := 1 + numFullNodes := 0 + coinDecimals := int64(6) + + // https://github.com/rollkit/local-celestia-devnet/blob/main/entrypoint.sh + + // configFileOverrides := make(map[string]any) + // configFileOverrides["config/config.toml"] = make(testutil.Toml) + // configFileOverrides["config/client.toml"] = make(testutil.Toml) + + cfg := ibc.ChainConfig{ + Name: "celestia", // Type: Rollkit / Rollup / Celestia? + Denom: "utia", + Type: "cosmos", + GasPrices: "0utia", + TrustingPeriod: "500h", + // HostPortOverride: , + EncodingConfig: nil, + SkipGenTx: false, + CoinDecimals: &coinDecimals, + AdditionalStartArgs: []string{"--grpc.enable"}, + ChainID: "test", + Bin: "celestia-appd", + Images: []ibc.DockerImage{ + { + Repository: DockerImage, + Version: DockerVersion, + UidGid: "1025:1025", + }, + }, + Bech32Prefix: "celestia", + CoinType: "118", + // ModifyGenesis: cosmos.ModifyGenesis([]cosmos.GenesisKV{}), + GasAdjustment: 1.5, + ConfigFileOverrides: testutil.Toml{"config/config.toml": testutil.Toml{ + "index_all_keys": true, + "mode": "validator", // be sure to only use 1 validator here + }}, + } + + cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ + { + Name: cfg.Name, + ChainName: cfg.Name, + Version: DockerVersion, + ChainConfig: cfg, + NumValidators: &numVals, + NumFullNodes: &numFullNodes, + }, + }) + + chains, err := cf.Chains(t.Name()) + require.NoError(t, err) + + chain := chains[0].(*cosmos.CosmosChain) + + ic := interchaintest.NewInterchain(). + AddChain(chain) + + ctx := context.Background() + client, network := interchaintest.DockerSetup(t) + + require.NoError(t, ic.Build(ctx, nil, interchaintest.InterchainBuildOptions{ + TestName: t.Name(), + Client: client, + NetworkID: network, + SkipPathCreation: true, + })) + t.Cleanup(func() { + _ = ic.Close() + }) + + // var userFunds = math.NewInt(10_000_000_000) + // users := interchaintest.GetAndFundTestUsers(t, ctx, t.Name(), userFunds, chain) + // chainUser := users[0] + // fmt.Println("chainUser", chainUser) + + nodePath := path.Join(chain.GetNode().HomeDir(), NODE_PATH) + fmt.Println("nodePath", nodePath) + + // n := chain.GetNode() + // n.Exec() + + // TODO: get the genesis file from the node + // Start the celestia da bridge +} From 0afb2b18eeeb28b16e905d0a15a4f8bac8f7371a Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 19 Jan 2024 21:49:42 -0600 Subject: [PATCH 2/5] Set ValidatorMnemonic on CreateKey for val --- chain/cosmos/chain_node.go | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/chain/cosmos/chain_node.go b/chain/cosmos/chain_node.go index adc99896d..92b335eee 100644 --- a/chain/cosmos/chain_node.go +++ b/chain/cosmos/chain_node.go @@ -43,16 +43,17 @@ import ( // ChainNode represents a node in the test network that is being created type ChainNode struct { - VolumeName string - Index int - Chain ibc.Chain - Validator bool - NetworkID string - DockerClient *dockerclient.Client - Client rpcclient.Client - GrpcConn *grpc.ClientConn - TestName string - Image ibc.DockerImage + VolumeName string + Index int + Chain ibc.Chain + Validator bool + ValidatorMnemonic string // if this is a validator, this will be set + NetworkID string + DockerClient *dockerclient.Client + Client rpcclient.Client + GrpcConn *grpc.ClientConn + TestName string + Image ibc.DockerImage // Additional processes that need to be run on a per-validator basis. Sidecars SidecarProcesses @@ -644,11 +645,25 @@ func (tn *ChainNode) CreateKey(ctx context.Context, name string) error { tn.lock.Lock() defer tn.lock.Unlock() - _, _, err := tn.ExecBin(ctx, + _, stderr, err := tn.ExecBin(ctx, "keys", "add", name, "--coin-type", tn.Chain.Config().CoinType, "--keyring-backend", keyring.BackendTest, ) + + if tn.Validator && tn.ValidatorMnemonic == "" { + lines := strings.Split(string(stderr), "\n") + + updated := []string{} + for _, line := range lines { + if line != "" { + updated = append(updated, line) + } + } + + tn.ValidatorMnemonic = updated[len(updated)-1] + } + return err } From 9fb8fee437f11351e3e7aefe9667b81f76af3acc Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 19 Jan 2024 22:15:42 -0600 Subject: [PATCH 3/5] sidecar pull image if not there --- chain/cosmos/sidecar.go | 5 +++++ ibc/types.go | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/chain/cosmos/sidecar.go b/chain/cosmos/sidecar.go index 2275bd4db..9c66e9d5a 100644 --- a/chain/cosmos/sidecar.go +++ b/chain/cosmos/sidecar.go @@ -107,6 +107,11 @@ func (s *SidecarProcess) logger() *zap.Logger { } func (s *SidecarProcess) CreateContainer(ctx context.Context) error { + // TODO: move into containerLifecycle.CreateContainer + if err := s.Image.PullImage(ctx, *s.DockerClient); err != nil { + return fmt.Errorf("sidecar createcontainer failed to pull image: %w", err) + } + return s.containerLifecycle.CreateContainer(ctx, s.TestName, s.NetworkID, s.Image, s.ports, s.Bind(), nil, s.HostName(), s.startCmd, s.env) } diff --git a/ibc/types.go b/ibc/types.go index 4edc901c6..7c3788faf 100644 --- a/ibc/types.go +++ b/ibc/types.go @@ -1,7 +1,9 @@ package ibc import ( + "context" "fmt" + "io" "reflect" "strconv" "strings" @@ -10,6 +12,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module/testutil" ibcexported "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + "github.com/docker/docker/api/types" + "github.com/docker/docker/client" ) // ChainConfig defines the chain parameters requires to run an interchaintest testnet for a chain. @@ -276,6 +280,20 @@ func (i DockerImage) Ref() string { return i.Repository + ":" + i.Version } +func (i DockerImage) PullImage(ctx context.Context, client client.Client) error { + ref := i.Ref() + _, _, err := client.ImageInspectWithRaw(ctx, ref) + if err != nil { + rc, err := client.ImagePull(ctx, ref, types.ImagePullOptions{}) + if err != nil { + return fmt.Errorf("pull image %s: %w", ref, err) + } + _, _ = io.Copy(io.Discard, rc) + _ = rc.Close() + } + return nil +} + type WalletAmount struct { Address string Denom string From cb8031cf6a7679174659d5080f1e7bf3ef3197df Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 19 Jan 2024 22:18:26 -0600 Subject: [PATCH 4/5] rough base --- examples/cosmos/Dockerfile | 21 ++++ examples/cosmos/rollkit_test.go | 167 ++++++++++++++++++++++++++------ 2 files changed, 157 insertions(+), 31 deletions(-) create mode 100644 examples/cosmos/Dockerfile diff --git a/examples/cosmos/Dockerfile b/examples/cosmos/Dockerfile new file mode 100644 index 000000000..c9934034c --- /dev/null +++ b/examples/cosmos/Dockerfile @@ -0,0 +1,21 @@ + +# docker build . -t strangelove/full-celestia:v0.0.1 +# +# Run both a celestia-da and celestia-app node from the same image +# Ideally this is temperary so we can ignore docker host mounting. + +FROM ghcr.io/strangelove-ventures/heighliner/celestia:v1.6.0 AS celestia-app + +FROM ghcr.io/rollkit/celestia-da:v0.12.6 + +USER root + +COPY --from=celestia-app /bin/celestia-appd /bin/ + +RUN chmod +x /bin/celestia-appd +RUN chmod +x /bin/celestia-da + +EXPOSE 26650 26657 26658 26659 9090 26657 26656 1317 + + +# docker run reece/full-celestia:v0.0.1 celestia-da \ No newline at end of file diff --git a/examples/cosmos/rollkit_test.go b/examples/cosmos/rollkit_test.go index bdc722a15..9e51d762c 100644 --- a/examples/cosmos/rollkit_test.go +++ b/examples/cosmos/rollkit_test.go @@ -6,6 +6,9 @@ import ( "path" "testing" + "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/strangelove-ventures/interchaintest/v8" "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/ibc" @@ -15,24 +18,47 @@ import ( ) // https://rollkit.dev/tutorials/gm-world -const ( +var ( // TODO: get https://github.com/rollkit/local-celestia-devnet/blob/main/entrypoint.sh into interchaintest // 26650:26650 -p 26657:26657 -p 26658:26658 -p 26659:26659 -p 9090:9090 // 26650 runs th celestia-da server - // DockerImage = "ghcr.io/celestiaorg/celestia-app" - DockerImage = "ghcr.io/strangelove-ventures/heighliner/celestia" - DockerVersion = "v1.6.0" + // DockerImage = "ghcr.io/strangelove-ventures/heighliner/celestia" + // DockerVersion = "v1.6.0" + // DADockerImage = "ghcr.io/rollkit/celestia-da" + // DADockerVersion = "v0.12.6" - DADockerImage = "ghcr.io/rollkit/celestia-da" - DADockerVersion = "v0.12.6" + // holds both the da and app binaries from heighliner so we can ignore docker mounting magic + DockerImage = "reece/full-celestia" + DockerVersion = "v0.0.1" // App & node has a celestia user with home dir /home/celestia - APP_PATH = ".celestia-app" - NODE_PATH = "bridge" + hardcodedPath = "/var/cosmos-chain/celestia" + APP_PATH = ".celestia-app" + NODE_PATH = path.Join(hardcodedPath, "bridge") + + // TODO: Set namespace and CELESTIA_CUSTOM env variable on bridge start + // echo 0000$(openssl rand -hex 8) + CELESTIA_NAMESPACE = "00007e5327f23637ed07" + + startCmd = []string{ + "celestia-da", "bridge", "init", "--node.store", NODE_PATH, + } + + otherCmd = []string{ + "celestia-da", "bridge", "start", + "--node.store", NODE_PATH, + "--gateway", + "--core.ip", "test-val-0-TestRollkitCelestia", // n.HostName() + "--keyring.accname", "validator", + "--gateway.addr", "0.0.0.0", + "--rpc.addr", "0.0.0.0", + "--da.grpc.namespace", CELESTIA_NAMESPACE, + "--da.grpc.listen", "0.0.0.0:26650", + } ) func TestRollkitCelestia(t *testing.T) { if testing.Short() { - t.Skip("skipping in short mode") + t.Skip("skipping in short mode.") } t.Parallel() @@ -41,19 +67,13 @@ func TestRollkitCelestia(t *testing.T) { numFullNodes := 0 coinDecimals := int64(6) - // https://github.com/rollkit/local-celestia-devnet/blob/main/entrypoint.sh - - // configFileOverrides := make(map[string]any) - // configFileOverrides["config/config.toml"] = make(testutil.Toml) - // configFileOverrides["config/client.toml"] = make(testutil.Toml) - cfg := ibc.ChainConfig{ - Name: "celestia", // Type: Rollkit / Rollup / Celestia? - Denom: "utia", - Type: "cosmos", - GasPrices: "0utia", - TrustingPeriod: "500h", - // HostPortOverride: , + Name: "celestia", // Type: Rollkit / Rollup / Celestia? + Denom: "utia", + Type: "cosmos", + GasPrices: "0utia", + TrustingPeriod: "500h", + HostPortOverride: map[int]int{26650: 26650, 1317: 1317, 26656: 26656, 26657: 26657, 9090: 9090}, EncodingConfig: nil, SkipGenTx: false, CoinDecimals: &coinDecimals, @@ -74,7 +94,26 @@ func TestRollkitCelestia(t *testing.T) { ConfigFileOverrides: testutil.Toml{"config/config.toml": testutil.Toml{ "index_all_keys": true, "mode": "validator", // be sure to only use 1 validator here + "tx_index": testutil.Toml{ + "indexer": "kv", // TODO: since we execute queries against the validator (unsure if this works on a celestia validator node) + }, }}, + SidecarConfigs: []ibc.SidecarConfig{ + { + ValidatorProcess: true, + ProcessName: "celestia-da", + Image: ibc.DockerImage{ + Repository: DockerImage, + Version: DockerVersion, + UidGid: "1025:1025", + }, + HomeDir: hardcodedPath, + Ports: []string{"26650"}, + StartCmd: startCmd, + Env: []string{}, + PreStart: false, + }, + }, } cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ @@ -109,17 +148,83 @@ func TestRollkitCelestia(t *testing.T) { _ = ic.Close() }) - // var userFunds = math.NewInt(10_000_000_000) - // users := interchaintest.GetAndFundTestUsers(t, ctx, t.Name(), userFunds, chain) - // chainUser := users[0] - // fmt.Println("chainUser", chainUser) + var userFunds = math.NewInt(10_000_000_000) + users := interchaintest.GetAndFundTestUsers(t, ctx, t.Name(), userFunds, chain) + chainUser := users[0] + fmt.Println("chainUser", chainUser) + + fmt.Println("nodePaths", NODE_PATH) + + // TODO: From the guide, after 1 block (20 seconds?) + n := chain.GetNode() + + // valCommonAddr, err := chain.GetAddress(ctx, "validator") + // require.NoError(t, err) + + // // print valCommonAddr + // fmt.Println("valCommonAddr", string(valCommonAddr)) - nodePath := path.Join(chain.GetNode().HomeDir(), NODE_PATH) - fmt.Println("nodePath", nodePath) + // // celestiavaloper (could also just query from staking?) + // valAddr, err := sdk.GetFromBech32(string(valCommonAddr), cfg.Bech32Prefix+"valoper") + // require.NoError(t, err) + + // fmt.Println("valAddr", string(valAddr)) + + fmt.Println("n.ValidatorMnemonic", n.ValidatorMnemonic) + + // qgb register validator + vals, err := chain.StakingQueryValidators(ctx, stakingtypes.BondStatusBonded) + require.NoError(t, err) - // n := chain.GetNode() - // n.Exec() + val := vals[0].OperatorAddress + + fmt.Println("n.Sidecars", n.Sidecars[0]) + + // recover the validator key (from mnemonic) to the da layer home ( https://github.com/rollkit/local-celestia-devnet/blob/main/entrypoint.sh#L57 ) + if err := RecoverKey(ctx, n, "validator", n.ValidatorMnemonic, path.Join(NODE_PATH, "keys")); err != nil { + t.Fatal(err) + } + + sc := n.Sidecars[0] + if err := sc.CreateContainer(ctx); err != nil { + t.Fatal(err) + } + if err := sc.StartContainer(ctx); err != nil { + t.Fatal(err) + } + + // waits for 20 seconds (2s blocks * 10) + testutil.WaitForBlocks(ctx, 10, chain) + + stdout, stderr, err := sc.Exec(ctx, otherCmd, nil) + fmt.Println("stdout", stdout) + fmt.Println("stderr", stderr) + fmt.Println("err", err) + + testutil.WaitForBlocks(ctx, 10, chain) + + // register teh EVM address + // # private key: da6ed55cb2894ac2c9c10209c09de8e8b9d109b910338d5bf3d747a7e1fc9eb9 + txHash, err := n.ExecTx(ctx, "validator", "qgb", "register", val, "0x966e6f22781EF6a6A82BBB4DB3df8E225DfD9488", "--fees", "30000utia", "-b", "block", "-y") + require.NoError(t, err) + + // convert txHash to response (this does not print, but works upon manually querying against the local node) + res, err := n.TxHashToResponse(ctx, txHash) + require.NoError(t, err) + fmt.Printf("res: %+v\n", res) + + // wait for 100 blocks + testutil.WaitForBlocks(ctx, 100, chain) + +} + +func RecoverKey(ctx context.Context, tn *cosmos.ChainNode, keyName, mnemonic, homeDir string) error { + command := []string{ + "sh", + "-c", + fmt.Sprintf(`echo %q | %s keys add %s --recover --keyring-backend %s --coin-type %s --home %s --output json`, mnemonic, tn.Chain.Config().Bin, keyName, keyring.BackendTest, tn.Chain.Config().CoinType, homeDir), + } - // TODO: get the genesis file from the node - // Start the celestia da bridge + _, _, err := tn.Exec(ctx, command, nil) + return err } From 75cb4c312aec5e777ebb4735ad39cd1cecaa5eea Mon Sep 17 00:00:00 2001 From: Reece Williams Date: Fri, 19 Jan 2024 22:57:30 -0600 Subject: [PATCH 5/5] `NewSidecarProcessFromConfig` with custom env var --- chain/cosmos/chain_node.go | 16 ++++ examples/cosmos/rollkit_test.go | 125 +++++++++++++++++++++----------- 2 files changed, 98 insertions(+), 43 deletions(-) diff --git a/chain/cosmos/chain_node.go b/chain/cosmos/chain_node.go index 92b335eee..f214a9a47 100644 --- a/chain/cosmos/chain_node.go +++ b/chain/cosmos/chain_node.go @@ -138,6 +138,22 @@ func (tn *ChainNode) NewClient(addr string) error { return nil } +func (tn *ChainNode) NewSidecarProcessFromConfig(ctx context.Context, sidecar ibc.SidecarConfig) error { + return tn.NewSidecarProcess( + ctx, + sidecar.PreStart, + sidecar.ProcessName, + tn.DockerClient, + tn.NetworkID, + tn.Image, + tn.HomeDir(), + sidecar.Ports, + sidecar.StartCmd, + sidecar.Env, + ) + +} + func (tn *ChainNode) NewSidecarProcess( ctx context.Context, preStart bool, diff --git a/examples/cosmos/rollkit_test.go b/examples/cosmos/rollkit_test.go index 9e51d762c..4242e4f6d 100644 --- a/examples/cosmos/rollkit_test.go +++ b/examples/cosmos/rollkit_test.go @@ -2,9 +2,11 @@ package cosmos_test import ( "context" + "encoding/json" "fmt" "path" "testing" + "time" "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/crypto/keyring" @@ -38,22 +40,6 @@ var ( // TODO: Set namespace and CELESTIA_CUSTOM env variable on bridge start // echo 0000$(openssl rand -hex 8) CELESTIA_NAMESPACE = "00007e5327f23637ed07" - - startCmd = []string{ - "celestia-da", "bridge", "init", "--node.store", NODE_PATH, - } - - otherCmd = []string{ - "celestia-da", "bridge", "start", - "--node.store", NODE_PATH, - "--gateway", - "--core.ip", "test-val-0-TestRollkitCelestia", // n.HostName() - "--keyring.accname", "validator", - "--gateway.addr", "0.0.0.0", - "--rpc.addr", "0.0.0.0", - "--da.grpc.namespace", CELESTIA_NAMESPACE, - "--da.grpc.listen", "0.0.0.0:26650", - } ) func TestRollkitCelestia(t *testing.T) { @@ -73,7 +59,7 @@ func TestRollkitCelestia(t *testing.T) { Type: "cosmos", GasPrices: "0utia", TrustingPeriod: "500h", - HostPortOverride: map[int]int{26650: 26650, 1317: 1317, 26656: 26656, 26657: 26657, 9090: 9090}, + HostPortOverride: map[int]int{26650: 26650, 1317: 1317, 26656: 26656, 26657: 26657, 26658: 26658, 26659: 26659, 9090: 9090}, EncodingConfig: nil, SkipGenTx: false, CoinDecimals: &coinDecimals, @@ -98,22 +84,6 @@ func TestRollkitCelestia(t *testing.T) { "indexer": "kv", // TODO: since we execute queries against the validator (unsure if this works on a celestia validator node) }, }}, - SidecarConfigs: []ibc.SidecarConfig{ - { - ValidatorProcess: true, - ProcessName: "celestia-da", - Image: ibc.DockerImage{ - Repository: DockerImage, - Version: DockerVersion, - UidGid: "1025:1025", - }, - HomeDir: hardcodedPath, - Ports: []string{"26650"}, - StartCmd: startCmd, - Env: []string{}, - PreStart: false, - }, - }, } cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ @@ -153,9 +123,6 @@ func TestRollkitCelestia(t *testing.T) { chainUser := users[0] fmt.Println("chainUser", chainUser) - fmt.Println("nodePaths", NODE_PATH) - - // TODO: From the guide, after 1 block (20 seconds?) n := chain.GetNode() // valCommonAddr, err := chain.GetAddress(ctx, "validator") @@ -176,15 +143,41 @@ func TestRollkitCelestia(t *testing.T) { vals, err := chain.StakingQueryValidators(ctx, stakingtypes.BondStatusBonded) require.NoError(t, err) - val := vals[0].OperatorAddress - - fmt.Println("n.Sidecars", n.Sidecars[0]) + // fmt.Println("n.Sidecars", n.Sidecars[0]) // recover the validator key (from mnemonic) to the da layer home ( https://github.com/rollkit/local-celestia-devnet/blob/main/entrypoint.sh#L57 ) if err := RecoverKey(ctx, n, "validator", n.ValidatorMnemonic, path.Join(NODE_PATH, "keys")); err != nil { t.Fatal(err) } + // wait for 100 blocks + // testutil.WaitForBlocks(ctx, 100, chain) + + genesisHash := getGenesisBlockHash(ctx, n, 0) + fmt.Println("genesisHash", genesisHash) + + err = n.NewSidecarProcessFromConfig(ctx, ibc.SidecarConfig{ + ValidatorProcess: true, + ProcessName: "celestia-da", + Image: ibc.DockerImage{ + Repository: DockerImage, + Version: DockerVersion, + UidGid: "1025:1025", + }, + HomeDir: hardcodedPath, + Ports: []string{"26650"}, + StartCmd: []string{ + "celestia-da", "bridge", "init", "--node.store", NODE_PATH, + }, + Env: []string{ + "CELESTIA_CUSTOM=test:" + genesisHash, // TODO: does this fix bridge start? + }, + PreStart: false, + }) + if err != nil { + t.Fatal(fmt.Errorf("failed to start celestia-da: %w", err)) + } + sc := n.Sidecars[0] if err := sc.CreateContainer(ctx); err != nil { t.Fatal(err) @@ -194,18 +187,28 @@ func TestRollkitCelestia(t *testing.T) { } // waits for 20 seconds (2s blocks * 10) - testutil.WaitForBlocks(ctx, 10, chain) + testutil.WaitForBlocks(ctx, 5, chain) - stdout, stderr, err := sc.Exec(ctx, otherCmd, nil) + stdout, stderr, err := sc.Exec(ctx, []string{ + "celestia-da", "bridge", "start", + "--node.store", NODE_PATH, + "--gateway", + "--core.ip", n.HostName(), // "test-val-0-TestRollkitCelestia" = n.HostName() + "--keyring.accname", "validator", + "--gateway.addr", "0.0.0.0", + "--rpc.addr", "0.0.0.0", + "--da.grpc.namespace", CELESTIA_NAMESPACE, + "--da.grpc.listen", "0.0.0.0:26650", + }, nil) fmt.Println("stdout", stdout) fmt.Println("stderr", stderr) fmt.Println("err", err) - testutil.WaitForBlocks(ctx, 10, chain) + testutil.WaitForBlocks(ctx, 5, chain) // register teh EVM address // # private key: da6ed55cb2894ac2c9c10209c09de8e8b9d109b910338d5bf3d747a7e1fc9eb9 - txHash, err := n.ExecTx(ctx, "validator", "qgb", "register", val, "0x966e6f22781EF6a6A82BBB4DB3df8E225DfD9488", "--fees", "30000utia", "-b", "block", "-y") + txHash, err := n.ExecTx(ctx, "validator", "qgb", "register", vals[0].OperatorAddress, "0x966e6f22781EF6a6A82BBB4DB3df8E225DfD9488", "--fees", "30000utia", "-b", "block", "-y") require.NoError(t, err) // convert txHash to response (this does not print, but works upon manually querying against the local node) @@ -228,3 +231,39 @@ func RecoverKey(ctx context.Context, tn *cosmos.ChainNode, keyName, mnemonic, ho _, _, err := tn.Exec(ctx, command, nil) return err } + +func getGenesisBlockHash(ctx context.Context, node *cosmos.ChainNode, attempt int) string { + // GENESIS=$(curl -s | jq '.result.block_id.hash' | tr -d '"') + + type CelestiaBlock struct { + BlockID struct { + Hash string `json:"hash"` + } `json:"block_id"` + } + + // stdout, stderr, err := node.ExecQuery(ctx, "block", "1", "--log_format=json") // --output breaks celestia ofc.... + + // docker run reece/full-celestia:v0.0.1 celestia-appd q block 1 --node=http://172.17.0.1:26657 + + cmd := []string{"query", "block", "1", "--log_format=json", "--node=http://" + node.HostName() + ":26657"} + stdout, _, err := node.ExecBin(ctx, cmd...) + // if err != nil { + // log.Fatal(err) + // } + fmt.Println("stdout", string(stdout)) + fmt.Println("err", err) + + // put stdout into genesis struct + var g CelestiaBlock + json.Unmarshal(stdout, &g) + + if g.BlockID.Hash == "" { + if attempt > 15 { + panic("could not get genesis block hash") + } + time.Sleep(1 * time.Second) + return getGenesisBlockHash(ctx, node, attempt+1) + } + + return g.BlockID.Hash +}