Skip to content

Commit

Permalink
Merge pull request #19 from cosmwasm/vw/auto-gzip-contracts
Browse files Browse the repository at this point in the history
Add auto-gzip contracts in cli when uploading
  • Loading branch information
ethanfrey authored Jan 14, 2020
2 parents e075a16 + 10e49dc commit d365da2
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 0 deletions.
22 changes: 22 additions & 0 deletions x/wasm/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cli

import (
"bufio"
"fmt"
"io/ioutil"
"strconv"

Expand All @@ -15,6 +16,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"

wasmUtils "github.com/cosmwasm/wasmd/x/wasm/client/utils"
"github.com/cosmwasm/wasmd/x/wasm/internal/types"
)

Expand All @@ -23,6 +25,9 @@ const (
flagAmount = "amount"
)

// limit max bytes read to prevent gzip bombs
const maxSize = 400 * 1024

// GetTxCmd returns the transaction commands for this module
func GetTxCmd(cdc *codec.Codec) *cobra.Command {
txCmd := &cobra.Command{
Expand Down Expand Up @@ -57,6 +62,23 @@ func StoreCodeCmd(cdc *codec.Codec) *cobra.Command {
return err
}

// limit the input size
if len(wasm) > maxSize {
return fmt.Errorf("input size exceeds the max size allowed (allowed:%d, actual: %d)",
maxSize, len(wasm))
}

// gzip the wasm file
if wasmUtils.IsWasm(wasm) {
wasm, err = wasmUtils.GzipIt(wasm)

if err != nil {
return err
}
} else if !wasmUtils.IsGzip(wasm) {
return fmt.Errorf("invalid input file. Use wasm binary or gzip")
}

// build and sign the transaction, then broadcast to Tendermint
msg := types.MsgStoreCode{
Sender: cliCtx.GetFromAddress(),
Expand Down
38 changes: 38 additions & 0 deletions x/wasm/client/utils/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package utils

import (
"bytes"
"compress/gzip"
)

var (
gzipIdent = []byte("\x1F\x8B\x08")
wasmIdent = []byte("\x00\x61\x73\x6D")
)

// IsGzip returns checks if the file contents are gzip compressed
func IsGzip(input []byte) bool {
return bytes.Equal(input[:3], gzipIdent)
}

// IsWasm checks if the file contents are of wasm binary
func IsWasm(input []byte) bool {
return bytes.Equal(input[:4], wasmIdent)
}

// GzipIt compresses the input ([]byte)
func GzipIt(input []byte) ([]byte, error) {
// Create gzip writer.
var b bytes.Buffer
w := gzip.NewWriter(&b)
_, err := w.Write(input)
if err != nil {
return nil, err
}
err = w.Close() // You must close this first to flush the bytes to the buffer.
if err != nil {
return nil, err
}

return b.Bytes(), nil
}
64 changes: 64 additions & 0 deletions x/wasm/client/utils/utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package utils

import (
"github.com/stretchr/testify/require"
"io/ioutil"
"testing"
)

func GetTestData() ([]byte, []byte, []byte, error){
wasmCode, err := ioutil.ReadFile("../../internal/keeper/testdata/contract.wasm")

if err != nil {
return nil, nil, nil, err
}

gzipData, err := GzipIt(wasmCode)
if err != nil {
return nil, nil, nil, err
}

someRandomStr := []byte("hello world")

return wasmCode, someRandomStr, gzipData, nil
}

func TestIsWasm (t *testing.T) {
wasmCode, someRandomStr, gzipData, err := GetTestData()
require.NoError(t, err)

t.Log("should return false for some random string data")
require.False(t, IsWasm(someRandomStr))
t.Log("should return false for gzip data")
require.False(t, IsWasm(gzipData))
t.Log("should return true for exact wasm")
require.True(t, IsWasm(wasmCode))
}

func TestIsGzip (t *testing.T) {
wasmCode, someRandomStr, gzipData, err := GetTestData()
require.NoError(t, err)

require.False(t, IsGzip(wasmCode))
require.False(t, IsGzip(someRandomStr))
require.True(t, IsGzip(gzipData))
}

func TestGzipIt (t *testing.T) {
wasmCode, someRandomStr, _, err := GetTestData()
originalGzipData := []byte{31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 202, 72, 205, 201, 201, 87, 40, 207, 47, 202, 73, 1,
4, 0, 0, 255, 255, 133, 17, 74, 13, 11, 0, 0, 0}

require.NoError(t, err)

t.Log("gzip wasm with no error")
_, err = GzipIt(wasmCode)
require.NoError(t, err)

t.Log("gzip of a string should return exact gzip data")
strToGzip, err := GzipIt(someRandomStr)

require.True(t, IsGzip(strToGzip))
require.NoError(t, err)
require.Equal(t, originalGzipData, strToGzip)
}

0 comments on commit d365da2

Please sign in to comment.