Skip to content

Commit

Permalink
Merge pull request #197 from CosmWasm/update-rust-and-types
Browse files Browse the repository at this point in the history
Update Rust and Types
  • Loading branch information
webmaster128 authored Mar 3, 2021
2 parents b2eaa90 + 632a1d5 commit a7cedc3
Show file tree
Hide file tree
Showing 16 changed files with 132 additions and 18 deletions.
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ jobs:
# All checks on the codebase that can run in parallel to build_library
sanity:
docker:
- image: circleci/rust:1.49.0-buster
- image: circleci/rust:1.50.0-buster
steps:
- checkout
- run:
Expand Down Expand Up @@ -39,7 +39,7 @@ jobs:

build_library:
docker:
- image: circleci/rust:1.49.0-buster
- image: circleci/rust:1.50.0-buster
steps:
- checkout
- run:
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@ and this project adheres to

### Added

- Add Submessages and Subcall types ([#197])
- Add WasmMsg::Migrate message type ([#197])
- Add IBC and Stargate message types ([#167], [#174])
- Expose IBC entry points and AnalyzeCode ([#167], [#174])

[#167]: https://github.com/CosmWasm/wasmvm/pull/167
[#174]: https://github.com/CosmWasm/wasmvm/pull/174
[#197]: https://github.com/CosmWasm/wasmvm/pull/197

### Changed

- Renamed the Go type `CodeID` to `Checksum` to clarify the difference between
the numeric code ID assigned by x/wasm and the hash used to identify it in the cache.
- Update required Rust version in build scripts to 1.50 ([#197])

## 0.13.0

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.PHONY: all build build-rust build-go test

BUILDERS_PREFIX := cosmwasm/go-ext-builder:0004
BUILDERS_PREFIX := cosmwasm/go-ext-builder:0005
USER_ID := $(shell id -u)
USER_GROUP = $(shell id -g)

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ link with, and Go developers should just be able to import this directly.

## Supported Platforms

Requires Rust 1.50+, Requires Go 1.15+

Since this package includes a rust prebuilt dll, you cannot just import the go code,
but need to be on a system that works with an existing dll. Currently this is Linux
(tested on Ubuntu, Debian, and CentOS7) and MacOS. We have a build system for Windows,
Expand Down
18 changes: 9 additions & 9 deletions api/lib_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func TestInstantiate(t *testing.T) {
res, cost, err := Instantiate(cache, checksum, env, info, msg, &igasMeter, store, api, &querier, TESTING_GAS_LIMIT, TESTING_PRINT_DEBUG)
require.NoError(t, err)
requireOkResponse(t, res, 0)
assert.Equal(t, uint64(0xd830), cost)
assert.Equal(t, uint64(0xdb95), cost)

var result types.ContractResult
err = json.Unmarshal(res, &result)
Expand Down Expand Up @@ -215,7 +215,7 @@ func TestHandle(t *testing.T) {
diff := time.Now().Sub(start)
require.NoError(t, err)
requireOkResponse(t, res, 0)
assert.Equal(t, uint64(0xd830), cost)
assert.Equal(t, uint64(0xdb95), cost)
t.Logf("Time (%d gas): %s\n", cost, diff)

// execute with the same store
Expand All @@ -228,7 +228,7 @@ func TestHandle(t *testing.T) {
res, cost, err = Handle(cache, checksum, env, info, []byte(`{"release":{}}`), &igasMeter2, store, api, &querier, TESTING_GAS_LIMIT, TESTING_PRINT_DEBUG)
diff = time.Now().Sub(start)
require.NoError(t, err)
assert.Equal(t, uint64(0x112a4), cost)
assert.Equal(t, uint64(0x12168), cost)
t.Logf("Time (%d gas): %s\n", cost, diff)

// make sure it read the balance properly and we got 250 atoms
Expand Down Expand Up @@ -270,7 +270,7 @@ func TestHandleCpuLoop(t *testing.T) {
diff := time.Now().Sub(start)
require.NoError(t, err)
requireOkResponse(t, res, 0)
assert.Equal(t, uint64(0xd830), cost)
assert.Equal(t, uint64(0xdb95), cost)
t.Logf("Time (%d gas): %s\n", cost, diff)

// execute a cpu loop
Expand Down Expand Up @@ -421,7 +421,7 @@ func TestMultipleInstances(t *testing.T) {
require.NoError(t, err)
requireOkResponse(t, res, 0)
// we now count wasm gas charges and db writes
assert.Equal(t, uint64(0xd7ae), cost)
assert.Equal(t, uint64(0xdb2c), cost)

// instance2 controlled by mary
gasMeter2 := NewMockGasMeter(TESTING_GAS_LIMIT)
Expand All @@ -432,14 +432,14 @@ func TestMultipleInstances(t *testing.T) {
res, cost, err = Instantiate(cache, checksum, env, info, msg, &igasMeter2, store2, api, &querier, TESTING_GAS_LIMIT, TESTING_PRINT_DEBUG)
require.NoError(t, err)
requireOkResponse(t, res, 0)
assert.Equal(t, uint64(0xd7f7), cost)
assert.Equal(t, uint64(0xdb75), cost)

// fail to execute store1 with mary
resp := exec(t, cache, checksum, "mary", store1, api, querier, 0x9a35)
resp := exec(t, cache, checksum, "mary", store1, api, querier, 0xa6c3)
require.Equal(t, "Unauthorized", resp.Err)

// succeed to execute store1 with fred
resp = exec(t, cache, checksum, "fred", store1, api, querier, 0x112a4)
resp = exec(t, cache, checksum, "fred", store1, api, querier, 0x12168)
require.Equal(t, "", resp.Err)
require.Equal(t, 1, len(resp.Ok.Messages))
attributes := resp.Ok.Attributes
Expand All @@ -448,7 +448,7 @@ func TestMultipleInstances(t *testing.T) {
require.Equal(t, "bob", attributes[1].Value)

// succeed to execute store2 with mary
resp = exec(t, cache, checksum, "mary", store2, api, querier, 0x112a4)
resp = exec(t, cache, checksum, "mary", store2, api, querier, 0x12168)
require.Equal(t, "", resp.Err)
require.Equal(t, 1, len(resp.Ok.Messages))
attributes = resp.Ok.Attributes
Expand Down
Binary file modified api/testdata/hackatom.wasm
Binary file not shown.
Binary file modified api/testdata/ibc_reflect.wasm
Binary file not shown.
Binary file modified api/testdata/queue.wasm
Binary file not shown.
Binary file modified api/testdata/reflect.wasm
Binary file not shown.
4 changes: 2 additions & 2 deletions builders/Dockerfile.alpine
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ RUN set -eux; \

RUN wget "https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-musl/rustup-init"
RUN chmod +x rustup-init
RUN ./rustup-init -y --no-modify-path --default-toolchain 1.49.0; rm rustup-init
RUN ./rustup-init -y --no-modify-path --default-toolchain 1.50.0; rm rustup-init
RUN chmod -R a+w $RUSTUP_HOME $CARGO_HOME

# needed for
# /usr/lib/gcc/x86_64-alpine-linux-musl/9.3.0/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find crti.o: No such file or directory
ENV LIBRARY_PATH=/usr/local/rustup/toolchains/1.49.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib:$LIBRARY_PATH
ENV LIBRARY_PATH=/usr/local/rustup/toolchains/1.50.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib:$LIBRARY_PATH

# prepare go cache dirs
RUN mkdir -p /.cache/go-build
Expand Down
2 changes: 1 addition & 1 deletion builders/Dockerfile.centos7
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ENV RUSTUP_HOME=/usr/local/rustup \
RUN url="https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init"; \
wget "$url"; \
chmod +x rustup-init; \
./rustup-init -y --no-modify-path --default-toolchain 1.49.0; \
./rustup-init -y --no-modify-path --default-toolchain 1.50.0; \
rm rustup-init; \
chmod -R a+w $RUSTUP_HOME $CARGO_HOME; \
rustup --version; \
Expand Down
2 changes: 1 addition & 1 deletion builders/Dockerfile.cross
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM rust:1.49.0-buster
FROM rust:1.50.0-buster

# Install build dependencies
RUN apt-get update
Expand Down
2 changes: 1 addition & 1 deletion builders/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Versioned by a simple counter that is not bound to a specific CosmWasm version
# See builders/README.md
BUILDERS_PREFIX := cosmwasm/go-ext-builder:0004
BUILDERS_PREFIX := cosmwasm/go-ext-builder:0005

.PHONY: docker-image-centos7
docker-image-centos7:
Expand Down
4 changes: 4 additions & 0 deletions builders/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ can do the cross-compilation.

## Changelog

**Version 0005:**

- Update Rust to 1.50.0.

**Version 0004:**

- Update Rust to 1.49.0.
Expand Down
47 changes: 46 additions & 1 deletion types/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,41 @@ type ContractResult struct {
type Response struct {
// Messages comes directly from the contract and is it's request for action
Messages []CosmosMsg `json:"messages"`
// Submessages are like Messages, but they guarantee a reply to the calling contract
// after their execution, and return both success and error rather than auto-failing on error
Submessages []SubMsg `json:"submessages"`
// base64-encoded bytes to return as ABCI.Data field
Data []byte `json:"data"`
// attributes for a log event to return over abci interface
Attributes []EventAttribute `json:"attributes"`
}

// EventAttributes must encode empty array as []
type EventAttributes []EventAttribute

// MarshalJSON ensures that we get [] for empty arrays
func (a EventAttributes) MarshalJSON() ([]byte, error) {
if len(a) == 0 {
return []byte("[]"), nil
}
var raw []EventAttribute = a
return json.Marshal(raw)
}

// UnmarshalJSON ensures that we get [] for empty arrays
func (a *EventAttributes) UnmarshalJSON(data []byte) error {
// make sure we deserialize [] back to null
if string(data) == "[]" || string(data) == "null" {
return nil
}
var raw []EventAttribute
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
*a = raw
return nil
}

// EventAttribute
type EventAttribute struct {
Key string `json:"key"`
Expand Down Expand Up @@ -125,6 +154,7 @@ type StargateMsg struct {
type WasmMsg struct {
Execute *ExecuteMsg `json:"execute,omitempty"`
Instantiate *InstantiateMsg `json:"instantiate,omitempty"`
Migrate *MigrateMsg `json:"migrate,omitempty"`
}

// ExecuteMsg is used to call another defined contract on this chain.
Expand All @@ -145,12 +175,27 @@ type ExecuteMsg struct {
Send Coins `json:"send"`
}

// InstantiateMsg will create a new contract instance from a previously uploaded CodeID.
// This allows one contract to spawn "sub-contracts".
type InstantiateMsg struct {
// CodeID is the reference to the wasm byte code as used by the Cosmos-SDK
CodeID uint64 `json:"code_id"`
// Msg is assumed to be a json-encoded message, which will be passed directly
// as `userMsg` when calling `Handle` on the above-defined contract
// as `userMsg` when calling `Init` on a new contract with the above-defined CodeID
Msg []byte `json:"msg"`
// Send is an optional amount of coins this contract sends to the called contract
Send Coins `json:"send"`
}

// MigrateMsg will migrate an existing contract from it's current wasm code (logic)
// to another previously uploaded wasm code. It requires the calling contract to be
// listed as "admin" of the contract to be migrated.
type MigrateMsg struct {
// ContractAddr is the sdk.AccAddress of the target contract, to migrate.
ContractAddr string `json:"contract_addr"`
// NewCodeID is the reference to the wasm byte code for the new logic to migrate to
NewCodeID uint64 `json:"new_code_id"`
// Msg is assumed to be a json-encoded message, which will be passed directly
// as `userMsg` when calling `Migrate` on the above-defined contract
Msg []byte `json:"msg"`
}
59 changes: 59 additions & 0 deletions types/subcall.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package types

import "encoding/json"

// SubMsg wraps a CosmosMsg with some metadata for handling replies (ID) and optionally
// limiting the gas usage (GasLimit)
type SubMsg struct {
ID uint64 `json:"id"`
Msg CosmosMsg `json:"msg"`
GasLimit *uint64 `json:"gas_limit,omitempty"`
}

type Reply struct {
ID uint64 `json:"id"`
Result SubcallResult `json:"result"`
}

// SubcallResult is the raw response we return from the sdk -> reply after executing a SubMsg.
// This is mirrors Rust's ContractResult<SubcallResponse>.
type SubcallResult struct {
Ok *SubcallResponse `json:"ok,omitempty"`
Err string `json:"error,omitempty"`
}

type SubcallResponse struct {
Events Events `json:"events"`
Data []byte `json:"data,omitempty"`
}

// Events must encode empty array as []
type Events []Event

// MarshalJSON ensures that we get [] for empty arrays
func (e Events) MarshalJSON() ([]byte, error) {
if len(e) == 0 {
return []byte("[]"), nil
}
var raw []Event = e
return json.Marshal(raw)
}

// UnmarshalJSON ensures that we get [] for empty arrays
func (e *Events) UnmarshalJSON(data []byte) error {
// make sure we deserialize [] back to null
if string(data) == "[]" || string(data) == "null" {
return nil
}
var raw []Event
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
*e = raw
return nil
}

type Event struct {
Type string `json:"type"`
Attributes EventAttributes `json:"attributes"`
}

0 comments on commit a7cedc3

Please sign in to comment.