diff --git a/.github/workflows/contracts.yml b/.github/workflows/contracts.yml index e7f470a2..637cdd7d 100644 --- a/.github/workflows/contracts.yml +++ b/.github/workflows/contracts.yml @@ -22,9 +22,16 @@ jobs: uses: cachix/install-nix-action@5c11eae19dba042788936d4f1c9685fdd814ac49 # v19 with: nix_path: nixpkgs=channel:nixos-unstable + extra_nix_config: "sandbox = false" + + - name: Cache Nix + uses: cachix/cachix-action@v12 + with: + name: chainlink-cosmos + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' # TODO: We probably want cachix enabled heres - # https://github.com/smartcontractkit/chainlink-terra/issues/15 + # https://github.com/smartcontractkit/chainlink-cosmos/issues/15 - name: Run unit tests run: nix develop -c cargo unit-test --locked @@ -47,6 +54,13 @@ jobs: uses: cachix/install-nix-action@5c11eae19dba042788936d4f1c9685fdd814ac49 # v19 with: nix_path: nixpkgs=channel:nixos-unstable + extra_nix_config: "sandbox = false" + + - name: Cache Nix + uses: cachix/cachix-action@v12 + with: + name: chainlink-cosmos + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - name: Avoid using non-nix rust binaries run: rm -rf ~/.cargo/bin @@ -59,6 +73,6 @@ jobs: - name: Run cargo clippy run: nix develop -c cargo clippy -- -D warnings - + # TODO: Add schema checks # https://github.com/smartcontractkit/chainlink-terra/issues/17 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 67847c92..f2c65e87 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -38,7 +38,7 @@ on: QA_KUBECONFIG: required: true description: The kubernetes configuation to use - + jobs: e2e_build_contracts: name: E2E Build Contracts @@ -82,6 +82,13 @@ jobs: uses: cachix/install-nix-action@5c11eae19dba042788936d4f1c9685fdd814ac49 # v19 with: nix_path: nixpkgs=channel:nixos-unstable + extra_nix_config: "sandbox = false" + + - name: Cache Nix + uses: cachix/cachix-action@v12 + with: + name: chainlink-cosmos + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 diff --git a/.github/workflows/e2e_custom_cl.yml b/.github/workflows/e2e_custom_cl.yml index 2fef33af..d49f1dfa 100644 --- a/.github/workflows/e2e_custom_cl.yml +++ b/.github/workflows/e2e_custom_cl.yml @@ -61,6 +61,12 @@ jobs: uses: cachix/install-nix-action@5c11eae19dba042788936d4f1c9685fdd814ac49 # v19 with: nix_path: nixpkgs=channel:nixos-unstable + extra_nix_config: "sandbox = false" + - name: Cache Nix + uses: cachix/cachix-action@v12 + with: + name: chainlink-cosmos + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 with: @@ -118,4 +124,4 @@ jobs: uses: actions/upload-artifact@v2.2.4 with: name: test-logs - path: /home/runner/work/chainlink-terra/chainlink-terra/tests/e2e/logs \ No newline at end of file + path: /home/runner/work/chainlink-terra/chainlink-terra/tests/e2e/logs diff --git a/.github/workflows/gauntlet.yml b/.github/workflows/gauntlet.yml index d6dc0566..dafcbec7 100644 --- a/.github/workflows/gauntlet.yml +++ b/.github/workflows/gauntlet.yml @@ -15,6 +15,12 @@ jobs: uses: cachix/install-nix-action@5c11eae19dba042788936d4f1c9685fdd814ac49 # v19 with: nix_path: nixpkgs=channel:nixos-unstable + extra_nix_config: "sandbox = false" + - name: Cache Nix + uses: cachix/cachix-action@v12 + with: + name: chainlink-cosmos + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - run: nix develop -c yarn install --frozen-lockfile - run: nix develop -c yarn build @@ -29,6 +35,12 @@ jobs: uses: cachix/install-nix-action@5c11eae19dba042788936d4f1c9685fdd814ac49 # v19 with: nix_path: nixpkgs=channel:nixos-unstable + extra_nix_config: "sandbox = false" + - name: Cache Nix + uses: cachix/cachix-action@v12 + with: + name: chainlink-cosmos + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - run: nix develop -c yarn install --frozen-lockfile - run: nix develop -c yarn lint:format @@ -43,5 +55,11 @@ jobs: uses: cachix/install-nix-action@5c11eae19dba042788936d4f1c9685fdd814ac49 # v19 with: nix_path: nixpkgs=channel:nixos-unstable + extra_nix_config: "sandbox = false" + - name: Cache Nix + uses: cachix/cachix-action@v12 + with: + name: chainlink-cosmos + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - run: nix develop -c yarn install --frozen-lockfile - run: nix develop -c yarn test:ci diff --git a/.github/workflows/relay.yml b/.github/workflows/relay.yml index 6f649bc5..edc69f7e 100644 --- a/.github/workflows/relay.yml +++ b/.github/workflows/relay.yml @@ -30,6 +30,13 @@ jobs: uses: cachix/install-nix-action@5c11eae19dba042788936d4f1c9685fdd814ac49 # v19 with: nix_path: nixpkgs=channel:nixos-unstable + extra_nix_config: "sandbox = false" + + - name: Cache Nix + uses: cachix/cachix-action@v12 + with: + name: chainlink-cosmos + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - name: Compile relay run: nix develop -c go build -v ./pkg/cosmos/... @@ -38,4 +45,4 @@ jobs: run: nix develop -c go test -v ./pkg/cosmos/... - name: Run tests with the race detector enabled - run: nix develop -c go test -v ./pkg/cosmos/... -race -count=10 \ No newline at end of file + run: nix develop -c go test -v ./pkg/cosmos/... -race -count=10 diff --git a/nix.conf b/nix.conf index c7d7291e..b99a32b8 100644 --- a/nix.conf +++ b/nix.conf @@ -1 +1,2 @@ experimental-features = nix-command flakes +sandbox = false diff --git a/packages-ts/gauntlet-terra/src/lib/constants.ts b/packages-ts/gauntlet-terra/src/lib/constants.ts index 9079ccdf..ebbd7c91 100644 --- a/packages-ts/gauntlet-terra/src/lib/constants.ts +++ b/packages-ts/gauntlet-terra/src/lib/constants.ts @@ -1 +1 @@ -export const BIP44_ATOM_PATH = "44'/330'/0'/0/0" +export const BIP44_ATOM_PATH = "44'/118'/0'/0/0" diff --git a/pkg/cosmos/client/client.go b/pkg/cosmos/client/client.go index 35b699a7..9bb0448b 100644 --- a/pkg/cosmos/client/client.go +++ b/pkg/cosmos/client/client.go @@ -58,7 +58,11 @@ var ( func init() { // Extracted from app.MakeEncodingConfig() to ensure that we only call them once, since they race and can panic. std.RegisterLegacyAminoCodec(encodingConfig.Amino) + // This registers base sdk, tx and crypto types, see + // https://github.com/cosmos/cosmos-sdk/blob/47f46643affd7ec7978329c42bac47275ac7e1cc/std/codec.go#L20 std.RegisterInterfaces(encodingConfig.InterfaceRegistry) + // needed for Client.Account() to deserialize authtypes.AccountI + authtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) // NOTE: bech32 is configured globally, blocked on https://github.com/cosmos/cosmos-sdk/issues/13140 config := sdk.GetConfig() diff --git a/pkg/cosmos/client/client_test.go b/pkg/cosmos/client/client_test.go index a447a2c4..4d44690b 100644 --- a/pkg/cosmos/client/client_test.go +++ b/pkg/cosmos/client/client_test.go @@ -49,7 +49,7 @@ func TestBatchSim(t *testing.T) { return func() { assert.Len(t, logs.TakeAll(), l) } } - contract := DeployTestContract(t, tendermintURL, accounts[0], accounts[0], tc, testdir, "../testdata/my_first_contract.wasm") + contract := DeployTestContract(t, tendermintURL, "42", accounts[0], accounts[0], tc, testdir, "../testdata/my_first_contract.wasm") var succeed sdk.Msg = &wasmtypes.MsgExecuteContract{Sender: accounts[0].Address.String(), Contract: contract.String(), Msg: []byte(`{"reset":{"count":5}}`)} var fail sdk.Msg = &wasmtypes.MsgExecuteContract{Sender: accounts[0].Address.String(), Contract: contract.String(), Msg: []byte(`{"blah":{"count":5}}`)} @@ -132,7 +132,7 @@ func TestCosmosClient(t *testing.T) { gpe := NewFixedGasPriceEstimator(map[string]sdk.DecCoin{ "ucosm": sdk.NewDecCoinFromDec("ucosm", sdk.MustNewDecFromStr("0.01")), }) - contract := DeployTestContract(t, tendermintURL, accounts[0], accounts[0], tc, testdir, "../testdata/my_first_contract.wasm") + contract := DeployTestContract(t, tendermintURL, "42", accounts[0], accounts[0], tc, testdir, "../testdata/my_first_contract.wasm") t.Run("send tx between accounts", func(t *testing.T) { // Assert balance before @@ -239,34 +239,39 @@ func TestCosmosClient(t *testing.T) { // Check events querying works // TxEvents sorts in a descending manner, so latest txes are first - ev, err := tc.TxsEvents([]string{fmt.Sprintf("wasm-reset.contract_address='%s'", contract.String())}, nil) + ev, err := tc.TxsEvents([]string{"wasm.action='reset'", fmt.Sprintf("wasm._contract_address='%s'", contract.String())}, nil) require.NoError(t, err) require.Equal(t, 2, len(ev.TxResponses)) - foundCount := false foundContract := false for _, event := range ev.TxResponses[0].Logs[0].Events { - if event.Type != "wasm-reset" { + if event.Type != "wasm" { continue } + isResetAction := false for _, attr := range event.Attributes { - if attr.Key == "count" { - assert.Equal(t, "4", attr.Value) - foundCount = true + if attr.Key != "action" { + continue } - if attr.Key == "contract_address" { + isResetAction = attr.Value == "reset" + break + } + if !isResetAction { + continue + } + for _, attr := range event.Attributes { + if attr.Key == "_contract_address" { assert.Equal(t, contract.String(), attr.Value) foundContract = true } } } - assert.True(t, foundCount) assert.True(t, foundContract) // Ensure the height filtering works - ev, err = tc.TxsEvents([]string{fmt.Sprintf("tx.height>=%d", resp1.TxResponse.Height+1), fmt.Sprintf("wasm-reset.contract_address='%s'", contract.String())}, nil) + ev, err = tc.TxsEvents([]string{fmt.Sprintf("tx.height>=%d", resp1.TxResponse.Height+1), "wasm.action='reset'", fmt.Sprintf("wasm._contract_address='%s'", contract.String())}, nil) require.NoError(t, err) require.Equal(t, 1, len(ev.TxResponses)) - ev, err = tc.TxsEvents([]string{fmt.Sprintf("tx.height=%d", resp1.TxResponse.Height), fmt.Sprintf("wasm-reset.contract_address='%s'", contract)}, nil) + ev, err = tc.TxsEvents([]string{fmt.Sprintf("tx.height=%d", resp1.TxResponse.Height), "wasm.action='reset'", fmt.Sprintf("wasm._contract_address='%s'", contract)}, nil) require.NoError(t, err) require.Equal(t, 1, len(ev.TxResponses)) for _, ev := range ev.TxResponses[0].Logs[0].Events { diff --git a/pkg/cosmos/client/test_helpers.go b/pkg/cosmos/client/test_helpers.go index 505b007b..acd21025 100644 --- a/pkg/cosmos/client/test_helpers.go +++ b/pkg/cosmos/client/test_helpers.go @@ -9,6 +9,7 @@ import ( "os" "os/exec" "path" + "strings" "testing" "time" @@ -32,16 +33,15 @@ type Account struct { // 0.001 var minGasPrice = sdk.NewDecCoinFromDec("ucosm", sdk.NewDecWithPrec(1, 3)) -// SetupLocalCosmosNode sets up a local terra node via terrad, and returns pre-funded accounts, the test directory, and the url. +// SetupLocalCosmosNode sets up a local terra node via wasmd, and returns pre-funded accounts, the test directory, and the url. func SetupLocalCosmosNode(t *testing.T, chainID string) ([]Account, string, string) { - t.Skip("depends on wasmd") testdir, err := os.MkdirTemp("", "integration-test") require.NoError(t, err) t.Cleanup(func() { require.NoError(t, os.RemoveAll(testdir)) }) t.Log(testdir) - out, err := exec.Command("terrad", "init", "integration-test", "-o", "--chain-id", chainID, "--home", testdir).Output() + out, err := exec.Command("wasmd", "init", "integration-test", "-o", "--chain-id", chainID, "--home", testdir).Output() require.NoError(t, err, string(out)) p := path.Join(testdir, "config", "app.toml") @@ -54,11 +54,23 @@ func SetupLocalCosmosNode(t *testing.T, chainID string) ([]Account, string, stri require.NoError(t, os.WriteFile(p, []byte(config.String()), 0600)) // TODO: could also speed up the block mining config + p = path.Join(testdir, "config", "genesis.json") + f, err = os.ReadFile(p) + require.NoError(t, err) + + genesisData := string(f) + // fix hardcoded token, see + // https://github.com/CosmWasm/wasmd/blob/develop/docker/setup_wasmd.sh + // https://github.com/CosmWasm/wasmd/blob/develop/contrib/local/setup_wasmd.sh + genesisData = strings.ReplaceAll(genesisData, "\"ustake\"", "\"ucosm\"") + genesisData = strings.ReplaceAll(genesisData, "\"stake\"", "\"ucosm\"") + require.NoError(t, os.WriteFile(p, []byte(genesisData), 0600)) + // Create 2 test accounts var accounts []Account for i := 0; i < 2; i++ { account := fmt.Sprintf("test%d", i) - key, err2 := exec.Command("terrad", "keys", "add", account, "--output", "json", "--keyring-backend", "test", "--keyring-dir", testdir).CombinedOutput() + key, err2 := exec.Command("wasmd", "keys", "add", account, "--output", "json", "--keyring-backend", "test", "--home", testdir).CombinedOutput() require.NoError(t, err2, string(key)) var k struct { Address string `json:"address"` @@ -71,7 +83,7 @@ func SetupLocalCosmosNode(t *testing.T, chainID string) ([]Account, string, stri require.NoError(t, err4) require.Equal(t, expAcctAddr, address) // Give it 100 luna - out2, err2 := exec.Command("terrad", "add-genesis-account", k.Address, "100000000ucosm", "--home", testdir).Output() //nolint:gosec + out2, err2 := exec.Command("wasmd", "add-genesis-account", k.Address, "100000000ucosm", "--home", testdir).Output() //nolint:gosec require.NoError(t, err2, string(out2)) accounts = append(accounts, Account{ Name: account, @@ -80,20 +92,22 @@ func SetupLocalCosmosNode(t *testing.T, chainID string) ([]Account, string, stri }) } // Stake 10 luna in first acct - out, err = exec.Command("terrad", "gentx", accounts[0].Name, "10000000ucosm", fmt.Sprintf("--chain-id=%s", chainID), "--keyring-backend", "test", "--keyring-dir", testdir, "--home", testdir).CombinedOutput() //nolint:gosec + out, err = exec.Command("wasmd", "gentx", accounts[0].Name, "10000000ucosm", "--chain-id", chainID, "--keyring-backend", "test", "--home", testdir).CombinedOutput() //nolint:gosec require.NoError(t, err, string(out)) - out, err = exec.Command("terrad", "collect-gentxs", "--home", testdir).CombinedOutput() + out, err = exec.Command("wasmd", "collect-gentxs", "--home", testdir).CombinedOutput() require.NoError(t, err, string(out)) port := mustRandomPort() - tendermintURL := fmt.Sprintf("http://127.0.0.1:%d", port) + tendermintHost := fmt.Sprintf("127.0.0.1:%d", port) + tendermintURL := "http://" + tendermintHost t.Log(tendermintURL) - cmd := exec.Command("terrad", "start", "--home", testdir, - "--rpc.laddr", fmt.Sprintf("tcp://127.0.0.1:%d", port), - "--rpc.pprof_laddr", "0.0.0.0:0", - "--grpc.address", "0.0.0.0:0", - "--grpc-web.address", "0.0.0.0:0", - "--p2p.laddr", "0.0.0.0:0") + + cmd := exec.Command("wasmd", "start", "--home", testdir, + "--rpc.laddr", "tcp://"+tendermintHost, + "--rpc.pprof_laddr", "127.0.0.1:0", + "--grpc.address", "127.0.0.1:0", + "--grpc-web.address", "127.0.0.1:0", + "--p2p.laddr", "127.0.0.1:0") var stdErr bytes.Buffer cmd.Stderr = &stdErr require.NoError(t, cmd.Start()) @@ -101,7 +115,7 @@ func SetupLocalCosmosNode(t *testing.T, chainID string) ([]Account, string, stri assert.NoError(t, cmd.Process.Kill()) if err2 := cmd.Wait(); assert.Error(t, err2) { if !assert.Contains(t, err2.Error(), "signal: killed", cmd.ProcessState.String()) { - t.Log("terrad stderr:", stdErr.String()) + t.Log("wasmd stderr:", stdErr.String()) } } }) @@ -135,10 +149,10 @@ func SetupLocalCosmosNode(t *testing.T, chainID string) ([]Account, string, stri } // DeployTestContract deploys a test contract. -func DeployTestContract(t *testing.T, tendermintURL string, deployAccount, ownerAccount Account, tc *Client, testdir, wasmTestContractPath string) sdk.AccAddress { +func DeployTestContract(t *testing.T, tendermintURL, chainID string, deployAccount, ownerAccount Account, tc *Client, testdir, wasmTestContractPath string) sdk.AccAddress { //nolint:gosec - out, err := exec.Command("terrad", "tx", "wasm", "store", wasmTestContractPath, "--node", tendermintURL, - "--from", deployAccount.Name, "--gas", "auto", "--fees", "100000ucosm", "--chain-id", "42", "--broadcast-mode", "block", "--home", testdir, "--keyring-backend", "test", "--keyring-dir", testdir, "--yes").CombinedOutput() + out, err := exec.Command("wasmd", "tx", "wasm", "store", wasmTestContractPath, "--node", tendermintURL, + "--from", deployAccount.Name, "--gas", "auto", "--fees", "100000ucosm", "--gas-adjustment", "1.3", "--chain-id", chainID, "--broadcast-mode", "block", "--home", testdir, "--keyring-backend", "test", "--keyring-dir", testdir, "--yes", "--output", "json").CombinedOutput() require.NoError(t, err, string(out)) an, sn, err2 := tc.Account(ownerAccount.Address) require.NoError(t, err2) @@ -146,7 +160,9 @@ func DeployTestContract(t *testing.T, tendermintURL string, deployAccount, owner &wasmtypes.MsgInstantiateContract{ Sender: ownerAccount.Address.String(), Admin: "", + // TODO: this only works for the first code deployment, read code_id from the store invocation above and use the value here. CodeID: 1, + Label: "testcontract", Msg: []byte(`{"count":0}`), Funds: sdk.Coins{}, }, @@ -170,7 +186,7 @@ func GetContractAddr(t *testing.T, tc *Client, deploymentHash string) sdk.AccAdd for _, etype := range deploymentTx.TxResponse.Events { if etype.Type == "wasm" { for _, attr := range etype.Attributes { - if string(attr.Key) == "contract_address" { + if string(attr.Key) == "_contract_address" { contractAddr = string(attr.Value) } } diff --git a/pkg/cosmos/testdata/my_first_contract.wasm b/pkg/cosmos/testdata/my_first_contract.wasm index df62c5ed..e89b47b3 100644 Binary files a/pkg/cosmos/testdata/my_first_contract.wasm and b/pkg/cosmos/testdata/my_first_contract.wasm differ diff --git a/pkg/cosmos/testutil/testutil.go b/pkg/cosmos/testutil/testutil.go index bd165129..8440c09a 100644 --- a/pkg/cosmos/testutil/testutil.go +++ b/pkg/cosmos/testutil/testutil.go @@ -22,9 +22,16 @@ func CreateMnemonic() (string, error) { return bip39.NewMnemonic(entropy) } +// TODO: these should be configurable +var ( + // ATOM coin type + // ref: https://github.com/satoshilabs/slips/blob/master/slip-0044.md + coinType uint32 = 118 +) + // CreateHDPath returns BIP 44 object from account and index parameters. func CreateHDPath(account uint32, index uint32) string { - return hd.CreateHDPath(330, account, index).String() + return hd.CreateHDPath(coinType, account, index).String() } func CreateKeyFromMnemonic(mnemonic string) (cryptotypes.PrivKey, sdk.AccAddress, error) { diff --git a/shell.nix b/shell.nix index 8d6f643f..6a0b5a94 100644 --- a/shell.nix +++ b/shell.nix @@ -12,10 +12,9 @@ pkgs.mkShell { cargo-generate cargo-tarpaulin gcc - # pkg-config - # openssl - - (pkgs.callPackage ./terrad.nix {}) + pkg-config + openssl + cacert # Golang # Keep this golang version in sync with the version in .tool-versions please @@ -25,6 +24,11 @@ pkgs.mkShell { golangci-lint gotools + which + git + gnumake + (pkgs.callPackage ./wasmd.nix {}) + # NodeJS + TS nodePackages.typescript nodePackages.typescript-language-server diff --git a/terrad.nix b/terrad.nix deleted file mode 100644 index f4bd0036..00000000 --- a/terrad.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ stdenv, lib -, fetchurl -#, autoPatchelfHook -}: - -stdenv.mkDerivation rec { - name = "terrad-${version}"; - version = "2.0.1"; - - src = fetchurl { - url = "https://github.com/terra-money/core/releases/download/v${version}/terra_${version}_Linux_x86_64.tar.gz"; - sha256 = "sha256-6uI6rVmzbqKtqlQadmKmEZVpJ50ubEAT497ulukmOzA="; - }; - - # nativeBuildInputs = [ - # autoPatchelfHook - # ]; - - sourceRoot = "."; - - installPhase = '' - install -m755 -D terrad $out/bin/terrad - ''; -} diff --git a/wasmd.nix b/wasmd.nix new file mode 100644 index 00000000..ca1da5e3 --- /dev/null +++ b/wasmd.nix @@ -0,0 +1,24 @@ +{ stdenv, pkgs, lib +, fetchFromGitHub +}: + +stdenv.mkDerivation rec { + name = "wasmd-${version}"; + version = "0.3.0"; + + src = fetchFromGitHub { + owner = "CosmWasm"; + repo = "wasmd"; + rev = "d48bb69b391edf92228708008dcd5bbe47b83128"; + sha256 = "07nprps0da81krpl2a66qn823ybzghnx55zw7504wpynhgfa0bll"; + }; + + buildInputs = with pkgs; [ gnumake git go_1_20 which openssl cacert ]; + + buildPhase = '' + export HOME=$out + cd $src && make install + ''; + + installPhase = "ln -s go/bin $out/bin"; +}