diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 14f0a57b9..a1a661411 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -4,7 +4,7 @@ on: [push] jobs: Enclave-Unit-Tests: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - name: Install Intel's SGX SDK @@ -35,7 +35,7 @@ jobs: run: | cargo --version rustc --version - cargo +stable install xargo + cargo +stable install xargo --version 0.3.25 xargo --version - name: Download sccache run: | @@ -51,7 +51,7 @@ jobs: make clean-enclave Build: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - uses: actions/setup-go@v2 @@ -85,7 +85,7 @@ jobs: run: | cargo --version rustc --version - cargo +stable install xargo + cargo +stable install xargo --version 0.3.25 xargo --version - name: Download sccache run: | @@ -150,7 +150,7 @@ jobs: path: ./x/compute/internal/keeper/testdata/test-contract/static-too-high-initial-memory.wasm Go-Tests: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 needs: Build steps: - uses: actions/checkout@v2 @@ -208,7 +208,7 @@ jobs: LOG_LEVEL=ERROR go test -p 1 -timeout 20m -v ./x/compute/internal/... Clippy: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - name: Install Intel's SGX SDK @@ -239,7 +239,7 @@ jobs: run: | cargo --version rustc --version - cargo +stable install xargo + cargo +stable install xargo --version 0.3.25 xargo --version - name: Download sccache run: | @@ -255,7 +255,7 @@ jobs: SGX_MODE=HW make clippy XBuild-CLI: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - uses: actions/setup-go@v2 @@ -271,7 +271,7 @@ jobs: run: make build_windows_cli Integration-Tests: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - name: Build docker testnet diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index aa3c78ab8..bb79d6ea5 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -14,7 +14,7 @@ jobs: fail-fast: false matrix: db_backend: [rocksdb, goleveldb] - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 env: # Or as an environment variable SPID_TESTNET: ${{ secrets.SPID_TESTNET }} API_KEY_TESTNET: ${{ secrets.API_KEY_TESTNET }} @@ -55,7 +55,7 @@ jobs: - run: rustup component add rust-src clippy - name: Install xargo run: | - cargo +stable install xargo + cargo +stable install xargo --version 0.3.25 xargo --version - name: Download sccache run: | @@ -80,7 +80,7 @@ jobs: path: secretnetwork_${{ steps.get_version.outputs.VERSION }}_testnet_${{ matrix.db_backend }}_amd64.deb build-deb-mainnet: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 strategy: fail-fast: false matrix: @@ -125,7 +125,7 @@ jobs: runs-on: ${{matrix.os}} strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-20.04, windows-latest, macos-latest] steps: - uses: actions/checkout@v3 - name: Build CLI @@ -139,7 +139,7 @@ jobs: path: secretcli-${{runner.os}} x-build-cli: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v2 @@ -160,7 +160,7 @@ jobs: path: secretcli-MacOS-arm64 publish-localsecret: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 env: REGISTRY: ghcr.io IMAGE_NAME: scrtlabs/localsecret @@ -189,7 +189,7 @@ jobs: Release: needs: [native-build-cli, build-deb-testnet, build-deb-mainnet, x-build-cli] - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - name: Get the version diff --git a/deployment/ci/docker-compose.ci.yaml b/deployment/ci/docker-compose.ci.yaml index a9ef99e8d..3b9451dbf 100644 --- a/deployment/ci/docker-compose.ci.yaml +++ b/deployment/ci/docker-compose.ci.yaml @@ -2,7 +2,7 @@ version: '3' services: aesm: - image: enigmampc/aesm + image: fortanix/aesmd:2.13.103.1-1 devices: - /dev/sgx/enclave - /dev/sgx/provision @@ -20,8 +20,9 @@ services: - aesm devices: - /dev/sgx/enclave + - /dev/sgx/provision volumes: - - /var/run/aesmd:/var/run/aesmd + - /tmp/aesmd:/var/run/aesmd - /tmp/secretd:/root/.secretd - /tmp/secretcli:/root/.secretcli stdin_open: true @@ -39,8 +40,9 @@ services: - aesm devices: - /dev/sgx/enclave + - /dev/sgx/provision volumes: - - /var/run/aesmd:/var/run/aesmd + - /tmp/aesmd:/var/run/aesmd - /tmp/secretd:/root/.secretd # - /tmp/secretcli:/root/.secretcli stdin_open: true @@ -58,8 +60,9 @@ services: - bootstrap devices: - /dev/sgx/enclave + - /dev/sgx/provision volumes: - - /var/run/aesmd:/var/run/aesmd + - /tmp/aesmd:/var/run/aesmd - /tmp/secretd:/tmp/.secretd # - /tmp/secretcli:/root/.secretcli stdin_open: true @@ -74,8 +77,9 @@ services: - aesm devices: - /dev/sgx/enclave + - /dev/sgx/provision volumes: - - /var/run/aesmd:/var/run/aesmd + - /tmp/aesmd:/var/run/aesmd - /tmp/secretd:/tmp/.secretd - /tmp/secretcli:/root/.secretcli stdin_open: true diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index 0eadac156..0a47d9ba4 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -28,9 +28,23 @@ import ( type ContractEvent []v010cosmwasm.LogAttribute +type TestContract struct { + CosmWasmVersion string + WasmFilePath string +} + +var testContracts = []TestContract{ + { + CosmWasmVersion: "v0.10", + WasmFilePath: "./testdata/test-contract/contract.wasm", + }, { + CosmWasmVersion: "v1", + WasmFilePath: "./testdata/v1-sanity-contract/contract.wasm", + }, +} + // if codeID isn't 0, it will try to use that. Otherwise will take the contractAddress func testEncrypt(t *testing.T, keeper Keeper, ctx sdk.Context, contractAddress sdk.AccAddress, codeId uint64, msg []byte) ([]byte, error) { - var hash []byte if codeId != 0 { hash = keeper.GetCodeInfo(ctx, codeId).CodeHash @@ -224,27 +238,34 @@ func (wasmGasMeter *WasmCounterGasMeter) RefundGas(amount stypes.Gas, descriptor func (wasmGasMeter *WasmCounterGasMeter) GasConsumed() sdk.Gas { return wasmGasMeter.gasMeter.GasConsumed() } + func (wasmGasMeter *WasmCounterGasMeter) GasConsumedToLimit() sdk.Gas { return wasmGasMeter.gasMeter.GasConsumedToLimit() } + func (wasmGasMeter *WasmCounterGasMeter) Limit() sdk.Gas { return wasmGasMeter.gasMeter.Limit() } + func (wasmGasMeter *WasmCounterGasMeter) ConsumeGas(amount sdk.Gas, descriptor string) { if (descriptor == "wasm contract" || descriptor == "contract sub-query") && amount > 0 { wasmGasMeter.wasmCounter++ } wasmGasMeter.gasMeter.ConsumeGas(amount, descriptor) } + func (wasmGasMeter *WasmCounterGasMeter) IsPastLimit() bool { return wasmGasMeter.gasMeter.IsPastLimit() } + func (wasmGasMeter *WasmCounterGasMeter) IsOutOfGas() bool { return wasmGasMeter.gasMeter.IsOutOfGas() } + func (wasmGasMeter *WasmCounterGasMeter) String() string { return fmt.Sprintf("WasmCounterGasMeter: %+v %+v", wasmGasMeter.wasmCounter, wasmGasMeter.gasMeter) } + func (wasmGasMeter *WasmCounterGasMeter) GetWasmCounter() uint64 { return wasmGasMeter.wasmCounter } @@ -431,42 +452,46 @@ func initHelperImpl( } func TestCallbackSanity(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - // init - contractAddress, initEvents, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) - - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "init", Value: "🌈"}, - }, - }, - initEvents, - ) - - data, execEvents, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"a":{"contract_addr":"%s","code_hash":"%s","x":2,"y":3}}`, contractAddress.String(), codeHash), true, false, defaultGasForTests, 0) - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "banana", Value: "🍌"}, - }, - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "kiwi", Value: "🥝"}, - }, - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "watermelon", Value: "🍉"}, - }, - }, - execEvents, - ) - require.Equal(t, []byte{2, 3}, data) + for _, testContract := range testContracts { + t.Run(testContract.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, testContract.WasmFilePath) + + // init + contractAddress, initEvents, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) + + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "init", Value: "🌈"}, + }, + }, + initEvents, + ) + + data, execEvents, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"a":{"contract_addr":"%s","code_hash":"%s","x":2,"y":3}}`, contractAddress.String(), codeHash), true, false, defaultGasForTests, 0) + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "banana", Value: "🍌"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "kiwi", Value: "🥝"}, + }, + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "watermelon", Value: "🍉"}, + }, + }, + execEvents, + ) + require.Equal(t, []byte{2, 3}, data) + }) + } } func TestSanity(t *testing.T) { @@ -477,7 +502,7 @@ func TestSanity(t *testing.T) { contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, initMsg, true, false, defaultGasForTests) require.Empty(t, err) - //require.Empty(t, initEvents) + // require.Empty(t, initEvents) // check state after init qRes, qErr := queryHelper(t, keeper, ctx, contractAddress, fmt.Sprintf(`{"balance":{"address":"%s"}}`, walletA.String()), true, false, defaultGasForTests) @@ -517,120 +542,148 @@ func TestSanity(t *testing.T) { } func TestInitLogs(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - require.Equal(t, 1, len(initEvents)) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "init", Value: "🌈"}, - }, - }, - initEvents, - ) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + require.Equal(t, 1, len(initEvents)) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "init", Value: "🌈"}, + }, + }, + initEvents, + ) + }) + } } func TestEmptyLogKeyValue(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - - _, execEvents, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"empty_log_key_value":{}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, execErr) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "my value is empty", Value: ""}, - {Key: "", Value: "my key is empty"}, - }, - }, - execEvents, - ) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + + _, execEvents, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"empty_log_key_value":{}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, execErr) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "my value is empty", Value: ""}, + {Key: "", Value: "my key is empty"}, + }, + }, + execEvents, + ) + }) + } } func TestEmptyData(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"empty_data":{}}`, true, false, defaultGasForTests, 0) + data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"empty_data":{}}`, true, false, defaultGasForTests, 0) - require.Empty(t, err) - require.Empty(t, data) + require.Empty(t, err) + require.Empty(t, data) + }) + } } func TestNoData(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"no_data":{}}`, true, false, defaultGasForTests, 0) + data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"no_data":{}}`, true, false, defaultGasForTests, 0) - require.Empty(t, err) - require.Empty(t, data) + require.Empty(t, err) + require.Empty(t, data) + }) + } } func TestExecuteIllegalInputError(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - _, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `bad input`, true, false, defaultGasForTests, 0) + _, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `bad input`, true, false, defaultGasForTests, 0) - require.NotNil(t, execErr.ParseErr) + require.NotNil(t, execErr.ParseErr) + }) + } } func TestInitIllegalInputError(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `bad input`, true, false, defaultGasForTests) + _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `bad input`, true, false, defaultGasForTests) - require.NotNil(t, initErr.ParseErr) + require.NotNil(t, initErr.ParseErr) + }) + } } func TestCallbackFromInitAndCallbackEvents(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - // init first contract so we'd have someone to callback - firstContractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: firstContractAddress.String()}, - {Key: "init", Value: "🌈"}, - }, - }, - initEvents, - ) - - // init second contract and callback to the first contract - contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback":{"contract_addr":"%s", "code_hash": "%s"}}`, firstContractAddress.String(), codeHash), true, false, defaultGasForTests) - require.Empty(t, initErr) - - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "init with a callback", Value: "🦄"}, - }, - { - {Key: "contract_address", Value: firstContractAddress.String()}, - {Key: "watermelon", Value: "🍉"}, - }, - }, - initEvents, - ) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + // init first contract so we'd have someone to callback + firstContractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: firstContractAddress.String()}, + {Key: "init", Value: "🌈"}, + }, + }, + initEvents, + ) + + // init second contract and callback to the first contract + contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback":{"contract_addr":"%s", "code_hash": "%s"}}`, firstContractAddress.String(), codeHash), true, false, defaultGasForTests) + require.Empty(t, initErr) + + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "init with a callback", Value: "🦄"}, + }, + { + {Key: "contract_address", Value: firstContractAddress.String()}, + {Key: "watermelon", Value: "🍉"}, + }, + }, + initEvents, + ) + }) + } } func TestQueryInputParamError(t *testing.T) { @@ -641,7 +694,7 @@ func TestQueryInputParamError(t *testing.T) { contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, initMsg, true, false, defaultGasForTests) require.Empty(t, err) - //require.Empty(t, initEvents) + // require.Empty(t, initEvents) _, qErr := queryHelper(t, keeper, ctx, contractAddress, `{"balance":{"address":"blabla"}}`, true, false, defaultGasForTests) @@ -650,210 +703,234 @@ func TestQueryInputParamError(t *testing.T) { } func TestUnicodeData(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"unicode_data":{}}`, true, false, defaultGasForTests, 0) + data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"unicode_data":{}}`, true, false, defaultGasForTests, 0) - require.Empty(t, err) - require.Equal(t, "🍆🥑🍄", string(data)) + require.Empty(t, err) + require.Equal(t, "🍆🥑🍄", string(data)) + }) + } } func TestInitContractError(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - t.Run("generic_err", func(t *testing.T) { - _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"generic_err"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.GenericErr) - require.Equal(t, "la la 🤯", err.GenericErr.Msg) - }) - t.Run("invalid_base64", func(t *testing.T) { - _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"invalid_base64"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.InvalidBase64) - require.Equal(t, "ra ra 🤯", err.InvalidBase64.Msg) - }) - t.Run("invalid_utf8", func(t *testing.T) { - _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"invalid_utf8"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.InvalidUtf8) - require.Equal(t, "ka ka 🤯", err.InvalidUtf8.Msg) - }) - t.Run("not_found", func(t *testing.T) { - _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"not_found"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.NotFound) - require.Equal(t, "za za 🤯", err.NotFound.Kind) - }) - t.Run("parse_err", func(t *testing.T) { - _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"parse_err"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.ParseErr) - require.Equal(t, "na na 🤯", err.ParseErr.Target) - require.Equal(t, "pa pa 🤯", err.ParseErr.Msg) - }) - t.Run("serialize_err", func(t *testing.T) { - _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"serialize_err"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.SerializeErr) - require.Equal(t, "ba ba 🤯", err.SerializeErr.Source) - require.Equal(t, "ga ga 🤯", err.SerializeErr.Msg) - }) - t.Run("unauthorized", func(t *testing.T) { - _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"unauthorized"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.Unauthorized) - }) - t.Run("underflow", func(t *testing.T) { - _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"underflow"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.Underflow) - require.Equal(t, "minuend 🤯", err.Underflow.Minuend) - require.Equal(t, "subtrahend 🤯", err.Underflow.Subtrahend) - }) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + t.Run("generic_err", func(t *testing.T) { + _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"generic_err"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.GenericErr) + require.Equal(t, "la la 🤯", err.GenericErr.Msg) + }) + t.Run("invalid_base64", func(t *testing.T) { + _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"invalid_base64"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.InvalidBase64) + require.Equal(t, "ra ra 🤯", err.InvalidBase64.Msg) + }) + t.Run("invalid_utf8", func(t *testing.T) { + _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"invalid_utf8"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.InvalidUtf8) + require.Equal(t, "ka ka 🤯", err.InvalidUtf8.Msg) + }) + t.Run("not_found", func(t *testing.T) { + _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"not_found"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.NotFound) + require.Equal(t, "za za 🤯", err.NotFound.Kind) + }) + t.Run("parse_err", func(t *testing.T) { + _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"parse_err"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.ParseErr) + require.Equal(t, "na na 🤯", err.ParseErr.Target) + require.Equal(t, "pa pa 🤯", err.ParseErr.Msg) + }) + t.Run("serialize_err", func(t *testing.T) { + _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"serialize_err"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.SerializeErr) + require.Equal(t, "ba ba 🤯", err.SerializeErr.Source) + require.Equal(t, "ga ga 🤯", err.SerializeErr.Msg) + }) + t.Run("unauthorized", func(t *testing.T) { + _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"unauthorized"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.Unauthorized) + }) + t.Run("underflow", func(t *testing.T) { + _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"contract_error":{"error_type":"underflow"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.Underflow) + require.Equal(t, "minuend 🤯", err.Underflow.Minuend) + require.Equal(t, "subtrahend 🤯", err.Underflow.Subtrahend) + }) + }) + } } func TestExecContractError(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - contractAddr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - - t.Run("generic_err", func(t *testing.T) { - _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"generic_err"}}`, true, false, defaultGasForTests, 0) - - require.NotNil(t, err.GenericErr) - require.Equal(t, "la la 🤯", err.GenericErr.Msg) - }) - t.Run("invalid_base64", func(t *testing.T) { - _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"invalid_base64"}}`, true, false, defaultGasForTests, 0) - - require.NotNil(t, err.InvalidBase64) - require.Equal(t, "ra ra 🤯", err.InvalidBase64.Msg) - }) - t.Run("invalid_utf8", func(t *testing.T) { - _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"invalid_utf8"}}`, true, false, defaultGasForTests, 0) - - require.NotNil(t, err.InvalidUtf8) - require.Equal(t, "ka ka 🤯", err.InvalidUtf8.Msg) - }) - t.Run("not_found", func(t *testing.T) { - _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"not_found"}}`, true, false, defaultGasForTests, 0) - - require.NotNil(t, err.NotFound) - require.Equal(t, "za za 🤯", err.NotFound.Kind) - }) - t.Run("parse_err", func(t *testing.T) { - _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"parse_err"}}`, true, false, defaultGasForTests, 0) - - require.NotNil(t, err.ParseErr) - require.Equal(t, "na na 🤯", err.ParseErr.Target) - require.Equal(t, "pa pa 🤯", err.ParseErr.Msg) - }) - t.Run("serialize_err", func(t *testing.T) { - _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"serialize_err"}}`, true, false, defaultGasForTests, 0) - - require.NotNil(t, err.SerializeErr) - require.Equal(t, "ba ba 🤯", err.SerializeErr.Source) - require.Equal(t, "ga ga 🤯", err.SerializeErr.Msg) - }) - t.Run("unauthorized", func(t *testing.T) { - _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"unauthorized"}}`, true, false, defaultGasForTests, 0) - - require.NotNil(t, err.Unauthorized) - }) - t.Run("underflow", func(t *testing.T) { - _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"underflow"}}`, true, false, defaultGasForTests, 0) - - require.NotNil(t, err.Underflow) - require.Equal(t, "minuend 🤯", err.Underflow.Minuend) - require.Equal(t, "subtrahend 🤯", err.Underflow.Subtrahend) - }) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + contractAddr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + + t.Run("generic_err", func(t *testing.T) { + _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"generic_err"}}`, true, false, defaultGasForTests, 0) + + require.NotNil(t, err.GenericErr) + require.Equal(t, "la la 🤯", err.GenericErr.Msg) + }) + t.Run("invalid_base64", func(t *testing.T) { + _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"invalid_base64"}}`, true, false, defaultGasForTests, 0) + + require.NotNil(t, err.InvalidBase64) + require.Equal(t, "ra ra 🤯", err.InvalidBase64.Msg) + }) + t.Run("invalid_utf8", func(t *testing.T) { + _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"invalid_utf8"}}`, true, false, defaultGasForTests, 0) + + require.NotNil(t, err.InvalidUtf8) + require.Equal(t, "ka ka 🤯", err.InvalidUtf8.Msg) + }) + t.Run("not_found", func(t *testing.T) { + _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"not_found"}}`, true, false, defaultGasForTests, 0) + + require.NotNil(t, err.NotFound) + require.Equal(t, "za za 🤯", err.NotFound.Kind) + }) + t.Run("parse_err", func(t *testing.T) { + _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"parse_err"}}`, true, false, defaultGasForTests, 0) + + require.NotNil(t, err.ParseErr) + require.Equal(t, "na na 🤯", err.ParseErr.Target) + require.Equal(t, "pa pa 🤯", err.ParseErr.Msg) + }) + t.Run("serialize_err", func(t *testing.T) { + _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"serialize_err"}}`, true, false, defaultGasForTests, 0) + + require.NotNil(t, err.SerializeErr) + require.Equal(t, "ba ba 🤯", err.SerializeErr.Source) + require.Equal(t, "ga ga 🤯", err.SerializeErr.Msg) + }) + t.Run("unauthorized", func(t *testing.T) { + _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"unauthorized"}}`, true, false, defaultGasForTests, 0) + + require.NotNil(t, err.Unauthorized) + }) + t.Run("underflow", func(t *testing.T) { + _, _, _, err := execHelper(t, keeper, ctx, contractAddr, walletA, privKeyA, `{"contract_error":{"error_type":"underflow"}}`, true, false, defaultGasForTests, 0) + + require.NotNil(t, err.Underflow) + require.Equal(t, "minuend 🤯", err.Underflow.Minuend) + require.Equal(t, "subtrahend 🤯", err.Underflow.Subtrahend) + }) + }) + } } func TestQueryContractError(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - contractAddr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - - t.Run("generic_err", func(t *testing.T) { - _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"generic_err"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.GenericErr) - require.Equal(t, "la la 🤯", err.GenericErr.Msg) - }) - t.Run("invalid_base64", func(t *testing.T) { - _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"invalid_base64"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.InvalidBase64) - require.Equal(t, "ra ra 🤯", err.InvalidBase64.Msg) - }) - t.Run("invalid_utf8", func(t *testing.T) { - _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"invalid_utf8"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.InvalidUtf8) - require.Equal(t, "ka ka 🤯", err.InvalidUtf8.Msg) - }) - t.Run("not_found", func(t *testing.T) { - _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"not_found"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.NotFound) - require.Equal(t, "za za 🤯", err.NotFound.Kind) - }) - t.Run("parse_err", func(t *testing.T) { - _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"parse_err"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.ParseErr) - require.Equal(t, "na na 🤯", err.ParseErr.Target) - require.Equal(t, "pa pa 🤯", err.ParseErr.Msg) - }) - t.Run("serialize_err", func(t *testing.T) { - _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"serialize_err"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.SerializeErr) - require.Equal(t, "ba ba 🤯", err.SerializeErr.Source) - require.Equal(t, "ga ga 🤯", err.SerializeErr.Msg) - }) - t.Run("unauthorized", func(t *testing.T) { - _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"unauthorized"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.Unauthorized) - }) - t.Run("underflow", func(t *testing.T) { - _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"underflow"}}`, true, false, defaultGasForTests) - - require.NotNil(t, err.Underflow) - require.Equal(t, "minuend 🤯", err.Underflow.Minuend) - require.Equal(t, "subtrahend 🤯", err.Underflow.Subtrahend) - }) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + contractAddr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + + t.Run("generic_err", func(t *testing.T) { + _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"generic_err"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.GenericErr) + require.Equal(t, "la la 🤯", err.GenericErr.Msg) + }) + t.Run("invalid_base64", func(t *testing.T) { + _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"invalid_base64"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.InvalidBase64) + require.Equal(t, "ra ra 🤯", err.InvalidBase64.Msg) + }) + t.Run("invalid_utf8", func(t *testing.T) { + _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"invalid_utf8"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.InvalidUtf8) + require.Equal(t, "ka ka 🤯", err.InvalidUtf8.Msg) + }) + t.Run("not_found", func(t *testing.T) { + _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"not_found"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.NotFound) + require.Equal(t, "za za 🤯", err.NotFound.Kind) + }) + t.Run("parse_err", func(t *testing.T) { + _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"parse_err"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.ParseErr) + require.Equal(t, "na na 🤯", err.ParseErr.Target) + require.Equal(t, "pa pa 🤯", err.ParseErr.Msg) + }) + t.Run("serialize_err", func(t *testing.T) { + _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"serialize_err"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.SerializeErr) + require.Equal(t, "ba ba 🤯", err.SerializeErr.Source) + require.Equal(t, "ga ga 🤯", err.SerializeErr.Msg) + }) + t.Run("unauthorized", func(t *testing.T) { + _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"unauthorized"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.Unauthorized) + }) + t.Run("underflow", func(t *testing.T) { + _, err := queryHelper(t, keeper, ctx, contractAddr, `{"contract_error":{"error_type":"underflow"}}`, true, false, defaultGasForTests) + + require.NotNil(t, err.Underflow) + require.Equal(t, "minuend 🤯", err.Underflow.Minuend) + require.Equal(t, "subtrahend 🤯", err.Underflow.Subtrahend) + }) + }) + } } func TestInitParamError(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - codeHash := "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - msg := fmt.Sprintf(`{"callback":{"contract_addr":"notanaddress", "code_hash":"%s"}}`, codeHash) + codeHash := "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + msg := fmt.Sprintf(`{"callback":{"contract_addr":"notanaddress", "code_hash":"%s"}}`, codeHash) - _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, msg, false, false, defaultGasForTests) + _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, msg, false, false, defaultGasForTests) - require.Contains(t, initErr.Error(), "invalid address") + require.Contains(t, initErr.Error(), "invalid address") + }) + } } func TestCallbackExecuteParamError(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - msg := fmt.Sprintf(`{"a":{"code_hash":"%s","contract_addr":"notanaddress","x":2,"y":3}}`, codeHash) + msg := fmt.Sprintf(`{"a":{"code_hash":"%s","contract_addr":"notanaddress","x":2,"y":3}}`, codeHash) - _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, msg, false, false, defaultGasForTests, 0) + _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, msg, false, false, defaultGasForTests, 0) - require.Contains(t, err.Error(), "invalid address") + require.Contains(t, err.Error(), "invalid address") + }) + } } func TestQueryInputStructureError(t *testing.T) { @@ -864,7 +941,7 @@ func TestQueryInputStructureError(t *testing.T) { contractAddress, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, initMsg, true, false, defaultGasForTests) require.Empty(t, err) - //require.Empty(t, initEvents) + // require.Empty(t, initEvents) _, qErr := queryHelper(t, keeper, ctx, contractAddress, `{"balance":{"invalidkey":"invalidval"}}`, true, false, defaultGasForTests) @@ -873,830 +950,1022 @@ func TestQueryInputStructureError(t *testing.T) { } func TestInitNotEncryptedInputError(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKey, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKey, _, _ := setupTest(t, tc.WasmFilePath) - //ctx = sdk.NewContext( - // ctx.MultiStore(), - // ctx.BlockHeader(), - // ctx.IsCheckTx(), - // log.NewNopLogger(), - //).WithGasMeter(sdk.NewGasMeter(defaultGas)) + //ctx = sdk.NewContext( + // ctx.MultiStore(), + // ctx.BlockHeader(), + // ctx.IsCheckTx(), + // log.NewNopLogger(), + //).WithGasMeter(sdk.NewGasMeter(defaultGas)) - initMsg := []byte(`{"nop":{}`) + initMsg := []byte(`{"nop":{}`) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privKey, initMsg, codeID, nil) + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privKey, initMsg, codeID, nil) - // init - _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, initMsg, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - require.Error(t, err) + // init + _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, initMsg, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + require.Error(t, err) - require.Contains(t, err.Error(), "failed to decrypt data") + require.Contains(t, err.Error(), "failed to decrypt data") + }) + } } func TestExecuteNotEncryptedInputError(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - //ctx = sdk.NewContext( - // ctx.MultiStore(), - // ctx.BlockHeader(), - // ctx.IsCheckTx(), - // log.NewNopLogger(), - //).WithGasMeter(sdk.NewGasMeter(defaultGas)) + //ctx = sdk.NewContext( + // ctx.MultiStore(), + // ctx.BlockHeader(), + // ctx.IsCheckTx(), + // log.NewNopLogger(), + //).WithGasMeter(sdk.NewGasMeter(defaultGas)) - execMsg := []byte(`{"empty_log_key_value":{}}`) + execMsg := []byte(`{"empty_log_key_value":{}}`) - ctx = PrepareExecSignedTx(t, keeper, ctx, walletA, privKeyA, execMsg, contractAddress, nil) + ctx = PrepareExecSignedTx(t, keeper, ctx, walletA, privKeyA, execMsg, contractAddress, nil) - _, err := keeper.Execute(ctx, contractAddress, walletA, execMsg, sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - require.Error(t, err) + _, err := keeper.Execute(ctx, contractAddress, walletA, execMsg, sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + require.Error(t, err) - require.Contains(t, err.Error(), "failed to decrypt data") + require.Contains(t, err.Error(), "failed to decrypt data") + }) + } } func TestQueryNotEncryptedInputError(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - _, err := keeper.QuerySmart(ctx, contractAddress, []byte(`{"owner":{}}`), false) - require.Error(t, err) + _, err := keeper.QuerySmart(ctx, contractAddress, []byte(`{"owner":{}}`), false) + require.Error(t, err) - require.Contains(t, err.Error(), "failed to decrypt data") + require.Contains(t, err.Error(), "failed to decrypt data") + }) + } } func TestInitNoLogs(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - // init - _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"no_logs":{}}`, true, false, defaultGasForTests) + // init + _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"no_logs":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - ////require.Empty(t, initEvents) + require.Empty(t, initErr) + ////require.Empty(t, initEvents) + }) + } } func TestExecNoLogs(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - // init - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + // init + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"no_logs":{}}`, true, false, defaultGasForTests, 0) + _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"no_logs":{}}`, true, false, defaultGasForTests, 0) - require.Empty(t, err) - //require.Empty(t, execEvents) + require.Empty(t, err) + // require.Empty(t, execEvents) + }) + } } func TestExecCallbackToInit(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - // init first contract - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - - // init second contract and callback to the first contract - execData, execEvents, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"callback_to_init":{"code_id":%d, "code_hash":"%s"}}`, codeID, codeHash), true, false, defaultGasForTests, 0) - require.Empty(t, execErr) - require.Empty(t, execData) - - require.Equal(t, 2, len(execEvents)) - require.Equal(t, - ContractEvent{ - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "instantiating a new contract", Value: "🪂"}, - }, - execEvents[0], - ) - require.Equal(t, - v010cosmwasm.LogAttribute{Key: "init", Value: "🌈"}, - execEvents[1][1], - ) - require.Equal(t, "contract_address", execEvents[1][0].Key) - - secondContractAddressBech32 := execEvents[1][0].Value - secondContractAddress, err := sdk.AccAddressFromBech32(secondContractAddressBech32) - require.NoError(t, err) - - data, _, _, err := execHelper(t, keeper, ctx, secondContractAddress, walletA, privKeyA, `{"unicode_data":{}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - //require.Empty(t, execEvents) - require.Equal(t, "🍆🥑🍄", string(data)) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + // init first contract + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + + // init second contract and callback to the first contract + execData, execEvents, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"callback_to_init":{"code_id":%d, "code_hash":"%s"}}`, codeID, codeHash), true, false, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Empty(t, execData) + + require.Equal(t, 2, len(execEvents)) + require.Equal(t, + ContractEvent{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "instantiating a new contract", Value: "🪂"}, + }, + execEvents[0], + ) + require.Equal(t, + v010cosmwasm.LogAttribute{Key: "init", Value: "🌈"}, + execEvents[1][1], + ) + require.Equal(t, "contract_address", execEvents[1][0].Key) + + secondContractAddressBech32 := execEvents[1][0].Value + secondContractAddress, err := sdk.AccAddressFromBech32(secondContractAddressBech32) + require.NoError(t, err) + + data, _, _, err := execHelper(t, keeper, ctx, secondContractAddress, walletA, privKeyA, `{"unicode_data":{}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + // require.Empty(t, execEvents) + require.Equal(t, "🍆🥑🍄", string(data)) + }) + } } func TestInitCallbackToInit(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback_to_init":{"code_id":%d, "code_hash":"%s"}}`, codeID, codeHash), true, false, defaultGasForTests) - require.Empty(t, initErr) - - require.Equal(t, 2, len(initEvents)) - require.Equal(t, - ContractEvent{ - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "instantiating a new contract from init!", Value: "🐙"}, - }, - initEvents[0], - ) - require.Equal(t, - v010cosmwasm.LogAttribute{Key: "init", Value: "🌈"}, - initEvents[1][1], - ) - require.Equal(t, "contract_address", initEvents[1][0].Key) - - secondContractAddressBech32 := initEvents[1][0].Value - secondContractAddress, err := sdk.AccAddressFromBech32(secondContractAddressBech32) - require.NoError(t, err) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - data, _, _, err := execHelper(t, keeper, ctx, secondContractAddress, walletA, privKeyA, `{"unicode_data":{}}`, true, false, defaultGasForTests, 0) + contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback_to_init":{"code_id":%d, "code_hash":"%s"}}`, codeID, codeHash), true, false, defaultGasForTests) + require.Empty(t, initErr) - require.Empty(t, err) - //require.Empty(t, execEvents) - require.Equal(t, "🍆🥑🍄", string(data)) + require.Equal(t, 2, len(initEvents)) + require.Equal(t, + ContractEvent{ + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "instantiating a new contract from init!", Value: "🐙"}, + }, + initEvents[0], + ) + require.Equal(t, + v010cosmwasm.LogAttribute{Key: "init", Value: "🌈"}, + initEvents[1][1], + ) + require.Equal(t, "contract_address", initEvents[1][0].Key) + + secondContractAddressBech32 := initEvents[1][0].Value + secondContractAddress, err := sdk.AccAddressFromBech32(secondContractAddressBech32) + require.NoError(t, err) + + data, _, _, err := execHelper(t, keeper, ctx, secondContractAddress, walletA, privKeyA, `{"unicode_data":{}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + // require.Empty(t, execEvents) + require.Equal(t, "🍆🥑🍄", string(data)) + }) + } } func TestInitCallbackContractError(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - require.Equal(t, 1, len(initEvents)) + contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + require.Equal(t, 1, len(initEvents)) - secondContractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback_contract_error":{"contract_addr":"%s", "code_hash":"%s"}}`, contractAddress, codeHash), true, false, defaultGasForTests) + secondContractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback_contract_error":{"contract_addr":"%s", "code_hash":"%s"}}`, contractAddress, codeHash), true, false, defaultGasForTests) - require.NotNil(t, initErr.GenericErr) - require.Equal(t, "la la 🤯", initErr.GenericErr.Msg) - require.Empty(t, secondContractAddress) - //require.Empty(t, initEvents) + require.NotNil(t, initErr.GenericErr) + require.Equal(t, "la la 🤯", initErr.GenericErr.Msg) + require.Empty(t, secondContractAddress) + // require.Empty(t, initEvents) + }) + } } func TestExecCallbackContractError(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - // init - contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - require.Equal(t, 1, len(initEvents)) + // init + contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + require.Equal(t, 1, len(initEvents)) - data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"callback_contract_error":{"contract_addr":"%s","code_hash":"%s"}}`, contractAddress, codeHash), true, false, defaultGasForTests, 0) + data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"callback_contract_error":{"contract_addr":"%s","code_hash":"%s"}}`, contractAddress, codeHash), true, false, defaultGasForTests, 0) - require.NotNil(t, execErr.GenericErr) - require.Equal(t, "la la 🤯", execErr.GenericErr.Msg) - //require.Empty(t, execEvents) - require.Empty(t, data) + require.NotNil(t, execErr.GenericErr) + require.Equal(t, "la la 🤯", execErr.GenericErr.Msg) + // require.Empty(t, execEvents) + require.Empty(t, data) + }) + } } func TestExecCallbackBadParam(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - // init - contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - require.Equal(t, 1, len(initEvents)) - - data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"callback_contract_bad_param":{"contract_addr":"%s"}}`, contractAddress), true, false, defaultGasForTests, 0) - - require.NotNil(t, execErr.ParseErr) - require.Equal(t, "test_contract::contract::HandleMsg", execErr.ParseErr.Target) - require.Contains(t, execErr.ParseErr.Msg, "unknown variant `callback_contract_bad_param`") - //require.Empty(t, execEvents) - require.Empty(t, data) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + // init + contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + require.Equal(t, 1, len(initEvents)) + + data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"callback_contract_bad_param":{"contract_addr":"%s"}}`, contractAddress), true, false, defaultGasForTests, 0) + + require.NotNil(t, execErr.ParseErr) + require.Equal(t, "test_contract::contract::HandleMsg", execErr.ParseErr.Target) + require.Contains(t, execErr.ParseErr.Msg, "unknown variant `callback_contract_bad_param`") + // require.Empty(t, execEvents) + require.Empty(t, data) + }) + } } func TestInitCallbackBadParam(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - // init first - contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - require.Equal(t, 1, len(initEvents)) - - secondContractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback_contract_bad_param":{"contract_addr":"%s"}}`, contractAddress), true, false, defaultGasForTests) - require.Empty(t, secondContractAddress) - //require.Empty(t, initEvents) - - require.NotNil(t, initErr.ParseErr) - require.Equal(t, "test_contract::contract::InitMsg", initErr.ParseErr.Target) - require.Contains(t, initErr.ParseErr.Msg, "unknown variant `callback_contract_bad_param`") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + // init first + contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + require.Equal(t, 1, len(initEvents)) + + secondContractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback_contract_bad_param":{"contract_addr":"%s"}}`, contractAddress), true, false, defaultGasForTests) + require.Empty(t, secondContractAddress) + // require.Empty(t, initEvents) + + require.NotNil(t, initErr.ParseErr) + require.Equal(t, "test_contract::contract::InitMsg", initErr.ParseErr.Target) + require.Contains(t, initErr.ParseErr.Msg, "unknown variant `callback_contract_bad_param`") + }) + } } func TestState(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - // init - contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - require.Equal(t, 1, len(initEvents)) + // init + contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + require.Equal(t, 1, len(initEvents)) - data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, false, defaultGasForTests, 0) - require.Empty(t, execErr) - require.Empty(t, data) + data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, false, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Empty(t, data) - _, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"set_state":{"key":"banana","value":"🍌"}}`, true, false, defaultGasForTests, 0) - require.Empty(t, execErr) + _, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"set_state":{"key":"banana","value":"🍌"}}`, true, false, defaultGasForTests, 0) + require.Empty(t, execErr) - data, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, false, defaultGasForTests, 0) - require.Empty(t, execErr) - require.Equal(t, "🍌", string(data)) + data, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, false, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Equal(t, "🍌", string(data)) - _, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"remove_state":{"key":"banana"}}`, true, false, defaultGasForTests, 0) - require.Empty(t, execErr) + _, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"remove_state":{"key":"banana"}}`, true, false, defaultGasForTests, 0) + require.Empty(t, execErr) - data, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, false, defaultGasForTests, 0) - require.Empty(t, execErr) - require.Empty(t, data) + data, _, _, execErr = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_state":{"key":"banana"}}`, true, false, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Empty(t, data) + }) + } } func TestCanonicalizeAddressErrors(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - require.Equal(t, 1, len(initEvents)) - - // this function should handle errors internally and return gracefully - data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"test_canonicalize_address_errors":{}}`, true, false, defaultGasForTests, 0) - require.Empty(t, execErr) - require.Equal(t, "🤟", string(data)) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + contractAddress, initEvents, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + require.Equal(t, 1, len(initEvents)) + + // this function should handle errors internally and return gracefully + data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"test_canonicalize_address_errors":{}}`, true, false, defaultGasForTests, 0) + require.Empty(t, execErr) + require.Equal(t, "🤟", string(data)) + }) + } } func TestInitPanic(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"panic":{}}`, false, false, defaultGasForTests) + _, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"panic":{}}`, false, false, defaultGasForTests) - require.NotNil(t, initErr.GenericErr) - require.Contains(t, initErr.GenericErr.Msg, "the contract panicked") + require.NotNil(t, initErr.GenericErr) + require.Contains(t, initErr.GenericErr.Msg, "the contract panicked") + }) + } } func TestExecPanic(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"panic":{}}`, false, false, defaultGasForTests, 0) + _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"panic":{}}`, false, false, defaultGasForTests, 0) - require.NotNil(t, execErr.GenericErr) - require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") + }) + } } func TestQueryPanic(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - _, queryErr := queryHelper(t, keeper, ctx, addr, `{"panic":{}}`, false, false, defaultGasForTests) - require.NotNil(t, queryErr.GenericErr) - require.Contains(t, queryErr.GenericErr.Msg, "the contract panicked") + _, queryErr := queryHelper(t, keeper, ctx, addr, `{"panic":{}}`, false, false, defaultGasForTests) + require.NotNil(t, queryErr.GenericErr) + require.Contains(t, queryErr.GenericErr.Msg, "the contract panicked") + }) + } } func TestAllocateOnHeapFailBecauseMemoryLimit(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"allocate_on_heap":{"bytes":13631488}}`, false, false, defaultGasForTests, 0) + data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"allocate_on_heap":{"bytes":13631488}}`, false, false, defaultGasForTests, 0) - // this should fail with memory error because 13MiB is more than the allowed 12MiB + // this should fail with memory error because 13MiB is more than the allowed 12MiB - require.Empty(t, data) + require.Empty(t, data) - require.NotNil(t, execErr.GenericErr) - require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") + }) + } } func TestAllocateOnHeapFailBecauseGasLimit(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - - // ensure we get an out of gas panic - defer func() { - r := recover() - require.NotNil(t, r) - _, ok := r.(sdk.ErrorOutOfGas) - require.True(t, ok, "%+v", r) - }() - - _, _, _, _ = execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"allocate_on_heap":{"bytes":1073741824}}`, false, false, defaultGasForTests, 0) - - // this should fail with out of gas because 1GiB will ask for - // 134,217,728 gas units (8192 per page times 16,384 pages) - // the default gas limit in ctx is 200,000 which translates into - // 20,000,000 WASM gas units, so before the memory_grow opcode is reached - // the gas metering sees a request that'll cost 134mn and the limit - // is 20mn, so it throws an out of gas exception - - require.True(t, false) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + + // ensure we get an out of gas panic + defer func() { + r := recover() + require.NotNil(t, r) + _, ok := r.(sdk.ErrorOutOfGas) + require.True(t, ok, "%+v", r) + }() + + _, _, _, _ = execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"allocate_on_heap":{"bytes":1073741824}}`, false, false, defaultGasForTests, 0) + + // this should fail with out of gas because 1GiB will ask for + // 134,217,728 gas units (8192 per page times 16,384 pages) + // the default gas limit in ctx is 200,000 which translates into + // 20,000,000 WASM gas units, so before the memory_grow opcode is reached + // the gas metering sees a request that'll cost 134mn and the limit + // is 20mn, so it throws an out of gas exception + + require.True(t, false) + }) + } } func TestAllocateOnHeapMoreThanSGXHasFailBecauseMemoryLimit(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"allocate_on_heap":{"bytes":1073741824}}`, false, false, 9_000_000, 0) + data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"allocate_on_heap":{"bytes":1073741824}}`, false, false, 9_000_000, 0) - // this should fail with memory error because 1GiB is more - // than the allowed 12MiB, gas is 9mn so WASM gas is 900mn - // which is bigger than the 134mn from the previous test + // this should fail with memory error because 1GiB is more + // than the allowed 12MiB, gas is 9mn so WASM gas is 900mn + // which is bigger than the 134mn from the previous test - require.Empty(t, data) + require.Empty(t, data) - require.NotNil(t, execErr.GenericErr) - require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") + }) + } } func TestPassNullPointerToImports(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - - tests := []string{ - "read_db_key", - "write_db_key", - "write_db_value", - "remove_db_key", - "canonicalize_address_input", - "humanize_address_input", - } + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + + tests := []string{ + "read_db_key", + "write_db_key", + "write_db_value", + "remove_db_key", + "canonicalize_address_input", + "humanize_address_input", + } - for _, passType := range tests { - t.Run(passType, func(t *testing.T) { - _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"pass_null_pointer_to_imports_should_throw":{"pass_type":"%s"}}`, passType), false, false, defaultGasForTests, 0) + for _, passType := range tests { + t.Run(passType, func(t *testing.T) { + _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"pass_null_pointer_to_imports_should_throw":{"pass_type":"%s"}}`, passType), false, false, defaultGasForTests, 0) - require.NotNil(t, execErr.GenericErr) - require.Contains(t, execErr.GenericErr.Msg, "failed to read memory") + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "failed to read memory") + }) + } }) } } func TestExternalQueryWorks(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0) + data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0) - require.Empty(t, execErr) - require.Equal(t, []byte{3}, data) + require.Empty(t, execErr) + require.Equal(t, []byte{3}, data) + }) + } } func TestExternalQueryCalleePanic(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) - _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_panic":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0) + _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_panic":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0) - require.NotNil(t, err.GenericErr) - require.Contains(t, err.GenericErr.Msg, "the contract panicked") + require.NotNil(t, err.GenericErr) + require.Contains(t, err.GenericErr.Msg, "the contract panicked") + }) + } } func TestExternalQueryCalleeStdError(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) - _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_error":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0) + _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_error":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0) - require.NotNil(t, err.GenericErr) - require.Equal(t, "la la 🤯", err.GenericErr.Msg) + require.NotNil(t, err.GenericErr) + require.Equal(t, "la la 🤯", err.GenericErr.Msg) + }) + } } func TestExternalQueryCalleeDoesntExist(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) - _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"send_external_query_error":{"to":"secret13l72vhjngmg55ykajxdnlalktwglyqjqv9pkq4","code_hash":"bla bla"}}`, true, false, defaultGasForTests, 0) + _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"send_external_query_error":{"to":"secret13l72vhjngmg55ykajxdnlalktwglyqjqv9pkq4","code_hash":"bla bla"}}`, true, false, defaultGasForTests, 0) - require.NotNil(t, err.GenericErr) - require.Contains(t, err.GenericErr.Msg, "not found") + require.NotNil(t, err.GenericErr) + require.Contains(t, err.GenericErr.Msg, "not found") + }) + } } func TestExternalQueryBadSenderABI(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) - _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_bad_abi":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0) + _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_bad_abi":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0) - require.NotNil(t, err.ParseErr) - require.Equal(t, "test_contract::contract::QueryMsg", err.ParseErr.Target) - require.Equal(t, "Invalid type", err.ParseErr.Msg) + require.NotNil(t, err.ParseErr) + require.Equal(t, "test_contract::contract::QueryMsg", err.ParseErr.Target) + require.Equal(t, "Invalid type", err.ParseErr.Msg) + }) + } } func TestExternalQueryBadReceiverABI(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) - _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_bad_abi_receiver":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0) + _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_bad_abi_receiver":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0) - require.NotNil(t, err.ParseErr) - require.Equal(t, "alloc::string::String", err.ParseErr.Target) - require.Equal(t, "Invalid type", err.ParseErr.Msg) + require.NotNil(t, err.ParseErr) + require.Equal(t, "alloc::string::String", err.ParseErr.Target) + require.Equal(t, "Invalid type", err.ParseErr.Msg) + }) + } } func TestMsgSenderInCallback(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) - _, events, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"callback_to_log_msg_sender":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0) + _, events, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"callback_to_log_msg_sender":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0) - require.Empty(t, err) - require.Equal(t, []ContractEvent{ - { - {Key: "contract_address", Value: addr.String()}, - {Key: "hi", Value: "hey"}, - }, - { - {Key: "contract_address", Value: addr.String()}, - {Key: "msg.sender", Value: addr.String()}, - }, - }, events) + require.Empty(t, err) + require.Equal(t, []ContractEvent{ + { + {Key: "contract_address", Value: addr.String()}, + {Key: "hi", Value: "hey"}, + }, + { + {Key: "contract_address", Value: addr.String()}, + {Key: "msg.sender", Value: addr.String()}, + }, + }, events) + }) + } } func TestInfiniteQueryLoopKilledGracefullyByOOM(t *testing.T) { t.SkipNow() // We no longer expect to hit OOM trivially - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) - data, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"send_external_query_infinite_loop":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests) + data, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"send_external_query_infinite_loop":{"to":"%s","code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests) - require.Empty(t, data) - require.NotNil(t, err.GenericErr) - require.Equal(t, err.GenericErr.Msg, "query contract failed: Execution error: Enclave: enclave ran out of heap memory") + require.Empty(t, data) + require.NotNil(t, err.GenericErr) + require.Equal(t, err.GenericErr.Msg, "query contract failed: Execution error: Enclave: enclave ran out of heap memory") + }) + } } func TestQueryRecursionLimitEnforcedInQueries(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) - data, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"send_external_query_recursion_limit":{"to":"%s","code_hash":"%s", "depth":1}}`, addr.String(), codeHash), true, false, defaultGasForTests) + data, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"send_external_query_recursion_limit":{"to":"%s","code_hash":"%s", "depth":1}}`, addr.String(), codeHash), true, false, defaultGasForTests) - require.NotEmpty(t, data) - require.Equal(t, data, "\"Recursion limit was correctly enforced\"") + require.NotEmpty(t, data) + require.Equal(t, data, "\"Recursion limit was correctly enforced\"") - require.Nil(t, err.GenericErr) + require.Nil(t, err.GenericErr) + }) + } } func TestQueryRecursionLimitEnforcedInHandles(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) - data, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_recursion_limit":{"to":"%s","code_hash":"%s", "depth":1}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0) + data, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_recursion_limit":{"to":"%s","code_hash":"%s", "depth":1}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0) - require.NotEmpty(t, data) - require.Equal(t, string(data), "\"Recursion limit was correctly enforced\"") + require.NotEmpty(t, data) + require.Equal(t, string(data), "\"Recursion limit was correctly enforced\"") - require.Nil(t, err.GenericErr) + require.Nil(t, err.GenericErr) + }) + } } func TestQueryRecursionLimitEnforcedInInits(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - // Initialize a contract that we will be querying - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) + // Initialize a contract that we will be querying + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) - // Initialize the contract that will be running the test - addr, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_recursion_limit":{"to":"%s","code_hash":"%s", "depth":1}}`, addr.String(), codeHash), true, false, defaultGasForTests) - require.Empty(t, err) + // Initialize the contract that will be running the test + addr, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_recursion_limit":{"to":"%s","code_hash":"%s", "depth":1}}`, addr.String(), codeHash), true, false, defaultGasForTests) + require.Empty(t, err) - require.Nil(t, err.GenericErr) + require.Nil(t, err.GenericErr) - require.Equal(t, []ContractEvent{ - { - {Key: "contract_address", Value: addr.String()}, - {Key: "message", Value: "Recursion limit was correctly enforced"}, - }, - }, events) + require.Equal(t, []ContractEvent{ + { + {Key: "contract_address", Value: addr.String()}, + {Key: "message", Value: "Recursion limit was correctly enforced"}, + }, + }, events) + }) + } } func TestWriteToStorageDuringQuery(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - _, queryErr := queryHelper(t, keeper, ctx, addr, `{"write_to_storage": {}}`, false, false, defaultGasForTests) - require.NotNil(t, queryErr.GenericErr) - require.Contains(t, queryErr.GenericErr.Msg, "contract tried to write to storage during a query") + _, queryErr := queryHelper(t, keeper, ctx, addr, `{"write_to_storage": {}}`, false, false, defaultGasForTests) + require.NotNil(t, queryErr.GenericErr) + require.Contains(t, queryErr.GenericErr.Msg, "contract tried to write to storage during a query") + }) + } } func TestRemoveFromStorageDuringQuery(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - _, queryErr := queryHelper(t, keeper, ctx, addr, `{"remove_from_storage": {}}`, false, false, defaultGasForTests) - require.NotNil(t, queryErr.GenericErr) - require.Contains(t, queryErr.GenericErr.Msg, "contract tried to write to storage during a query") + _, queryErr := queryHelper(t, keeper, ctx, addr, `{"remove_from_storage": {}}`, false, false, defaultGasForTests) + require.NotNil(t, queryErr.GenericErr) + require.Contains(t, queryErr.GenericErr.Msg, "contract tried to write to storage during a query") + }) + } } func TestDepositToContract(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) - walletCointsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCointsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) - require.Equal(t, "", contractCoinsBefore.String()) - require.Equal(t, "200000denom", walletCointsBefore.String()) + require.Equal(t, "", contractCoinsBefore.String()) + require.Equal(t, "200000denom", walletCointsBefore.String()) - data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, false, defaultGasForTests, 17) + data, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, false, defaultGasForTests, 17) - require.Empty(t, execErr) + require.Empty(t, execErr) - contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) - walletCointsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCointsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) - require.Equal(t, "17denom", contractCoinsAfter.String()) - require.Equal(t, "199983denom", walletCointsAfter.String()) + require.Equal(t, "17denom", contractCoinsAfter.String()) + require.Equal(t, "199983denom", walletCointsAfter.String()) - require.Equal(t, `[{"denom":"denom","amount":"17"}]`, string(data)) + require.Equal(t, `[{"denom":"denom","amount":"17"}]`, string(data)) + }) + } } func TestContractSendFunds(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, false, defaultGasForTests, 17) + _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, false, defaultGasForTests, 17) - require.Empty(t, execErr) + require.Empty(t, execErr) - contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) - walletCointsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCointsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) - require.Equal(t, "17denom", contractCoinsBefore.String()) - require.Equal(t, "199983denom", walletCointsBefore.String()) + require.Equal(t, "17denom", contractCoinsBefore.String()) + require.Equal(t, "199983denom", walletCointsBefore.String()) - _, _, _, execErr = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds":{"from":"%s","to":"%s","denom":"%s","amount":%d}}`, addr.String(), walletA.String(), "denom", 17), false, false, defaultGasForTests, 0) + _, _, _, execErr = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds":{"from":"%s","to":"%s","denom":"%s","amount":%d}}`, addr.String(), walletA.String(), "denom", 17), false, false, defaultGasForTests, 0) - contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) - walletCointsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCointsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) - require.Equal(t, "", contractCoinsAfter.String()) - require.Equal(t, "200000denom", walletCointsAfter.String()) + require.Equal(t, "", contractCoinsAfter.String()) + require.Equal(t, "200000denom", walletCointsAfter.String()) - require.Empty(t, execErr) + require.Empty(t, execErr) + }) + } } func TestContractTryToSendFundsFromSomeoneElse(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, false, defaultGasForTests, 17) + _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"deposit_to_contract":{}}`, false, false, defaultGasForTests, 17) - require.Empty(t, execErr) + require.Empty(t, execErr) - contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) - walletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) - require.Equal(t, "17denom", contractCoinsBefore.String()) - require.Equal(t, "199983denom", walletCoinsBefore.String()) + require.Equal(t, "17denom", contractCoinsBefore.String()) + require.Equal(t, "199983denom", walletCoinsBefore.String()) - _, _, _, execErr = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds":{"from":"%s","to":"%s","denom":"%s","amount":%d}}`, walletA.String(), addr.String(), "denom", 17), false, false, defaultGasForTests, 0) + _, _, _, execErr = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds":{"from":"%s","to":"%s","denom":"%s","amount":%d}}`, walletA.String(), addr.String(), "denom", 17), false, false, defaultGasForTests, 0) - require.NotNil(t, execErr.GenericErr) - require.Contains(t, execErr.GenericErr.Msg, "contract doesn't have permission") + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "contract doesn't have permission") + }) + } } func TestContractSendFundsToInitCallback(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) - walletCointsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCointsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) - require.Equal(t, "", contractCoinsBefore.String()) - require.Equal(t, "200000denom", walletCointsBefore.String()) + require.Equal(t, "", contractCoinsBefore.String()) + require.Equal(t, "200000denom", walletCointsBefore.String()) - _, execEvents, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds_to_init_callback":{"code_id":%d,"denom":"%s","amount":%d,"code_hash":"%s"}}`, codeID, "denom", 17, codeHash), true, false, defaultGasForTests, 17) + _, execEvents, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds_to_init_callback":{"code_id":%d,"denom":"%s","amount":%d,"code_hash":"%s"}}`, codeID, "denom", 17, codeHash), true, false, defaultGasForTests, 17) - require.Empty(t, execErr) - require.NotEmpty(t, execEvents) + require.Empty(t, execErr) + require.NotEmpty(t, execEvents) - contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) - walletCointsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCointsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) - newContract, err := sdk.AccAddressFromBech32(execEvents[1][0].Value) - require.NoError(t, err) - newContractCoins := keeper.bankKeeper.GetAllBalances(ctx, newContract) + newContract, err := sdk.AccAddressFromBech32(execEvents[1][0].Value) + require.NoError(t, err) + newContractCoins := keeper.bankKeeper.GetAllBalances(ctx, newContract) - require.Equal(t, "", contractCoinsAfter.String()) - require.Equal(t, "199983denom", walletCointsAfter.String()) - require.Equal(t, "17denom", newContractCoins.String()) + require.Equal(t, "", contractCoinsAfter.String()) + require.Equal(t, "199983denom", walletCointsAfter.String()) + require.Equal(t, "17denom", newContractCoins.String()) + }) + } } func TestContractSendFundsToInitCallbackNotEnough(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) - walletCointsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCointsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) - require.Equal(t, "", contractCoinsBefore.String()) - require.Equal(t, "200000denom", walletCointsBefore.String()) + require.Equal(t, "", contractCoinsBefore.String()) + require.Equal(t, "200000denom", walletCointsBefore.String()) - _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds_to_init_callback":{"code_id":%d,"denom":"%s","amount":%d,"code_hash":"%s"}}`, codeID, "denom", 18, codeHash), false, false, defaultGasForTests, 17) + _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds_to_init_callback":{"code_id":%d,"denom":"%s","amount":%d,"code_hash":"%s"}}`, codeID, "denom", 18, codeHash), false, false, defaultGasForTests, 17) - //require.Empty(t, execEvents) + // require.Empty(t, execEvents) - require.NotNil(t, execErr.GenericErr) - require.Contains(t, execErr.GenericErr.Msg, "insufficient funds") + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "insufficient funds") - contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) - walletCointsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) + walletCointsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) - require.Equal(t, "17denom", contractCoinsAfter.String()) - require.Equal(t, "199983denom", walletCointsAfter.String()) + require.Equal(t, "17denom", contractCoinsAfter.String()) + require.Equal(t, "199983denom", walletCointsAfter.String()) + }) + } } func TestContractSendFundsToExecCallback(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - addr2, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr2, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) - contract2CoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr2) - walletCointsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + contract2CoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr2) + walletCointsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) - require.Equal(t, "", contractCoinsBefore.String()) - require.Equal(t, "", contract2CoinsBefore.String()) - require.Equal(t, "200000denom", walletCointsBefore.String()) + require.Equal(t, "", contractCoinsBefore.String()) + require.Equal(t, "", contract2CoinsBefore.String()) + require.Equal(t, "200000denom", walletCointsBefore.String()) - _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds_to_exec_callback":{"to":"%s","denom":"%s","amount":%d,"code_hash":"%s"}}`, addr2.String(), "denom", 17, codeHash), true, false, defaultGasForTests, 17) + _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds_to_exec_callback":{"to":"%s","denom":"%s","amount":%d,"code_hash":"%s"}}`, addr2.String(), "denom", 17, codeHash), true, false, defaultGasForTests, 17) - require.Empty(t, execErr) + require.Empty(t, execErr) - contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) - contract2CoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr2) - walletCointsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) + contract2CoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr2) + walletCointsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) - require.Equal(t, "", contractCoinsAfter.String()) - require.Equal(t, "17denom", contract2CoinsAfter.String()) - require.Equal(t, "199983denom", walletCointsAfter.String()) + require.Equal(t, "", contractCoinsAfter.String()) + require.Equal(t, "17denom", contract2CoinsAfter.String()) + require.Equal(t, "199983denom", walletCointsAfter.String()) + }) + } } func TestContractSendFundsToExecCallbackNotEnough(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - addr2, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr2, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) - contract2CoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr2) - walletCointsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr) + contract2CoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, addr2) + walletCointsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) - require.Equal(t, "", contractCoinsBefore.String()) - require.Equal(t, "", contract2CoinsBefore.String()) - require.Equal(t, "200000denom", walletCointsBefore.String()) + require.Equal(t, "", contractCoinsBefore.String()) + require.Equal(t, "", contract2CoinsBefore.String()) + require.Equal(t, "200000denom", walletCointsBefore.String()) - _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds_to_exec_callback":{"to":"%s","denom":"%s","amount":%d,"code_hash":"%s"}}`, addr2.String(), "denom", 19, codeHash), false, false, defaultGasForTests, 17) + _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_funds_to_exec_callback":{"to":"%s","denom":"%s","amount":%d,"code_hash":"%s"}}`, addr2.String(), "denom", 19, codeHash), false, false, defaultGasForTests, 17) - require.NotNil(t, execErr.GenericErr) - require.Contains(t, execErr.GenericErr.Msg, "insufficient funds") + require.NotNil(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "insufficient funds") - contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) - contract2CoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr2) - walletCointsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) + contract2CoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr2) + walletCointsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) - require.Equal(t, "17denom", contractCoinsAfter.String()) - require.Equal(t, "", contract2CoinsAfter.String()) - require.Equal(t, "199983denom", walletCointsAfter.String()) + require.Equal(t, "17denom", contractCoinsAfter.String()) + require.Equal(t, "", contract2CoinsAfter.String()) + require.Equal(t, "199983denom", walletCointsAfter.String()) + }) + } } func TestSleep(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"sleep":{"ms":3000}}`, false, false, defaultGasForTests, 0) + _, _, _, execErr := execHelper(t, keeper, ctx, addr, walletA, privKeyA, `{"sleep":{"ms":3000}}`, false, false, defaultGasForTests, 0) - require.Error(t, execErr) - require.Error(t, execErr.GenericErr) - require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") + require.Error(t, execErr) + require.Error(t, execErr.GenericErr) + require.Contains(t, execErr.GenericErr.Msg, "the contract panicked") + }) + } } func TestGasIsChargedForInitCallbackToInit(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback_to_init":{"code_id":%d,"code_hash":"%s"}}`, codeID, codeHash), true, false, defaultGasForTests, 2, 0) - require.Empty(t, err) + _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback_to_init":{"code_id":%d,"code_hash":"%s"}}`, codeID, codeHash), true, false, defaultGasForTests, 2, 0) + require.Empty(t, err) + }) + } } func TestGasIsChargedForInitCallbackToExec(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback":{"contract_addr":"%s","code_hash":"%s"}}`, addr, codeHash), true, false, defaultGasForTests, 2, 0) - require.Empty(t, err) + _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"callback":{"contract_addr":"%s","code_hash":"%s"}}`, addr, codeHash), true, false, defaultGasForTests, 2, 0) + require.Empty(t, err) + }) + } } func TestGasIsChargedForExecCallbackToInit(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - // exec callback to init - _, _, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"callback_to_init":{"code_id":%d,"code_hash":"%s"}}`, codeID, codeHash), true, false, defaultGasForTests, 0, 2) - require.Empty(t, err) + // exec callback to init + _, _, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"callback_to_init":{"code_id":%d,"code_hash":"%s"}}`, codeID, codeHash), true, false, defaultGasForTests, 0, 2) + require.Empty(t, err) + }) + } } func TestGasIsChargedForExecCallbackToExec(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - // exec callback to exec - _, _, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"a":{"contract_addr":"%s","code_hash":"%s","x":1,"y":2}}`, addr, codeHash), true, false, defaultGasForTests, 0, 3) - require.Empty(t, err) + // exec callback to exec + _, _, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"a":{"contract_addr":"%s","code_hash":"%s","x":1,"y":2}}`, addr, codeHash), true, false, defaultGasForTests, 0, 3) + require.Empty(t, err) + }) + } } func TestGasIsChargedForExecExternalQuery(t *testing.T) { t.SkipNow() // as of v0.10 CowmWasm are overriding the default gas meter - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - _, _, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_depth_counter":{"to":"%s","depth":2,"code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0, 3) - require.Empty(t, err) + _, _, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_depth_counter":{"to":"%s","depth":2,"code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 0, 3) + require.Empty(t, err) + }) + } } func TestGasIsChargedForInitExternalQuery(t *testing.T) { t.SkipNow() // as of v0.10 CowmWasm are overriding the default gas meter - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_depth_counter":{"to":"%s","depth":2,"code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 3, 0) - require.Empty(t, err) + _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"send_external_query_depth_counter":{"to":"%s","depth":2,"code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 3, 0) + require.Empty(t, err) + }) + } } func TestGasIsChargedForQueryExternalQuery(t *testing.T) { t.SkipNow() // as of v0.10 CowmWasm are overriding the default gas meter - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + addr, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - _, err := queryHelperImpl(t, keeper, ctx, addr, fmt.Sprintf(`{"send_external_query_depth_counter":{"to":"%s","depth":2,"code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 3) - require.Empty(t, err) + _, err := queryHelperImpl(t, keeper, ctx, addr, fmt.Sprintf(`{"send_external_query_depth_counter":{"to":"%s","depth":2,"code_hash":"%s"}}`, addr.String(), codeHash), true, false, defaultGasForTests, 3) + require.Empty(t, err) + }) + } } func TestWasmTooHighInitialMemoryRuntimeFail(t *testing.T) { @@ -1728,414 +1997,466 @@ func TestWasmTooHighInitialMemoryStaticFail(t *testing.T) { } func TestWasmWithFloatingPoints(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract_with_floats.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract_with_floats.wasm") - _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, false, false, defaultGasForTests) - require.NotNil(t, err.GenericErr) - require.Contains(t, err.GenericErr.Msg, "found floating point operation in module code") + _, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, false, false, defaultGasForTests) + require.NotNil(t, err.GenericErr) + require.Contains(t, err.GenericErr.Msg, "found floating point operation in module code") + }) + } } func TestCodeHashInvalid(t *testing.T) { - ctx, keeper, codeID, _, walletA, privWalletA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - initMsg := []byte(`AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA{"nop":{}`) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privWalletA, _, _ := setupTest(t, tc.WasmFilePath) + initMsg := []byte(`AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA{"nop":{}`) - enc, _ := wasmCtx.Encrypt(initMsg) + enc, _ := wasmCtx.Encrypt(initMsg) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) - _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - require.Error(t, err) - require.Contains(t, err.Error(), "failed to validate transaction") + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) + _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + require.Error(t, err) + require.Contains(t, err.Error(), "failed to validate transaction") + }) + } } func TestCodeHashEmpty(t *testing.T) { - ctx, keeper, codeID, _, walletA, privWalletA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - initMsg := []byte(`{"nop":{}`) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privWalletA, _, _ := setupTest(t, tc.WasmFilePath) + initMsg := []byte(`{"nop":{}`) - enc, _ := wasmCtx.Encrypt(initMsg) + enc, _ := wasmCtx.Encrypt(initMsg) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) - _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - require.Error(t, err) - require.Contains(t, err.Error(), "failed to validate transaction") + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) + _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + require.Error(t, err) + require.Contains(t, err.Error(), "failed to validate transaction") + }) + } } func TestCodeHashNotHex(t *testing.T) { - ctx, keeper, codeID, _, walletA, privWalletA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - initMsg := []byte(`🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉{"nop":{}}`) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privWalletA, _, _ := setupTest(t, tc.WasmFilePath) + initMsg := []byte(`🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉{"nop":{}}`) - enc, _ := wasmCtx.Encrypt(initMsg) + enc, _ := wasmCtx.Encrypt(initMsg) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) - _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - require.Error(t, err) - require.Contains(t, err.Error(), "failed to validate transaction") + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) + _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + require.Error(t, err) + require.Contains(t, err.Error(), "failed to validate transaction") + }) + } } func TestCodeHashTooSmall(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privWalletA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privWalletA, _, _ := setupTest(t, tc.WasmFilePath) - initMsg := []byte(codeHash[0:63] + `{"nop":{}`) + initMsg := []byte(codeHash[0:63] + `{"nop":{}`) - enc, _ := wasmCtx.Encrypt(initMsg) + enc, _ := wasmCtx.Encrypt(initMsg) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) - _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - require.Error(t, err) - require.Contains(t, err.Error(), "failed to validate transaction") + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) + _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + require.Error(t, err) + require.Contains(t, err.Error(), "failed to validate transaction") + }) + } } func TestCodeHashTooBig(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privWalletA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privWalletA, _, _ := setupTest(t, tc.WasmFilePath) - initMsg := []byte(codeHash + "a" + `{"nop":{}`) + initMsg := []byte(codeHash + "a" + `{"nop":{}`) - enc, _ := wasmCtx.Encrypt(initMsg) + enc, _ := wasmCtx.Encrypt(initMsg) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) - _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - require.Error(t, err) + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) + _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + require.Error(t, err) - initErr := extractInnerError(t, err, enc[0:32], true, false) - require.NotEmpty(t, initErr) - require.NotNil(t, initErr.ParseErr) - require.Equal(t, "test_contract::contract::InitMsg", initErr.ParseErr.Target) - require.Equal(t, "Expected to parse either a `true`, `false`, or a `null`.", initErr.ParseErr.Msg) + initErr := extractInnerError(t, err, enc[0:32], true, false) + require.NotEmpty(t, initErr) + require.NotNil(t, initErr.ParseErr) + require.Equal(t, "test_contract::contract::InitMsg", initErr.ParseErr.Target) + require.Equal(t, "Expected to parse either a `true`, `false`, or a `null`.", initErr.ParseErr.Msg) + }) + } } func TestCodeHashWrong(t *testing.T) { - ctx, keeper, codeID, _, walletA, privWalletA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privWalletA, _, _ := setupTest(t, tc.WasmFilePath) - initMsg := []byte(`e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855{"nop":{}`) + initMsg := []byte(`e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855{"nop":{}`) - enc, _ := wasmCtx.Encrypt(initMsg) + enc, _ := wasmCtx.Encrypt(initMsg) - ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) - _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) - require.Error(t, err) - require.Contains(t, err.Error(), "failed to validate transaction") + ctx = PrepareInitSignedTx(t, keeper, ctx, walletA, privWalletA, enc, codeID, sdk.NewCoins(sdk.NewInt64Coin("denom", 0))) + _, _, err := keeper.Instantiate(ctx, codeID, walletA /* nil, */, enc, "some label", sdk.NewCoins(sdk.NewInt64Coin("denom", 0)), nil) + require.Error(t, err) + require.Contains(t, err.Error(), "failed to validate transaction") + }) + } } func TestCodeHashInitCallInit(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - t.Run("GoodCodeHash", func(t *testing.T) { - addr, events, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"1"}}`, codeID, codeHash, `{\"nop\":{}}`), true, false, defaultGasForTests, 2, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: addr.String()}, - {Key: "a", Value: "a"}, - }, - { - {Key: "contract_address", Value: events[1][0].Value}, - {Key: "init", Value: "🌈"}, - }, - }, - events, - ) - }) - t.Run("EmptyCodeHash", func(t *testing.T) { - _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"","msg":"%s","label":"2"}}`, codeID, `{\"nop\":{}}`), false, false, defaultGasForTests, 2, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) - t.Run("TooBigCodeHash", func(t *testing.T) { - _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%sa","msg":"%s","label":"3"}}`, codeID, codeHash, `{\"nop\":{}}`), true, false, defaultGasForTests, 2, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "parsing test_contract::contract::InitMsg: Expected to parse either a `true`, `false`, or a `null`.", - ) - }) - t.Run("TooSmallCodeHash", func(t *testing.T) { - _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"4"}}`, codeID, codeHash[0:63], `{\"nop\":{}}`), false, false, defaultGasForTests, 2, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) - t.Run("IncorrectCodeHash", func(t *testing.T) { - _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s","label":"5"}}`, codeID, `{\"nop\":{}}`), false, false, defaultGasForTests, 2, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + t.Run("GoodCodeHash", func(t *testing.T) { + addr, events, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"1"}}`, codeID, codeHash, `{\"nop\":{}}`), true, false, defaultGasForTests, 2, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: addr.String()}, + {Key: "a", Value: "a"}, + }, + { + {Key: "contract_address", Value: events[1][0].Value}, + {Key: "init", Value: "🌈"}, + }, + }, + events, + ) + }) + t.Run("EmptyCodeHash", func(t *testing.T) { + _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"","msg":"%s","label":"2"}}`, codeID, `{\"nop\":{}}`), false, false, defaultGasForTests, 2, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("TooBigCodeHash", func(t *testing.T) { + _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%sa","msg":"%s","label":"3"}}`, codeID, codeHash, `{\"nop\":{}}`), true, false, defaultGasForTests, 2, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "parsing test_contract::contract::InitMsg: Expected to parse either a `true`, `false`, or a `null`.", + ) + }) + t.Run("TooSmallCodeHash", func(t *testing.T) { + _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"4"}}`, codeID, codeHash[0:63], `{\"nop\":{}}`), false, false, defaultGasForTests, 2, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("IncorrectCodeHash", func(t *testing.T) { + _, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s","label":"5"}}`, codeID, `{\"nop\":{}}`), false, false, defaultGasForTests, 2, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + }) + } } func TestCodeHashInitCallExec(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - addr, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests, 1, 0) - require.Empty(t, err) - - t.Run("GoodCodeHash", func(t *testing.T) { - addr2, events, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, false, defaultGasForTests, 2, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: addr2.String()}, - {Key: "b", Value: "b"}, - }, - { - {Key: "contract_address", Value: addr.String()}, - {Key: "watermelon", Value: "🍉"}, - }, - }, - events, - ) - }) - t.Run("EmptyCodeHash", func(t *testing.T) { - _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr.String(), `{\"c\":{\"x\":1,\"y\":1}}`), false, false, defaultGasForTests, 2, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) - t.Run("TooBigCodeHash", func(t *testing.T) { - _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr.String(), codeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, false, defaultGasForTests, 2, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "parsing test_contract::contract::HandleMsg: Expected to parse either a `true`, `false`, or a `null`.", - ) - }) - t.Run("TooSmallCodeHash", func(t *testing.T) { - _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash[0:63], `{\"c\":{\"x\":1,\"y\":1}}`), false, false, defaultGasForTests, 2, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) - t.Run("IncorrectCodeHash", func(t *testing.T) { - _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr.String(), `{\"c\":{\"x\":1,\"y\":1}}`), false, false, defaultGasForTests, 2, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + addr, _, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests, 1, 0) + require.Empty(t, err) + + t.Run("GoodCodeHash", func(t *testing.T) { + addr2, events, err := initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, false, defaultGasForTests, 2, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: addr2.String()}, + {Key: "b", Value: "b"}, + }, + { + {Key: "contract_address", Value: addr.String()}, + {Key: "watermelon", Value: "🍉"}, + }, + }, + events, + ) + }) + t.Run("EmptyCodeHash", func(t *testing.T) { + _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr.String(), `{\"c\":{\"x\":1,\"y\":1}}`), false, false, defaultGasForTests, 2, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("TooBigCodeHash", func(t *testing.T) { + _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr.String(), codeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, false, defaultGasForTests, 2, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "parsing test_contract::contract::HandleMsg: Expected to parse either a `true`, `false`, or a `null`.", + ) + }) + t.Run("TooSmallCodeHash", func(t *testing.T) { + _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash[0:63], `{\"c\":{\"x\":1,\"y\":1}}`), false, false, defaultGasForTests, 2, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("IncorrectCodeHash", func(t *testing.T) { + _, _, err = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr.String(), `{\"c\":{\"x\":1,\"y\":1}}`), false, false, defaultGasForTests, 2, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + }) + } } func TestCodeHashInitCallQuery(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) - - t.Run("GoodCodeHash", func(t *testing.T) { - addr2, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: addr2.String()}, - {Key: "c", Value: "2"}, - }, - }, - events, - ) - }) - t.Run("EmptyCodeHash", func(t *testing.T) { - _, _, err = initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) - t.Run("TooBigCodeHash", func(t *testing.T) { - _, _, err = initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "Got an error from query: ParseErr { target: \"test_contract::contract::QueryMsg\", msg: \"Expected to parse either a `true`, `false`, or a `null`.\", backtrace: None }", - ) - }) - t.Run("TooSmallCodeHash", func(t *testing.T) { - _, _, err = initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash[0:63], `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) - t.Run("IncorrectCodeHash", func(t *testing.T) { - _, _, err = initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) + + t.Run("GoodCodeHash", func(t *testing.T) { + addr2, events, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: addr2.String()}, + {Key: "c", Value: "2"}, + }, + }, + events, + ) + }) + t.Run("EmptyCodeHash", func(t *testing.T) { + _, _, err = initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("TooBigCodeHash", func(t *testing.T) { + _, _, err = initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "Got an error from query: ParseErr { target: \"test_contract::contract::QueryMsg\", msg: \"Expected to parse either a `true`, `false`, or a `null`.\", backtrace: None }", + ) + }) + t.Run("TooSmallCodeHash", func(t *testing.T) { + _, _, err = initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash[0:63], `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("IncorrectCodeHash", func(t *testing.T) { + _, _, err = initHelper(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + }) + } } func TestCodeHashExecCallInit(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) - - t.Run("GoodCodeHash", func(t *testing.T) { - _, events, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"1"}}`, codeID, codeHash, `{\"nop\":{}}`), true, false, defaultGasForTests, 0, 2) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: addr.String()}, - {Key: "a", Value: "a"}, - }, - { - {Key: "contract_address", Value: events[1][0].Value}, - {Key: "init", Value: "🌈"}, - }, - }, - events, - ) - }) - t.Run("EmptyCodeHash", func(t *testing.T) { - _, _, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"","msg":"%s","label":"2"}}`, codeID, `{\"nop\":{}}`), false, false, defaultGasForTests, 0, 2) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) - t.Run("TooBigCodeHash", func(t *testing.T) { - _, _, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%sa","msg":"%s","label":"3"}}`, codeID, codeHash, `{\"nop\":{}}`), true, false, defaultGasForTests, 0, 2) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "parsing test_contract::contract::InitMsg: Expected to parse either a `true`, `false`, or a `null`.", - ) - }) - t.Run("TooSmallCodeHash", func(t *testing.T) { - _, _, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"4"}}`, codeID, codeHash[0:63], `{\"nop\":{}}`), false, false, defaultGasForTests, 0, 2) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) - t.Run("IncorrectCodeHash", func(t *testing.T) { - _, _, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s","label":"5"}}`, codeID, `{\"nop\":{}}`), false, false, defaultGasForTests, 0, 2) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) + + t.Run("GoodCodeHash", func(t *testing.T) { + _, events, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"1"}}`, codeID, codeHash, `{\"nop\":{}}`), true, false, defaultGasForTests, 0, 2) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: addr.String()}, + {Key: "a", Value: "a"}, + }, + { + {Key: "contract_address", Value: events[1][0].Value}, + {Key: "init", Value: "🌈"}, + }, + }, + events, + ) + }) + t.Run("EmptyCodeHash", func(t *testing.T) { + _, _, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"","msg":"%s","label":"2"}}`, codeID, `{\"nop\":{}}`), false, false, defaultGasForTests, 0, 2) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("TooBigCodeHash", func(t *testing.T) { + _, _, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%sa","msg":"%s","label":"3"}}`, codeID, codeHash, `{\"nop\":{}}`), true, false, defaultGasForTests, 0, 2) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "parsing test_contract::contract::InitMsg: Expected to parse either a `true`, `false`, or a `null`.", + ) + }) + t.Run("TooSmallCodeHash", func(t *testing.T) { + _, _, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"4"}}`, codeID, codeHash[0:63], `{\"nop\":{}}`), false, false, defaultGasForTests, 0, 2) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("IncorrectCodeHash", func(t *testing.T) { + _, _, _, err := execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s","label":"5"}}`, codeID, `{\"nop\":{}}`), false, false, defaultGasForTests, 0, 2) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + }) + } } func TestLabelCollisionWhenMultipleCallbacksToInitFromSameContract(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) - _, _, _, err = execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"1"}}`, codeID, codeHash, `{\"nop\":{}}`), true, false, defaultGasForTests, 0, 2) - require.Empty(t, err) + _, _, _, err = execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"1"}}`, codeID, codeHash, `{\"nop\":{}}`), true, false, defaultGasForTests, 0, 2) + require.Empty(t, err) - _, _, _, err = execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"1"}}`, codeID, codeHash, `{\"nop\":{}}`), false, false, defaultGasForTests, 0, 1) - require.NotEmpty(t, err) - require.NotNil(t, err.GenericErr) - require.Contains(t, err.GenericErr.Msg, "contract account already exists") + _, _, _, err = execHelperImpl(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_init":{"code_id":%d,"code_hash":"%s","msg":"%s","label":"1"}}`, codeID, codeHash, `{\"nop\":{}}`), false, false, defaultGasForTests, 0, 1) + require.NotEmpty(t, err) + require.NotNil(t, err.GenericErr) + require.Contains(t, err.GenericErr.Msg, "contract account already exists") + }) + } } func TestCodeHashExecCallExec(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) - - t.Run("GoodCodeHash", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr, codeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: addr.String()}, - {Key: "b", Value: "b"}, - }, - { - {Key: "contract_address", Value: events[1][0].Value}, - {Key: "watermelon", Value: "🍉"}, - }, - }, - events, - ) - }) - t.Run("EmptyCodeHash", func(t *testing.T) { - _, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr, `{\"c\":{\"x\":1,\"y\":1}}`), false, false, defaultGasForTests, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) - t.Run("TooBigCodeHash", func(t *testing.T) { - _, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr, codeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, false, defaultGasForTests, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "parsing test_contract::contract::HandleMsg: Expected to parse either a `true`, `false`, or a `null`.", - ) - }) - t.Run("TooSmallCodeHash", func(t *testing.T) { - _, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr, codeHash[0:63], `{\"c\":{\"x\":1,\"y\":1}}`), false, false, defaultGasForTests, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) - t.Run("IncorrectCodeHash", func(t *testing.T) { - _, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr, `{\"c\":{\"x\":1,\"y\":1}}`), false, false, defaultGasForTests, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) + + t.Run("GoodCodeHash", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr, codeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: addr.String()}, + {Key: "b", Value: "b"}, + }, + { + {Key: "contract_address", Value: events[1][0].Value}, + {Key: "watermelon", Value: "🍉"}, + }, + }, + events, + ) + }) + t.Run("EmptyCodeHash", func(t *testing.T) { + _, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr, `{\"c\":{\"x\":1,\"y\":1}}`), false, false, defaultGasForTests, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("TooBigCodeHash", func(t *testing.T) { + _, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr, codeHash, `{\"c\":{\"x\":1,\"y\":1}}`), true, false, defaultGasForTests, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "parsing test_contract::contract::HandleMsg: Expected to parse either a `true`, `false`, or a `null`.", + ) + }) + t.Run("TooSmallCodeHash", func(t *testing.T) { + _, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr, codeHash[0:63], `{\"c\":{\"x\":1,\"y\":1}}`), false, false, defaultGasForTests, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("IncorrectCodeHash", func(t *testing.T) { + _, _, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_exec":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr, `{\"c\":{\"x\":1,\"y\":1}}`), false, false, defaultGasForTests, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + }) + } } // todo: enable after the upgrade to sdk 0.45x //func TestGasUsageForStoreKey(t *testing.T) { -// ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") +// ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.Wasm) // // addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) // require.Empty(t, err) @@ -2161,126 +2482,137 @@ func TestCodeHashExecCallExec(t *testing.T) { //} func TestQueryGasPrice(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) - - t.Run("Query to Self Gas Price", func(t *testing.T) { - - _, _, gasUsed, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests, 0) - require.Empty(t, err) - // require that more gas was used than the base 20K (10K for execute, another 10K for query) - require.Greater(t, gasUsed, uint64(20_000)) - }) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) + + t.Run("Query to Self Gas Price", func(t *testing.T) { + _, _, gasUsed, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests, 0) + require.Empty(t, err) + // require that more gas was used than the base 20K (10K for execute, another 10K for query) + require.Greater(t, gasUsed, uint64(20_000)) + }) + }) + } } func TestCodeHashExecCallQuery(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) - - t.Run("GoodCodeHash", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: addr.String()}, - {Key: "c", Value: "2"}, - }, - }, - events, - ) - }) - t.Run("EmptyCodeHash", func(t *testing.T) { - _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) - t.Run("TooBigCodeHash", func(t *testing.T) { - _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "Got an error from query: ParseErr { target: \"test_contract::contract::QueryMsg\", msg: \"Expected to parse either a `true`, `false`, or a `null`.\", backtrace: None }", - ) - }) - t.Run("TooSmallCodeHash", func(t *testing.T) { - _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash[0:63], `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) - t.Run("IncorrectCodeHash", func(t *testing.T) { - _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests, 0) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) + + t.Run("GoodCodeHash", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: addr.String()}, + {Key: "c", Value: "2"}, + }, + }, + events, + ) + }) + t.Run("EmptyCodeHash", func(t *testing.T) { + _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("TooBigCodeHash", func(t *testing.T) { + _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "Got an error from query: ParseErr { target: \"test_contract::contract::QueryMsg\", msg: \"Expected to parse either a `true`, `false`, or a `null`.\", backtrace: None }", + ) + }) + t.Run("TooSmallCodeHash", func(t *testing.T) { + _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash[0:63], `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("IncorrectCodeHash", func(t *testing.T) { + _, _, _, err = execHelper(t, keeper, ctx, addr, walletA, privKeyA, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests, 0) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + }) + } } func TestCodeHashQueryCallQuery(t *testing.T) { - ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, err) - - t.Run("GoodCodeHash", func(t *testing.T) { - output, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) - - require.Empty(t, err) - require.Equal(t, "2", output) - }) - t.Run("EmptyCodeHash", func(t *testing.T) { - _, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) - t.Run("TooBigCodeHash", func(t *testing.T) { - _, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "Got an error from query: ParseErr { target: \"test_contract::contract::QueryMsg\", msg: \"Expected to parse either a `true`, `false`, or a `null`.\", backtrace: None }", - ) - }) - t.Run("TooSmallCodeHash", func(t *testing.T) { - _, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash[0:63], `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) - t.Run("IncorrectCodeHash", func(t *testing.T) { - _, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) - - require.NotEmpty(t, err) - require.Contains(t, - err.Error(), - "failed to validate transaction", - ) - }) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + addr, _, err := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, err) + + t.Run("GoodCodeHash", func(t *testing.T) { + output, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) + + require.Empty(t, err) + require.Equal(t, "2", output) + }) + t.Run("EmptyCodeHash", func(t *testing.T) { + _, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("TooBigCodeHash", func(t *testing.T) { + _, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%sa","msg":"%s"}}`, addr.String(), codeHash, `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "Got an error from query: ParseErr { target: \"test_contract::contract::QueryMsg\", msg: \"Expected to parse either a `true`, `false`, or a `null`.\", backtrace: None }", + ) + }) + t.Run("TooSmallCodeHash", func(t *testing.T) { + _, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"%s","msg":"%s"}}`, addr.String(), codeHash[0:63], `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + t.Run("IncorrectCodeHash", func(t *testing.T) { + _, err := queryHelper(t, keeper, ctx, addr, fmt.Sprintf(`{"call_to_query":{"addr":"%s","code_hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","msg":"%s"}}`, addr.String(), `{\"receive_external_query\":{\"num\":1}}`), true, false, defaultGasForTests) + + require.NotEmpty(t, err) + require.Contains(t, + err.Error(), + "failed to validate transaction", + ) + }) + }) + } } func TestEncryptedAndPlaintextLogs(t *testing.T) { @@ -2306,485 +2638,518 @@ func TestEncryptedAndPlaintextLogs(t *testing.T) { } func TestSecp256k1Verify(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - - // https://paulmillr.com/noble/ - - t.Run("CorrectCompactPubkey", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "true"}, - }, - }, - events, - ) - }) - t.Run("CorrectLongPubkey", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "true"}, - }, - }, - events, - ) - }) - t.Run("IncorrectMsgHashCompactPubkey", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzas="}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "false"}, - }, - }, - events, - ) - }) - t.Run("IncorrectMsgHashLongPubkey", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzas="}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "false"}, - }, - }, - events, - ) - }) - t.Run("IncorrectSigCompactPubkey", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"rhZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "false"}, - }, - }, - events, - ) - }) - t.Run("IncorrectSigLongPubkey", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"rhZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "false"}, - }, - }, - events, - ) - }) - t.Run("IncorrectCompactPubkey", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"AoSdDHH9J0Bfb9pT8GFn+bW9cEVkgIh4bFsepMWmczXc","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "false"}, - }, - }, - events, - ) - }) - t.Run("IncorrectLongPubkey", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BISdDHH9J0Bfb9pT8GFn+bW9cEVkgIh4bFsepMWmczXcFWl11YCgu65hzvNDQE2Qo1hwTMQ/42Xif8O/MrxzvxI=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "false"}, - }, - }, - events, - ) - }) - + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + + // https://paulmillr.com/noble/ + + t.Run("CorrectCompactPubkey", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("CorrectLongPubkey", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("IncorrectMsgHashCompactPubkey", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzas="}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectMsgHashLongPubkey", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzas="}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectSigCompactPubkey", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"rhZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectSigLongPubkey", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BEZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo///ne03QpL+5WFHztzVceB3WD4QY/Ipl0UkHr/R8kDpVk=","sig":"rhZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectCompactPubkey", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"AoSdDHH9J0Bfb9pT8GFn+bW9cEVkgIh4bFsepMWmczXc","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectLongPubkey", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":1,"pubkey":"BISdDHH9J0Bfb9pT8GFn+bW9cEVkgIh4bFsepMWmczXcFWl11YCgu65hzvNDQE2Qo1hwTMQ/42Xif8O/MrxzvxI=","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + }) + } } func TestBenchmarkSecp256k1VerifyAPI(t *testing.T) { t.SkipNow() // Assaf: I wrote the benchmark like this because the init functions take testing.T // and not testing.B and I just wanted to quickly get a feel for the perf improvments - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - start := time.Now() - // https://paulmillr.com/noble/ - execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":10,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) - elapsed := time.Since(start) - fmt.Printf("TestBenchmarkSecp256k1VerifyAPI took %s\n", elapsed) + start := time.Now() + // https://paulmillr.com/noble/ + execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify":{"iterations":10,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) + elapsed := time.Since(start) + fmt.Printf("TestBenchmarkSecp256k1VerifyAPI took %s\n", elapsed) + }) + } } func TestBenchmarkSecp256k1VerifyCrate(t *testing.T) { t.SkipNow() // Assaf: I wrote the benchmark like this because the init functions take testing.T // and not testing.B and I just wanted to quickly get a feel for the perf improvments - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - start := time.Now() - // https://paulmillr.com/noble/ - execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify_from_crate":{"iterations":10,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, 100_000_000, 0) - elapsed := time.Since(start) - fmt.Printf("TestBenchmarkSecp256k1VerifyCrate took %s\n", elapsed) + start := time.Now() + // https://paulmillr.com/noble/ + execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_verify_from_crate":{"iterations":10,"pubkey":"A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//","sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, 100_000_000, 0) + elapsed := time.Since(start) + fmt.Printf("TestBenchmarkSecp256k1VerifyCrate took %s\n", elapsed) + }) + } } func TestEd25519Verify(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - - // https://paulmillr.com/noble/ - t.Run("Correct", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "true"}, - }, - }, - events, - ) - }) - t.Run("IncorrectMsg", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmUK"}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "false"}, - }, - }, - events, - ) - }) - t.Run("IncorrectSig", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDw==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "false"}, - }, - }, - events, - ) - }) - t.Run("IncorrectPubkey", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"DV1lgRdKw7nt4hvl8XkGZXMzU9S3uM9NLTK0h0qMbUs=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "false"}, - }, - }, - events, - ) - }) - + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + + // https://paulmillr.com/noble/ + t.Run("Correct", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("IncorrectMsg", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmUK"}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectSig", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDw==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectPubkey", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_verify":{"iterations":1,"pubkey":"DV1lgRdKw7nt4hvl8XkGZXMzU9S3uM9NLTK0h0qMbUs=","sig":"8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","msg":"YXNzYWYgd2FzIGhlcmU="}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + }) + } } func TestEd25519BatchVerify(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - - // https://paulmillr.com/noble/ - t.Run("Correct", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "true"}, - }, - }, - events, - ) - }) - t.Run("100Correct", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU="]}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "true"}, - }, - }, - events, - ) - }) - t.Run("IncorrectPubkey", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["DV1lgRdKw7nt4hvl8XkGZXMzU9S3uM9NLTK0h0qMbUs="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "false"}, - }, - }, - events, - ) - }) - t.Run("IncorrectMsg", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmUK"]}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "false"}, - }, - }, - events, - ) - }) - t.Run("IncorrectSig", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDw=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "false"}, - }, - }, - events, - ) - }) - t.Run("CorrectEmptySigsEmptyMsgsOnePubkey", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":[],"msgs":[]}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "true"}, - }, - }, - events, - ) - }) - t.Run("CorrectEmpty", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":[],"sigs":[],"msgs":[]}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "true"}, - }, - }, - events, - ) - }) - t.Run("CorrectEmptyPubkeysEmptySigsOneMsg", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":[],"sigs":[],"msgs":["YXNzYWYgd2FzIGhlcmUK"]}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "true"}, - }, - }, - events, - ) - }) - t.Run("CorrectMultisig", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","2ukhmWRNmcgCrB9fpLP9/HZVuJn6AhpITf455F4GsbM="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","bp/N4Ub2WFk9SE9poZVEanU1l46WMrFkTd5wQIXi6QJKjvZUi7+GTzmTe8y2yzgpBI+GWQmt0/QwYbnSVxq/Cg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "true"}, - }, - }, - events, - ) - }) - t.Run("CorrectMultiMsgOneSigner", func(t *testing.T) { - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["2ukhmWRNmcgCrB9fpLP9/HZVuJn6AhpITf455F4GsbM="],"sigs":["bp/N4Ub2WFk9SE9poZVEanU1l46WMrFkTd5wQIXi6QJKjvZUi7+GTzmTe8y2yzgpBI+GWQmt0/QwYbnSVxq/Cg==","uuNxLEzAYDbuJ+BiYN94pTqhD7UhvCJNbxAbnWz0B9DivkPXmqIULko0DddP2/tVXPtjJ90J20faiWCEC3QkDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU=","cGVhY2Ugb3V0"]}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "true"}, - }, - }, - events, - ) - }) - + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + + // https://paulmillr.com/noble/ + t.Run("Correct", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("100Correct", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU="]}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("IncorrectPubkey", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["DV1lgRdKw7nt4hvl8XkGZXMzU9S3uM9NLTK0h0qMbUs="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectMsg", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmUK"]}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("IncorrectSig", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDw=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "false"}, + }, + }, + events, + ) + }) + t.Run("CorrectEmptySigsEmptyMsgsOnePubkey", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":[],"msgs":[]}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("CorrectEmpty", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":[],"sigs":[],"msgs":[]}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("CorrectEmptyPubkeysEmptySigsOneMsg", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":[],"sigs":[],"msgs":["YXNzYWYgd2FzIGhlcmUK"]}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("CorrectMultisig", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","2ukhmWRNmcgCrB9fpLP9/HZVuJn6AhpITf455F4GsbM="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","bp/N4Ub2WFk9SE9poZVEanU1l46WMrFkTd5wQIXi6QJKjvZUi7+GTzmTe8y2yzgpBI+GWQmt0/QwYbnSVxq/Cg=="],"msgs":["YXNzYWYgd2FzIGhlcmU="]}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + t.Run("CorrectMultiMsgOneSigner", func(t *testing.T) { + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1,"pubkeys":["2ukhmWRNmcgCrB9fpLP9/HZVuJn6AhpITf455F4GsbM="],"sigs":["bp/N4Ub2WFk9SE9poZVEanU1l46WMrFkTd5wQIXi6QJKjvZUi7+GTzmTe8y2yzgpBI+GWQmt0/QwYbnSVxq/Cg==","uuNxLEzAYDbuJ+BiYN94pTqhD7UhvCJNbxAbnWz0B9DivkPXmqIULko0DddP2/tVXPtjJ90J20faiWCEC3QkDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU=","cGVhY2Ugb3V0"]}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + }) + } } func TestSecp256k1RecoverPubkey(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") - - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) - - // https://paulmillr.com/noble/ - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_recover_pubkey":{"iterations":1,"recovery_param":0,"sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//"}, - }, - }, - events, - ) - - _, events, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_recover_pubkey":{"iterations":1,"recovery_param":1,"sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) - - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "Ams198xOCEVnc/ESvxF2nxnE3AVFO8ahB22S1ZgX2vSR"}, - }, - }, - events, - ) + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) + + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + + // https://paulmillr.com/noble/ + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_recover_pubkey":{"iterations":1,"recovery_param":0,"sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "A0ZGrlBHMWtCMNAIbIrOxofwCxzZ0dxjT2yzWKwKmo//"}, + }, + }, + events, + ) + + _, events, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_recover_pubkey":{"iterations":1,"recovery_param":1,"sig":"/hZeEYHs9trj+Akeb+7p3UAtXjcDNYP9/D/hj/ALIUAG9bfrJltxkfpMz/9Jn5K3c5QjLuvaNT2jgr7P/AEW8A==","msg_hash":"ARp3VEHssUlDEwoW8AzdQYGKg90ENy8yWePKcjfjzao="}}`, true, false, defaultGasForTests, 0) + + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "Ams198xOCEVnc/ESvxF2nxnE3AVFO8ahB22S1ZgX2vSR"}, + }, + }, + events, + ) + }) + } } func TestSecp256k1Sign(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - // priv iadRiuRKNZvAXwolxqzJvr60uiMDJTxOEzEwV8OK2ao= - // pub ArQojoh5TVlSSNA1HFlH5HcQsv0jnrpeE7hgwR/N46nS - // msg d2VuIG1vb24= - // msg_hash K9vGEuzCYCUcIXlhMZu20ke2K4mJhreguYct5MqAzhA= + // priv iadRiuRKNZvAXwolxqzJvr60uiMDJTxOEzEwV8OK2ao= + // pub ArQojoh5TVlSSNA1HFlH5HcQsv0jnrpeE7hgwR/N46nS + // msg d2VuIG1vb24= + // msg_hash K9vGEuzCYCUcIXlhMZu20ke2K4mJhreguYct5MqAzhA= - // https://paulmillr.com/noble/ - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_sign":{"iterations":1,"msg":"d2VuIG1vb24=","privkey":"iadRiuRKNZvAXwolxqzJvr60uiMDJTxOEzEwV8OK2ao="}}`, true, false, defaultGasForTests, 0) - require.Empty(t, err) + // https://paulmillr.com/noble/ + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"secp256k1_sign":{"iterations":1,"msg":"d2VuIG1vb24=","privkey":"iadRiuRKNZvAXwolxqzJvr60uiMDJTxOEzEwV8OK2ao="}}`, true, false, defaultGasForTests, 0) + require.Empty(t, err) - signature := events[0][1].Value + signature := events[0][1].Value - _, events, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"secp256k1_verify":{"iterations":1,"pubkey":"ArQojoh5TVlSSNA1HFlH5HcQsv0jnrpeE7hgwR/N46nS","sig":"%s","msg_hash":"K9vGEuzCYCUcIXlhMZu20ke2K4mJhreguYct5MqAzhA="}}`, signature), true, false, defaultGasForTests, 0) + _, events, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"secp256k1_verify":{"iterations":1,"pubkey":"ArQojoh5TVlSSNA1HFlH5HcQsv0jnrpeE7hgwR/N46nS","sig":"%s","msg_hash":"K9vGEuzCYCUcIXlhMZu20ke2K4mJhreguYct5MqAzhA="}}`, signature), true, false, defaultGasForTests, 0) - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "true"}, - }, - }, - events, - ) + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + } } func TestEd25519Sign(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - require.Empty(t, initErr) + contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) - // priv z01UNefH2yjRslwZMmcHssdHmdEjzVvbxjr+MloUEYo= - // pub jh58UkC0FDsiupZBLdaqKUqYubJbk3LDaruZiJiy0Po= - // msg d2VuIG1vb24= - // msg_hash K9vGEuzCYCUcIXlhMZu20ke2K4mJhreguYct5MqAzhA= + // priv z01UNefH2yjRslwZMmcHssdHmdEjzVvbxjr+MloUEYo= + // pub jh58UkC0FDsiupZBLdaqKUqYubJbk3LDaruZiJiy0Po= + // msg d2VuIG1vb24= + // msg_hash K9vGEuzCYCUcIXlhMZu20ke2K4mJhreguYct5MqAzhA= - // https://paulmillr.com/noble/ - _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_sign":{"iterations":1,"msg":"d2VuIG1vb24=","privkey":"z01UNefH2yjRslwZMmcHssdHmdEjzVvbxjr+MloUEYo="}}`, true, false, defaultGasForTests, 0) - require.Empty(t, err) + // https://paulmillr.com/noble/ + _, events, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_sign":{"iterations":1,"msg":"d2VuIG1vb24=","privkey":"z01UNefH2yjRslwZMmcHssdHmdEjzVvbxjr+MloUEYo="}}`, true, false, defaultGasForTests, 0) + require.Empty(t, err) - signature := events[0][1].Value + signature := events[0][1].Value - _, events, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"ed25519_verify":{"iterations":1,"pubkey":"jh58UkC0FDsiupZBLdaqKUqYubJbk3LDaruZiJiy0Po=","sig":"%s","msg":"d2VuIG1vb24="}}`, signature), true, false, defaultGasForTests, 0) + _, events, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"ed25519_verify":{"iterations":1,"pubkey":"jh58UkC0FDsiupZBLdaqKUqYubJbk3LDaruZiJiy0Po=","sig":"%s","msg":"d2VuIG1vb24="}}`, signature), true, false, defaultGasForTests, 0) - require.Empty(t, err) - require.Equal(t, - []ContractEvent{ - { - {Key: "contract_address", Value: contractAddress.String()}, - {Key: "result", Value: "true"}, - }, - }, - events, - ) + require.Empty(t, err) + require.Equal(t, + []ContractEvent{ + { + {Key: "contract_address", Value: contractAddress.String()}, + {Key: "result", Value: "true"}, + }, + }, + events, + ) + }) + } } func TestBenchmarkEd25519BatchVerifyAPI(t *testing.T) { t.SkipNow() // Assaf: I wrote the benchmark like this because the init functions take testing.T // and not testing.B and I just wanted to quickly get a feel for the performance improvments - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm") + for _, tc := range testContracts { + t.Run(tc.CosmWasmVersion, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, tc.WasmFilePath) - contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) - start := time.Now() - _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1000,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU="]}}`, true, false, math.MaxUint64, 0) + start := time.Now() + _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"ed25519_batch_verify":{"iterations":1000,"pubkeys":["LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA=","LO2+Bt+/FIjomSaPB+I++LXkxgxwfnrKHLyvCic72rA="],"sigs":["8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg==","8O7nwhM71/B9srKwe8Ps39z5lAsLMMs6LxdvoPk0HXjEM97TNhKbdU6gEePT2MaaIUSiMEmoG28HIZMgMRTCDg=="],"msgs":["YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU=","YXNzYWYgd2FzIGhlcmU="]}}`, true, false, math.MaxUint64, 0) - require.Empty(t, err) + require.Empty(t, err) - elapsed := time.Since(start) - fmt.Printf("TestBenchmarkEd25519BatchVerifyAPI took %s\n", elapsed) + elapsed := time.Since(start) + fmt.Printf("TestBenchmarkEd25519BatchVerifyAPI took %s\n", elapsed) + }) + } } type GetResponse struct { @@ -2795,9 +3160,9 @@ type v1QueryResponse struct { } func TestV1EndpointsSanity(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/v1-sanity-contract.wasm") + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/v1-sanity-contract/contract.wasm") - contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":10, "expires":100}`, true, true, defaultGasForTests) + contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"increment":{"addition": 13}}`, true, true, math.MaxUint64, 0) @@ -2815,9 +3180,9 @@ func TestV1EndpointsSanity(t *testing.T) { } func TestV1QueryWorksWithEnv(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/v1-sanity-contract.wasm") + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/v1-sanity-contract/contract.wasm") - contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":10, "expires":0}`, true, true, defaultGasForTests) + contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":0}}`, true, true, defaultGasForTests) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 10) queryRes, qErr := queryHelper(t, keeper, ctx, contractAddress, `{"get":{}}`, true, true, math.MaxUint64) @@ -2831,12 +3196,11 @@ func TestV1QueryWorksWithEnv(t *testing.T) { } func TestV1ReplySanity(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/v1-sanity-contract.wasm") + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/v1-sanity-contract/contract.wasm") - contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":10, "expires":100}`, true, true, defaultGasForTests) + contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":100}}`, true, true, defaultGasForTests) fmt.Printf("LIORRR %s", string(contractAddress)) - // data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"increment":{"addition": 13}}`, true, true, math.MaxUint64, 0) // require.Empty(t, err) diff --git a/x/compute/internal/keeper/testdata/test-contract/Makefile b/x/compute/internal/keeper/testdata/test-contract/Makefile index 8a497ea13..cbc476820 100644 --- a/x/compute/internal/keeper/testdata/test-contract/Makefile +++ b/x/compute/internal/keeper/testdata/test-contract/Makefile @@ -1,4 +1,6 @@ all: + rustup target add wasm32-unknown-unknown + RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown cp ./target/wasm32-unknown-unknown/release/test_contract.wasm ./contract.wasm diff --git a/x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.lock b/x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.lock index dccf7aa24..9f5bd82a4 100644 --- a/x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.lock +++ b/x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.lock @@ -56,7 +56,7 @@ checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" [[package]] name = "cosmwasm-crypto" version = "1.0.0" -source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret-sdk#9ae97ec0ffbd0d9dbc16820fc4670d672e1e452c" +source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret-sdk#88cc21f02ee471a94ee7909a608d4d56afcd488d" dependencies = [ "digest", "ed25519-zebra", @@ -68,7 +68,7 @@ dependencies = [ [[package]] name = "cosmwasm-derive" version = "1.0.0" -source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret-sdk#9ae97ec0ffbd0d9dbc16820fc4670d672e1e452c" +source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret-sdk#88cc21f02ee471a94ee7909a608d4d56afcd488d" dependencies = [ "syn", ] @@ -76,7 +76,7 @@ dependencies = [ [[package]] name = "cosmwasm-std" version = "1.0.0" -source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret-sdk#9ae97ec0ffbd0d9dbc16820fc4670d672e1e452c" +source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret-sdk#88cc21f02ee471a94ee7909a608d4d56afcd488d" dependencies = [ "base64", "cosmwasm-crypto", @@ -92,7 +92,7 @@ dependencies = [ [[package]] name = "cosmwasm-storage" version = "1.0.0" -source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret-sdk#9ae97ec0ffbd0d9dbc16820fc4670d672e1e452c" +source = "git+https://github.com/scrtlabs/cosmwasm?branch=secret-sdk#88cc21f02ee471a94ee7909a608d4d56afcd488d" dependencies = [ "cosmwasm-std", "serde", @@ -467,9 +467,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.137" +version = "1.0.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47" dependencies = [ "serde_derive", ] @@ -494,9 +494,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c" dependencies = [ "proc-macro2", "quote", diff --git a/x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.toml b/x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.toml index cf8a757ec..9a32c16b9 100644 --- a/x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.toml +++ b/x/compute/internal/keeper/testdata/v1-sanity-contract/Cargo.toml @@ -31,7 +31,7 @@ backtraces = ["cosmwasm-std/backtraces"] with_floats = [] [dependencies] -cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret-sdk"} +cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret-sdk" } cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", branch = "secret-sdk" } schemars = "0.7" serde = { version = "1.0.114", default-features = false, features = [ diff --git a/x/compute/internal/keeper/testdata/v1-sanity-contract/Makefile b/x/compute/internal/keeper/testdata/v1-sanity-contract/Makefile index 9e8e71a50..387b26dc4 100644 --- a/x/compute/internal/keeper/testdata/v1-sanity-contract/Makefile +++ b/x/compute/internal/keeper/testdata/v1-sanity-contract/Makefile @@ -1,7 +1,8 @@ all: + rustup target add wasm32-unknown-unknown RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown - cp ./target/wasm32-unknown-unknown/release/v1_sanity_contract.wasm ../v1-sanity-contract.wasm + cp ./target/wasm32-unknown-unknown/release/v1_sanity_contract.wasm ./contract.wasm clean: cargo clean - -rm -f ./v1-sanity-contract.wasm \ No newline at end of file + -rm -f ./contract.wasm \ No newline at end of file diff --git a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs index 561319330..91e0f1acc 100644 --- a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs +++ b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs @@ -1,8 +1,14 @@ +use core::time; +use mem::MaybeUninit; +use std::{mem, thread}; + use cosmwasm_std::{ - coins, entry_point, to_binary, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, - QueryRequest, Reply, ReplyOn, Response, StdError, StdResult, SubMsg, SubMsgResult, WasmMsg, - WasmQuery, + attr, coins, entry_point, to_binary, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, + MessageInfo, QueryRequest, Reply, ReplyOn, Response, StdError, StdResult, Storage, SubMsg, + SubMsgResult, WasmMsg, WasmQuery, }; +use cosmwasm_storage::PrefixedStorage; +use secp256k1::Secp256k1; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg, QueryRes}; use crate::state::{count, count_read, expiration, expiration_read}; @@ -14,28 +20,511 @@ pub fn instantiate( _info: MessageInfo, msg: InstantiateMsg, ) -> StdResult { - count(deps.storage).save(&msg.counter)?; - let expires = env.block.height + msg.expires; - expiration(deps.storage).save(&expires)?; + match msg { + InstantiateMsg::Counter { counter, expires } => { + count(deps.storage).save(&counter)?; + let expires = env.block.height + expires; + expiration(deps.storage).save(&expires)?; + let mut resp = Response::default(); + resp.data = Some(env.contract.address.as_bytes().into()); + Ok(resp) + } - let mut resp = Response::default(); - resp.data = Some(env.contract.address.as_str().as_bytes().into()); - Ok(resp) + // These were ported from the v0.10 test-contract: + InstantiateMsg::Nop {} => Ok(Response::new().add_attribute("init", "🌈")), + InstantiateMsg::Callback { + contract_addr, + code_hash, + } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + code_hash, + contract_addr: contract_addr.clone(), + msg: Binary::from(r#"{"c":{"x":0,"y":13}}"#.as_bytes().to_vec()), + funds: vec![], + })) + .add_attribute("init with a callback", "🦄")), + InstantiateMsg::CallbackContractError { + contract_addr, + code_hash, + } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + code_hash, + msg: Binary::from(r#"{"contract_error":{"error_type":"generic_err"}}"#.as_bytes()), + funds: vec![], + })) + .add_attribute("init with a callback with contract error", "🤷‍♀️")), + InstantiateMsg::ContractError { error_type } => Err(map_string_to_error(error_type)), + InstantiateMsg::NoLogs {} => Ok(Response::new()), + InstantiateMsg::CallbackToInit { code_id, code_hash } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + msg: Binary::from(r#"{"nop":{}}"#.as_bytes().to_vec()), + code_hash, + funds: vec![], + label: String::from("fi"), + })) + .add_attribute("instantiating a new contract from init!", "🐙")), + InstantiateMsg::CallbackBadParams { + contract_addr, + code_hash, + } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + code_hash, + msg: Binary::from(r#"{"c":{"x":"banana","y":3}}"#.as_bytes().to_vec()), + funds: vec![], + })), + ), + InstantiateMsg::Panic {} => panic!("panic in init"), + InstantiateMsg::SendExternalQueryDepthCounter { + to, + depth, + code_hash, + } => Ok(Response::new().add_attribute( + format!( + "{}", + send_external_query_depth_counter(deps.as_ref(), to, depth, code_hash) + ), + "", + )), + InstantiateMsg::SendExternalQueryRecursionLimit { + to, + depth, + code_hash, + } => Ok(Response::new().add_attribute( + "message", + send_external_query_recursion_limit(deps.as_ref(), to, depth, code_hash)?, + )), + InstantiateMsg::CallToInit { + code_id, + code_hash, + label, + msg, + } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + code_hash, + msg: Binary(msg.as_bytes().into()), + funds: vec![], + label: label, + })) + .add_attribute("a", "a")), + InstantiateMsg::CallToExec { + addr, + code_hash, + msg, + } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: addr, + code_hash, + msg: Binary(msg.as_bytes().into()), + funds: vec![], + })) + .add_attribute("b", "b")), + InstantiateMsg::CallToQuery { + addr, + code_hash, + msg, + } => { + let answer: u32 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: addr, + code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + })) + .map_err(|err| { + StdError::generic_err(format!("Got an error from query: {:?}", err)) + })?; + + Ok(Response::new().add_attribute("c", format!("{}", answer))) + } + } } #[entry_point] -pub fn execute( - deps: DepsMut, - env: Env, - _info: MessageInfo, - msg: ExecuteMsg, -) -> StdResult { +pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { match msg { ExecuteMsg::Increment { addition } => increment(deps, addition), ExecuteMsg::TransferMoney { amount } => transfer_money(deps, amount), ExecuteMsg::RecursiveReply {} => recursive_reply(env, deps), ExecuteMsg::RecursiveReplyFail {} => recursive_reply_fail(env, deps), ExecuteMsg::InitNewContract {} => init_new_contract(env, deps), + + // These were ported from the v0.10 test-contract: + ExecuteMsg::A { + contract_addr, + code_hash, + x, + y, + } => Ok(a(deps, env, contract_addr, code_hash, x, y)), + ExecuteMsg::B { + contract_addr, + code_hash, + x, + y, + } => Ok(b(deps, env, contract_addr, code_hash, x, y)), + ExecuteMsg::C { x, y } => Ok(c(deps, env, x, y)), + ExecuteMsg::UnicodeData {} => Ok(unicode_data(deps, env)), + ExecuteMsg::EmptyLogKeyValue {} => Ok(empty_log_key_value(deps, env)), + ExecuteMsg::EmptyData {} => Ok(empty_data(deps, env)), + ExecuteMsg::NoData {} => Ok(no_data(deps, env)), + ExecuteMsg::ContractError { error_type } => Err(map_string_to_error(error_type)), + ExecuteMsg::NoLogs {} => Ok(Response::default()), + ExecuteMsg::CallbackToInit { code_id, code_hash } => { + Ok(exec_callback_to_init(deps, env, code_id, code_hash)) + } + ExecuteMsg::CallbackBadParams { + contract_addr, + code_hash, + } => Ok(exec_callback_bad_params(contract_addr, code_hash)), + ExecuteMsg::CallbackContractError { + contract_addr, + code_hash, + } => Ok(exec_with_callback_contract_error(contract_addr, code_hash)), + ExecuteMsg::SetState { key, value } => Ok(set_state(deps, key, value)), + ExecuteMsg::GetState { key } => Ok(get_state(deps, key)), + ExecuteMsg::RemoveState { key } => Ok(remove_state(deps, key)), + ExecuteMsg::TestCanonicalizeAddressErrors {} => test_canonicalize_address_errors(deps), + ExecuteMsg::Panic {} => panic!("panic in exec"), + ExecuteMsg::AllocateOnHeap { bytes } => Ok(allocate_on_heap(bytes as usize)), + ExecuteMsg::PassNullPointerToImportsShouldThrow { pass_type } => { + Ok(pass_null_pointer_to_imports_should_throw(deps, pass_type)) + } + ExecuteMsg::SendExternalQuery { to, code_hash } => { + Ok(Response::new().set_data(vec![send_external_query(deps.as_ref(), to, code_hash)])) + } + ExecuteMsg::SendExternalQueryDepthCounter { + to, + code_hash, + depth, + } => Ok( + Response::new().set_data(vec![send_external_query_depth_counter( + deps.as_ref(), + to, + depth, + code_hash, + )]), + ), + ExecuteMsg::SendExternalQueryRecursionLimit { + to, + code_hash, + depth, + } => Ok( + Response::new().set_data(to_binary(&send_external_query_recursion_limit( + deps.as_ref(), + to, + depth, + code_hash, + )?)?), + ), + ExecuteMsg::SendExternalQueryPanic { to, code_hash } => { + send_external_query_panic(deps, to, code_hash) + } + ExecuteMsg::SendExternalQueryError { to, code_hash } => { + send_external_query_stderror(deps, to, code_hash) + } + ExecuteMsg::SendExternalQueryBadAbi { to, code_hash } => { + send_external_query_bad_abi(deps, to, code_hash) + } + ExecuteMsg::SendExternalQueryBadAbiReceiver { to, code_hash } => { + send_external_query_bad_abi_receiver(deps, to, code_hash) + } + ExecuteMsg::LogMsgSender {} => { + Ok(Response::new().add_attribute("msg.sender", info.sender.as_str())) + } + ExecuteMsg::CallbackToLogMsgSender { to, code_hash } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: to.clone(), + code_hash, + msg: Binary::from(r#"{"log_msg_sender":{}}"#.as_bytes().to_vec()), + funds: vec![], + })) + .add_attribute("hi", "hey")), + ExecuteMsg::DepositToContract {} => { + Ok(Response::new().set_data(to_binary(&info.funds).unwrap())) + } + ExecuteMsg::SendFunds { + amount, + from: _, + to, + denom, + } => Ok(Response::new().add_message(CosmosMsg::Bank(BankMsg::Send { + to_address: to, + amount: coins(amount.into(), denom), + }))), + ExecuteMsg::SendFundsToInitCallback { + amount, + denom, + code_id, + code_hash, + } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + msg: Binary("{\"nop\":{}}".as_bytes().to_vec()), + code_id, + code_hash, + label: String::from("yo"), + funds: coins(amount.into(), denom), + })), + ), + ExecuteMsg::SendFundsToExecCallback { + amount, + denom, + to, + code_hash, + } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + msg: Binary("{\"no_data\":{}}".as_bytes().to_vec()), + contract_addr: to, + code_hash, + funds: coins(amount.into(), denom), + })), + ), + ExecuteMsg::Sleep { ms } => { + thread::sleep(time::Duration::from_millis(ms)); + + Ok(Response::new()) + } + ExecuteMsg::WithFloats { x, y } => Ok(Response::new().set_data(use_floats(x, y))), + ExecuteMsg::CallToInit { + code_id, + code_hash, + label, + msg, + } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + code_hash, + msg: Binary(msg.as_bytes().into()), + funds: vec![], + label: label, + })) + .add_attribute("a", "a")), + ExecuteMsg::CallToExec { + addr, + code_hash, + msg, + } => Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: addr, + code_hash: code_hash, + msg: Binary(msg.as_bytes().into()), + funds: vec![], + })) + .add_attribute("b", "b")), + ExecuteMsg::CallToQuery { + addr, + code_hash, + msg, + } => { + let answer: u32 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: addr, + code_hash: code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + })) + .map_err(|err| { + StdError::generic_err(format!("Got an error from query: {:?}", err)) + })?; + + Ok(Response::new().add_attribute("c", format!("{}", answer))) + } + ExecuteMsg::StoreReallyLongKey {} => { + let mut store = PrefixedStorage::new(deps.storage, b"my_prefix"); + store.set(REALLY_LONG, b"hello"); + Ok(Response::default()) + } + ExecuteMsg::StoreReallyShortKey {} => { + let mut store = PrefixedStorage::new(deps.storage, b"my_prefix"); + store.set(b"a", b"hello"); + Ok(Response::default()) + } + ExecuteMsg::StoreReallyLongValue {} => { + let mut store = PrefixedStorage::new(deps.storage, b"my_prefix"); + store.set(b"hello", REALLY_LONG); + Ok(Response::default()) + } + ExecuteMsg::Secp256k1Verify { + pubkey, + sig, + msg_hash, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.secp256k1_verify( + msg_hash.as_slice(), + sig.as_slice(), + pubkey.as_slice(), + ) { + Ok(result) => { + Ok(Response::new().add_attribute("result", format!("{}", result))) + } + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Secp256k1VerifyFromCrate { + pubkey, + sig, + msg_hash, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + let secp256k1_verifier = Secp256k1::verification_only(); + + let secp256k1_signature = + secp256k1::Signature::from_compact(&sig.0).map_err(|err| { + StdError::generic_err(format!("Malformed signature: {:?}", err)) + })?; + let secp256k1_pubkey = secp256k1::PublicKey::from_slice(pubkey.0.as_slice()) + .map_err(|err| StdError::generic_err(format!("Malformed pubkey: {:?}", err)))?; + let secp256k1_msg = + secp256k1::Message::from_slice(&msg_hash.as_slice()).map_err(|err| { + StdError::generic_err(format!( + "Failed to create a secp256k1 message from signed_bytes: {:?}", + err + )) + })?; + + res = match secp256k1_verifier.verify( + &secp256k1_msg, + &secp256k1_signature, + &secp256k1_pubkey, + ) { + Ok(()) => Ok(Response::new().add_attribute("result", "true")), + Err(_err) => Ok(Response::new().add_attribute("result", "false")), + }; + } + + return res; + } + ExecuteMsg::Ed25519Verify { + pubkey, + sig, + msg, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = + match deps + .api + .ed25519_verify(msg.as_slice(), sig.as_slice(), pubkey.as_slice()) + { + Ok(result) => { + Ok(Response::new().add_attribute("result", format!("{}", result))) + } + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Ed25519BatchVerify { + pubkeys, + sigs, + msgs, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.ed25519_batch_verify( + msgs.iter() + .map(|m| m.as_slice()) + .collect::>() + .as_slice(), + sigs.iter() + .map(|s| s.as_slice()) + .collect::>() + .as_slice(), + pubkeys + .iter() + .map(|p| p.as_slice()) + .collect::>() + .as_slice(), + ) { + Ok(result) => { + Ok(Response::new().add_attribute("result", format!("{}", result))) + } + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Secp256k1RecoverPubkey { + msg_hash, + sig, + recovery_param, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.secp256k1_recover_pubkey( + msg_hash.as_slice(), + sig.as_slice(), + recovery_param, + ) { + Ok(result) => Ok(Response::new() + .add_attribute("result", format!("{}", Binary(result).to_base64()))), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Secp256k1Sign { + msg, + privkey, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.secp256k1_sign(msg.as_slice(), privkey.as_slice()) { + Ok(result) => Ok(Response::new() + .add_attribute("result", format!("{}", Binary(result).to_base64()))), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } + ExecuteMsg::Ed25519Sign { + msg, + privkey, + iterations, + } => { + let mut res = Ok(Response::new()); + + // loop for benchmarking + for _ in 0..iterations { + res = match deps.api.ed25519_sign(msg.as_slice(), privkey.as_slice()) { + Ok(result) => Ok(Response::new() + .add_attribute("result", format!("{}", Binary(result).to_base64()))), + Err(err) => Err(StdError::generic_err(format!("{:?}", err))), + }; + } + + return res; + } } } @@ -108,7 +597,11 @@ pub fn init_new_contract(env: Env, _deps: DepsMut) -> StdResult { id: 1404, msg: CosmosMsg::Wasm(WasmMsg::Instantiate { code_hash: env.contract.code_hash, - msg: Binary::from("{\"counter\":150, \"expires\":100}".as_bytes().to_vec()), + msg: Binary::from( + "{\"counter\":{\"counter\":150, \"expires\":100}}" + .as_bytes() + .to_vec(), + ), funds: vec![], label: "new202213".to_string(), code_id: 1, @@ -124,6 +617,50 @@ pub fn init_new_contract(env: Env, _deps: DepsMut) -> StdResult { pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { QueryMsg::Get {} => to_binary(&get(deps, env)?), + + // These were ported from the v0.10 test-contract: + QueryMsg::ContractError { error_type } => Err(map_string_to_error(error_type)), + QueryMsg::Panic {} => panic!("panic in query"), + QueryMsg::ReceiveExternalQuery { num } => { + Ok(Binary(serde_json_wasm::to_vec(&(num + 1)).unwrap())) + } + QueryMsg::SendExternalQueryInfiniteLoop { to, code_hash } => { + send_external_query_infinite_loop(deps, to, code_hash) + } + QueryMsg::WriteToStorage {} => write_to_storage_in_query(deps.storage), + QueryMsg::RemoveFromStorage {} => remove_from_storage_in_query(deps.storage), + QueryMsg::SendExternalQueryDepthCounter { + to, + depth, + code_hash, + } => Ok(to_binary(&send_external_query_depth_counter( + deps, to, depth, code_hash, + )) + .unwrap()), + QueryMsg::SendExternalQueryRecursionLimit { + to, + depth, + code_hash, + } => to_binary(&send_external_query_recursion_limit( + deps, to, depth, code_hash, + )?), + QueryMsg::CallToQuery { + addr, + code_hash, + msg, + } => { + let answer: u32 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: addr, + code_hash: code_hash, + msg: Binary::from(msg.as_bytes().to_vec()), + })) + .map_err(|err| { + StdError::generic_err(format!("Got an error from query: {:?}", err)) + })?; + return Ok(to_binary(&answer)?); + } } } @@ -178,7 +715,7 @@ pub fn reply(deps: DepsMut, env: Env, reply: Reply) -> StdResult { (1404, SubMsgResult::Ok(s)) => match s.data { Some(x) => { let response = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { - callback_code_hash: env.contract.code_hash, + code_hash: env.contract.code_hash, contract_addr: String::from_utf8( Binary::from_base64(String::from_utf8(x.to_vec())?.as_str())?.to_vec(), )?, @@ -212,3 +749,489 @@ fn get(deps: Deps, env: Env) -> StdResult { Ok(QueryRes::Get { count }) } + +fn map_string_to_error(error_type: String) -> StdError { + let as_str: &str = &error_type[..]; + match as_str { + "generic_err" => StdError::generic_err("la la 🤯"), + "invalid_base64" => StdError::invalid_base64("ra ra 🤯"), + "invalid_utf8" => StdError::invalid_utf8("ka ka 🤯"), + "not_found" => StdError::not_found("za za 🤯"), + "parse_err" => StdError::parse_err("na na 🤯", "pa pa 🤯"), + "serialize_err" => StdError::serialize_err("ba ba 🤯", "ga ga 🤯"), + // "unauthorized" => StdError::unauthorized(), // dosn't exist in v1 + // "underflow" => StdError::underflow("minuend 🤯", "subtrahend 🤯"), // dosn't exist in v1 + _ => StdError::generic_err("catch-all 🤯"), + } +} + +fn send_external_query_recursion_limit( + deps: Deps, + contract_addr: String, + depth: u8, + code_hash: String, +) -> StdResult { + let result = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: contract_addr.clone(), + code_hash: code_hash.clone(), + msg: Binary( + format!( + r#"{{"send_external_query_recursion_limit":{{"to":"{}","code_hash":"{}","depth":{}}}}}"#, + contract_addr.clone().to_string(), + code_hash.clone().to_string(), + depth + 1 + ) + .into_bytes(), + ), + })); + + // 5 is the current recursion limit. + if depth != 5 { + result + } else { + match result { + Err(StdError::GenericErr { msg, .. }) + if msg == "Querier system error: Query recursion limit exceeded" => + { + Ok(String::from("Recursion limit was correctly enforced")) + } + _ => Err(StdError::generic_err( + "Recursion limit was bypassed! this is a bug!", + )), + } + } +} + +#[cfg(feature = "with_floats")] +fn use_floats(x: u8, y: u8) -> Binary { + let res: f64 = (x as f64) / (y as f64); + to_binary(&format!("{}", res)).unwrap() +} + +#[cfg(not(feature = "with_floats"))] +fn use_floats(x: u8, y: u8) -> Binary { + Binary(vec![x, y]) +} + +fn send_external_query(deps: Deps, contract_addr: String, code_hash: String) -> u8 { + let answer: u8 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + code_hash: code_hash, + msg: Binary::from(r#"{"receive_external_query":{"num":2}}"#.as_bytes().to_vec()), + })) + .unwrap(); + answer +} + +fn send_external_query_depth_counter( + deps: Deps, + contract_addr: String, + depth: u8, + code_hash: String, +) -> u8 { + if depth == 0 { + return 0; + } + + let answer: u8 = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: contract_addr.clone(), + code_hash: code_hash.clone(), + msg: Binary( + format!( + r#"{{"send_external_query_depth_counter":{{"to":"{}","code_hash":"{}","depth":{}}}}}"#, + contract_addr.clone(), + code_hash.clone(), + depth - 1 + ) + .into(), + ), + })) + .unwrap(); + + answer + 1 +} + +fn send_external_query_panic( + deps: DepsMut, + contract_addr: String, + code_hash: String, +) -> StdResult { + let err = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: Binary::from(r#"{"panic":{}}"#.as_bytes().to_vec()), + code_hash: code_hash, + })) + .unwrap_err(); + + Err(err) +} + +fn send_external_query_stderror( + deps: DepsMut, + contract_addr: String, + code_hash: String, +) -> StdResult { + let answer = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: Binary::from( + r#"{"contract_error":{"error_type":"generic_err"}}"# + .as_bytes() + .to_vec(), + ), + code_hash: code_hash, + })); + + match answer { + Ok(wtf) => Ok(Response::new().set_data(wtf)), + Err(e) => Err(e), + } +} + +fn send_external_query_bad_abi( + deps: DepsMut, + contract_addr: String, + code_hash: String, +) -> StdResult { + let answer = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + code_hash: code_hash, + msg: Binary::from( + r#""contract_error":{"error_type":"generic_err"}}"#.as_bytes().to_vec(), + ), + })); + + match answer { + Ok(wtf) => Ok(Response::new().set_data(wtf)), + Err(e) => Err(e), + } +} + +fn send_external_query_bad_abi_receiver( + deps: DepsMut, + contract_addr: String, + code_hash: String, +) -> StdResult { + let answer = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: Binary::from(r#"{"receive_external_query":{"num":25}}"#.as_bytes().to_vec()), + code_hash: code_hash, + })); + + match answer { + Ok(wtf) => Ok(Response::new().add_attribute("wtf", wtf)), + Err(e) => Err(e), + } +} + +fn exec_callback_bad_params(contract_addr: String, code_hash: String) -> Response { + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + code_hash: code_hash, + msg: Binary::from(r#"{"c":{"x":"banana","y":3}}"#.as_bytes().to_vec()), + funds: vec![], + })) +} + +pub fn a( + _deps: DepsMut, + _env: Env, + contract_addr: String, + code_hash: String, + x: u8, + y: u8, +) -> Response { + Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + code_hash: code_hash.clone(), + msg: Binary::from( + format!( + "{{\"b\":{{\"x\":{} ,\"y\": {},\"contract_addr\": \"{}\",\"code_hash\": \"{}\" }}}}", + x, + y, + contract_addr.as_str(), + &code_hash + ) + .as_bytes() + .to_vec(), + ), + funds: vec![], + })) + .add_attribute("banana", "🍌") + .set_data(vec![x, y]) +} + +pub fn b( + _deps: DepsMut, + _env: Env, + contract_addr: String, + code_hash: String, + x: u8, + y: u8, +) -> Response { + Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + code_hash: code_hash, + msg: Binary::from( + format!("{{\"c\":{{\"x\":{} ,\"y\": {} }}}}", x + 1, y + 1) + .as_bytes() + .to_vec(), + ), + funds: vec![], + })) + .add_attribute("kiwi", "🥝") + .set_data(vec![x + y]) +} + +pub fn c(_deps: DepsMut, _env: Env, x: u8, y: u8) -> Response { + Response::new() + .add_attribute("watermelon", "🍉") + .set_data(vec![x + y]) +} + +pub fn empty_log_key_value(_deps: DepsMut, _env: Env) -> Response { + Response::new().add_attributes(vec![ + attr("my value is empty", ""), + attr("", "my key is empty"), + ]) +} + +pub fn empty_data(_deps: DepsMut, _env: Env) -> Response { + Response::new().set_data(vec![]) +} + +pub fn unicode_data(_deps: DepsMut, _env: Env) -> Response { + Response::new().set_data("🍆🥑🍄".as_bytes().to_vec()) +} + +pub fn no_data(_deps: DepsMut, _env: Env) -> Response { + Response::new() +} + +pub fn exec_callback_to_init( + _deps: DepsMut, + _env: Env, + code_id: u64, + code_hash: String, +) -> Response { + Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + msg: Binary::from("{\"nop\":{}}".as_bytes().to_vec()), + code_hash, + funds: vec![], + label: String::from("hi"), + })) + .add_attribute("instantiating a new contract", "🪂") +} + +fn exec_with_callback_contract_error(contract_addr: String, code_hash: String) -> Response { + Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_addr.clone(), + code_hash: code_hash, + msg: Binary::from( + r#"{"contract_error":{"error_type":"generic_err"}}"# + .as_bytes() + .to_vec(), + ), + funds: vec![], + })) + .add_attribute("exec with a callback with contract error", "🤷‍♂️") +} + +fn allocate_on_heap(bytes: usize) -> Response { + let mut values: Vec = vec![0; bytes]; + values[bytes - 1] = 1; + + Response::new().set_data("😅".as_bytes().to_vec()) +} + +fn get_state(deps: DepsMut, key: String) -> Response { + let store = PrefixedStorage::new(deps.storage, b"my_prefix"); + + match store.get(key.as_bytes()) { + Some(value) => Response::new().set_data(value), + None => Response::default(), + } +} + +fn set_state(deps: DepsMut, key: String, value: String) -> Response { + let mut store = PrefixedStorage::new(deps.storage, b"my_prefix"); + store.set(key.as_bytes(), value.as_bytes()); + Response::default() +} + +fn remove_state(deps: DepsMut, key: String) -> Response { + let mut store = PrefixedStorage::new(deps.storage, b"my_prefix"); + store.remove(key.as_bytes()); + Response::default() +} + +#[allow(invalid_value)] +#[allow(unused_must_use)] +fn pass_null_pointer_to_imports_should_throw(deps: DepsMut, pass_type: String) -> Response { + let null_ptr_slice: &[u8] = unsafe { MaybeUninit::zeroed().assume_init() }; + + match &pass_type[..] { + "read_db_key" => { + deps.storage.get(null_ptr_slice); + } + "write_db_key" => { + deps.storage.set(null_ptr_slice, b"write value"); + } + "write_db_value" => { + deps.storage.set(b"write key", null_ptr_slice); + } + "remove_db_key" => { + deps.storage.remove(null_ptr_slice); + } + "canonicalize_address_input" => { + deps.api + .addr_canonicalize(unsafe { MaybeUninit::zeroed().assume_init() }); + } + "canonicalize_address_output" => { /* TODO */ } + "humanize_address_input" => { + deps.api + .addr_humanize(unsafe { MaybeUninit::zeroed().assume_init() }); + } + "humanize_address_output" => { /* TODO */ } + "validate_address_input" => { + deps.api + .addr_validate(unsafe { MaybeUninit::zeroed().assume_init() }); + } + "validate_address_output" => { /* TODO */ } + _ => {} + }; + + Response::default() +} + +fn test_canonicalize_address_errors(deps: DepsMut) -> StdResult { + match deps.api.addr_canonicalize("") { + Err(StdError::GenericErr { msg }) => { + if msg != String::from("canonicalize_address errored: input is empty") { + return Err(StdError::generic_err( + "empty address should have failed with 'canonicalize_address errored: input is empty'", + )); + } + // all is good, continue + } + _ => return Err(StdError::generic_err( + "empty address should have failed with 'canonicalize_address errored: input is empty'", + )), + } + + match deps.api.addr_canonicalize(" ") { + Err(StdError::GenericErr { msg }) => { + if msg != String::from("canonicalize_address errored: input is empty") { + return Err(StdError::generic_err( + "empty trimmed address should have failed with 'canonicalize_address errored: input is empty'", + )); + } + // all is good, continue + } + _ => { + return Err(StdError::generic_err( + "empty trimmed address should have failed with 'canonicalize_address errored: input is empty'", + )) + } + } + + match deps.api.addr_canonicalize("cosmos1h99hrcc54ms9lxxxx") { + Err(StdError::GenericErr { msg }) => { + if msg != String::from("canonicalize_address errored: invalid checksum") { + return Err(StdError::generic_err( + "bad bech32 should have failed with 'canonicalize_address errored: invalid checksum'", + )); + } + // all is good, continue + } + _ => return Err(StdError::generic_err( + "bad bech32 should have failed with 'canonicalize_address errored: invalid checksum'", + )), + } + + match deps.api.addr_canonicalize("cosmos1h99hrcc54ms9luwpex9kw0rwdt7etvfdyxh6gu") { + Err(StdError::GenericErr { msg }) => { + if msg != String::from("canonicalize_address errored: wrong address prefix: \"cosmos\"") + { + return Err(StdError::generic_err( + "bad prefix should have failed with 'canonicalize_address errored: wrong address prefix: \"cosmos\"'", + )); + } + // all is good, continue + } + _ => { + return Err(StdError::generic_err( + "bad prefix should have failed with 'canonicalize_address errored: wrong address prefix: \"cosmos\"'", + )) + } + } + + Ok(Response::new().set_data("🤟".as_bytes().to_vec())) +} + +/////////////////////////////// Query /////////////////////////////// + +fn send_external_query_infinite_loop( + deps: Deps, + contract_addr: String, + code_hash: String, +) -> StdResult { + let answer = deps + .querier + .query::(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: contract_addr.clone(), + code_hash: code_hash.clone(), + msg: Binary::from( + format!( + r#"{{"send_external_query_infinite_loop":{{"to":"{}", "code_hash":"{}"}}}}"#, + contract_addr.clone().to_string(), + &code_hash + ) + .as_bytes() + .to_vec(), + ), + })); + + match answer { + Ok(wtf) => Ok(Binary(wtf.into())), + Err(e) => Err(e), + } +} + +fn write_to_storage_in_query(storage: &dyn Storage) -> StdResult { + #[allow(clippy::cast_ref_to_mut)] + let storage = unsafe { &mut *(storage as *const _ as *mut dyn Storage) }; + storage.set(b"abcd", b"dcba"); + + Ok(Binary(vec![])) +} + +fn remove_from_storage_in_query(storage: &dyn Storage) -> StdResult { + #[allow(clippy::cast_ref_to_mut)] + let storage = unsafe { &mut *(storage as *const _ as *mut dyn Storage) }; + storage.remove(b"abcd"); + + Ok(Binary(vec![])) +} + +//// consts + +const REALLY_LONG: &[u8] = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; diff --git a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs index b67d595ee..8f9d99700 100644 --- a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs +++ b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs @@ -1,26 +1,289 @@ +use cosmwasm_std::Binary; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct InstantiateMsg { - pub counter: u64, - pub expires: u64, +pub enum InstantiateMsg { + Counter { + counter: u64, + expires: u64, + }, + + // These were ported from the v0.10 test-contract: + Nop {}, + Callback { + contract_addr: String, + code_hash: String, + }, + CallbackContractError { + contract_addr: String, + code_hash: String, + }, + ContractError { + error_type: String, + }, + NoLogs {}, + CallbackToInit { + code_id: u64, + code_hash: String, + }, + CallbackBadParams { + contract_addr: String, + code_hash: String, + }, + Panic {}, + SendExternalQueryDepthCounter { + to: String, + depth: u8, + code_hash: String, + }, + SendExternalQueryRecursionLimit { + to: String, + depth: u8, + code_hash: String, + }, + CallToInit { + code_id: u64, + code_hash: String, + label: String, + msg: String, + }, + CallToExec { + addr: String, + code_hash: String, + msg: String, + }, + CallToQuery { + addr: String, + code_hash: String, + msg: String, + }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case")] pub enum ExecuteMsg { - Increment { addition: u64 }, - TransferMoney { amount: u64 }, + Increment { + addition: u64, + }, + TransferMoney { + amount: u64, + }, RecursiveReply {}, RecursiveReplyFail {}, InitNewContract {}, + + // These were ported from the v0.10 test-contract: + A { + contract_addr: String, + code_hash: String, + x: u8, + y: u8, + }, + B { + contract_addr: String, + code_hash: String, + x: u8, + y: u8, + }, + C { + x: u8, + y: u8, + }, + UnicodeData {}, + EmptyLogKeyValue {}, + EmptyData {}, + NoData {}, + ContractError { + error_type: String, + }, + NoLogs {}, + CallbackToInit { + code_id: u64, + code_hash: String, + }, + CallbackContractError { + contract_addr: String, + code_hash: String, + }, + CallbackBadParams { + contract_addr: String, + code_hash: String, + }, + SetState { + key: String, + value: String, + }, + GetState { + key: String, + }, + RemoveState { + key: String, + }, + TestCanonicalizeAddressErrors {}, + Panic {}, + AllocateOnHeap { + bytes: u32, + }, + PassNullPointerToImportsShouldThrow { + pass_type: String, + }, + SendExternalQuery { + to: String, + code_hash: String, + }, + SendExternalQueryPanic { + to: String, + code_hash: String, + }, + SendExternalQueryError { + to: String, + code_hash: String, + }, + SendExternalQueryBadAbi { + to: String, + code_hash: String, + }, + SendExternalQueryBadAbiReceiver { + to: String, + code_hash: String, + }, + LogMsgSender {}, + CallbackToLogMsgSender { + to: String, + code_hash: String, + }, + DepositToContract {}, + SendFunds { + amount: u32, + denom: String, + to: String, + from: String, + }, + SendFundsToInitCallback { + amount: u32, + denom: String, + code_id: u64, + code_hash: String, + }, + SendFundsToExecCallback { + amount: u32, + denom: String, + to: String, + code_hash: String, + }, + Sleep { + ms: u64, + }, + SendExternalQueryDepthCounter { + to: String, + code_hash: String, + depth: u8, + }, + SendExternalQueryRecursionLimit { + to: String, + code_hash: String, + depth: u8, + }, + WithFloats { + x: u8, + y: u8, + }, + CallToInit { + code_id: u64, + code_hash: String, + label: String, + msg: String, + }, + CallToExec { + addr: String, + code_hash: String, + msg: String, + }, + CallToQuery { + addr: String, + code_hash: String, + msg: String, + }, + StoreReallyLongKey {}, + StoreReallyShortKey {}, + StoreReallyLongValue {}, + Secp256k1Verify { + pubkey: Binary, + sig: Binary, + msg_hash: Binary, + iterations: u32, + }, + Secp256k1VerifyFromCrate { + pubkey: Binary, + sig: Binary, + msg_hash: Binary, + iterations: u32, + }, + Ed25519Verify { + pubkey: Binary, + sig: Binary, + msg: Binary, + iterations: u32, + }, + Ed25519BatchVerify { + pubkeys: Vec, + sigs: Vec, + msgs: Vec, + iterations: u32, + }, + Secp256k1RecoverPubkey { + msg_hash: Binary, + sig: Binary, + recovery_param: u8, + iterations: u32, + }, + Secp256k1Sign { + msg: Binary, + privkey: Binary, + iterations: u32, + }, + Ed25519Sign { + msg: Binary, + privkey: Binary, + iterations: u32, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryMsg { Get {}, + + // These were ported from the v0.10 test-contract: + ContractError { + error_type: String, + }, + Panic {}, + ReceiveExternalQuery { + num: u8, + }, + SendExternalQueryInfiniteLoop { + to: String, + code_hash: String, + }, + WriteToStorage {}, + RemoveFromStorage {}, + SendExternalQueryDepthCounter { + to: String, + depth: u8, + code_hash: String, + }, + SendExternalQueryRecursionLimit { + to: String, + depth: u8, + code_hash: String, + }, + CallToQuery { + addr: String, + code_hash: String, + msg: String, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]