Add source ref

This commit is contained in:
anilCSE 2020-01-17 10:58:50 +05:30
parent 09016ead0a
commit 62d0c308a8
8 changed files with 56 additions and 13 deletions

View File

@ -4,6 +4,7 @@ import (
"bufio" "bufio"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/url"
"strconv" "strconv"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -21,13 +22,20 @@ import (
) )
const ( const (
flagTo = "to" flagTo = "to"
flagAmount = "amount" flagAmount = "amount"
flagSource = "source"
flagBuilder = "builder"
) )
// limit max bytes read to prevent gzip bombs // limit max bytes read to prevent gzip bombs
const maxSize = 400 * 1024 const maxSize = 400 * 1024
// whitelist
var validBuildTags = map[string]bool{
"cosmwasm-opt:0.6.0": true, "cosmwasm-opt:0.5.2": true,
}
// GetTxCmd returns the transaction commands for this module // GetTxCmd returns the transaction commands for this module
func GetTxCmd(cdc *codec.Codec) *cobra.Command { func GetTxCmd(cdc *codec.Codec) *cobra.Command {
txCmd := &cobra.Command{ txCmd := &cobra.Command{
@ -48,7 +56,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command {
// StoreCodeCmd will upload code to be reused. // StoreCodeCmd will upload code to be reused.
func StoreCodeCmd(cdc *codec.Codec) *cobra.Command { func StoreCodeCmd(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "store [from_key_or_address] [wasm file]", Use: "store [from_key_or_address] [wasm file] --source [source] --builder [builder]",
Short: "Upload a wasm binary", Short: "Upload a wasm binary",
Args: cobra.ExactArgs(2), Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
@ -62,6 +70,26 @@ func StoreCodeCmd(cdc *codec.Codec) *cobra.Command {
return err return err
} }
source := viper.GetString(flagSource)
// ensure source to be a valid uri
if source != "" {
_, err := url.Parse(source)
if err != nil {
return fmt.Errorf("invalid url supplied for source %s", source)
}
}
builder := viper.GetString(flagBuilder)
// ensure builder to be a valid build tag
if builder != "" {
if !validBuildTags[builder] {
return fmt.Errorf("invalid tag supplied for builder %s", source)
}
}
// limit the input size // limit the input size
if len(wasm) > maxSize { if len(wasm) > maxSize {
return fmt.Errorf("input size exceeds the max size allowed (allowed:%d, actual: %d)", return fmt.Errorf("input size exceeds the max size allowed (allowed:%d, actual: %d)",
@ -83,10 +111,16 @@ func StoreCodeCmd(cdc *codec.Codec) *cobra.Command {
msg := types.MsgStoreCode{ msg := types.MsgStoreCode{
Sender: cliCtx.GetFromAddress(), Sender: cliCtx.GetFromAddress(),
WASMByteCode: wasm, WASMByteCode: wasm,
Source: source,
Builder: builder,
} }
return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
}, },
} }
cmd.Flags().String(flagSource, "", "A valid URI reference to the contract's source code, optional")
cmd.Flags().String(flagBuilder, "", "A valid docker tag for the build system, optional")
return cmd return cmd
} }

View File

@ -40,7 +40,7 @@ func NewHandler(k Keeper) sdk.Handler {
} }
func handleStoreCode(ctx sdk.Context, k Keeper, msg *MsgStoreCode) sdk.Result { func handleStoreCode(ctx sdk.Context, k Keeper, msg *MsgStoreCode) sdk.Result {
codeID, err := k.Create(ctx, msg.Sender, msg.WASMByteCode) codeID, err := k.Create(ctx, msg.Sender, msg.WASMByteCode, msg.Source, msg.Builder)
if err != nil { if err != nil {
return err.Result() return err.Result()
} }

View File

@ -14,7 +14,7 @@ import (
// CONTRACT: all types of accounts must have been already initialized/created // CONTRACT: all types of accounts must have been already initialized/created
func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) { func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) {
for _, code := range data.Codes { for _, code := range data.Codes {
newId, err := keeper.Create(ctx, code.CodeInfo.Creator, code.CodesBytes) newId, err := keeper.Create(ctx, code.CodeInfo.Creator, code.CodesBytes, code.CodeInfo.Source, code.CodeInfo.Builder)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -62,7 +62,8 @@ func NewKeeper(cdc *codec.Codec, storeKey sdk.StoreKey, accountKeeper auth.Accou
} }
// Create uploads and compiles a WASM contract, returning a short identifier for the contract // Create uploads and compiles a WASM contract, returning a short identifier for the contract
func (k Keeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte) (codeID uint64, sdkErr sdk.Error) { func (k Keeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, source string,
builder string) (codeID uint64, sdkErr sdk.Error) {
wasmCode, err := uncompress(wasmCode) wasmCode, err := uncompress(wasmCode)
if err != nil { if err != nil {
return 0, types.ErrCreateFailed(err) return 0, types.ErrCreateFailed(err)
@ -74,7 +75,7 @@ func (k Keeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte)
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
codeID = k.autoIncrementID(ctx, types.KeyLastCodeID) codeID = k.autoIncrementID(ctx, types.KeyLastCodeID)
contractInfo := types.NewCodeInfo(codeHash, creator) contractInfo := types.NewCodeInfo(codeHash, creator, source, builder)
// 0x01 | codeID (uint64) -> ContractInfo // 0x01 | codeID (uint64) -> ContractInfo
store.Set(types.GetCodeKey(codeID), k.cdc.MustMarshalBinaryBare(contractInfo)) store.Set(types.GetCodeKey(codeID), k.cdc.MustMarshalBinaryBare(contractInfo))

View File

@ -37,7 +37,7 @@ func TestCreate(t *testing.T) {
wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm") wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
require.NoError(t, err) require.NoError(t, err)
contractID, err := keeper.Create(ctx, creator, wasmCode) contractID, err := keeper.Create(ctx, creator, wasmCode, "", "")
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, uint64(1), contractID) require.Equal(t, uint64(1), contractID)
// and verify content // and verify content
@ -58,7 +58,7 @@ func TestCreateWithGzippedPayload(t *testing.T) {
wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm.gzip") wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm.gzip")
require.NoError(t, err) require.NoError(t, err)
contractID, err := keeper.Create(ctx, creator, wasmCode) contractID, err := keeper.Create(ctx, creator, wasmCode, "", "")
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, uint64(1), contractID) require.Equal(t, uint64(1), contractID)
// and verify content // and verify content
@ -81,7 +81,7 @@ func TestInstantiate(t *testing.T) {
wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm") wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
require.NoError(t, err) require.NoError(t, err)
contractID, err := keeper.Create(ctx, creator, wasmCode) contractID, err := keeper.Create(ctx, creator, wasmCode, "", "")
require.NoError(t, err) require.NoError(t, err)
initMsg := InitMsg{ initMsg := InitMsg{
@ -138,7 +138,7 @@ func TestExecute(t *testing.T) {
wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm") wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
require.NoError(t, err) require.NoError(t, err)
contractID, err := keeper.Create(ctx, creator, wasmCode) contractID, err := keeper.Create(ctx, creator, wasmCode, "", "")
require.NoError(t, err) require.NoError(t, err)
_, _, bob := keyPubAddr() _, _, bob := keyPubAddr()

View File

@ -32,7 +32,7 @@ func TestQueryContractState(t *testing.T) {
wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm") wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
require.NoError(t, err) require.NoError(t, err)
contractID, err := keeper.Create(ctx, creator, wasmCode) contractID, err := keeper.Create(ctx, creator, wasmCode, "", "")
require.NoError(t, err) require.NoError(t, err)
_, _, bob := keyPubAddr() _, _, bob := keyPubAddr()

View File

@ -12,6 +12,10 @@ type MsgStoreCode struct {
Sender sdk.AccAddress `json:"sender" yaml:"sender"` Sender sdk.AccAddress `json:"sender" yaml:"sender"`
// WASMByteCode can be raw or gzip compressed // WASMByteCode can be raw or gzip compressed
WASMByteCode []byte `json:"wasm_byte_code" yaml:"wasm_byte_code"` WASMByteCode []byte `json:"wasm_byte_code" yaml:"wasm_byte_code"`
// Source is a valid URI reference to the contract's source code, optional
Source string `json:"source" yaml:"source"`
// Builder is a docker tag, optional
Builder string `json:"builder" yaml:"builder"`
} }
func (msg MsgStoreCode) Route() string { func (msg MsgStoreCode) Route() string {

View File

@ -16,13 +16,17 @@ type Model struct {
type CodeInfo struct { type CodeInfo struct {
CodeHash []byte `json:"code_hash"` CodeHash []byte `json:"code_hash"`
Creator sdk.AccAddress `json:"creator"` Creator sdk.AccAddress `json:"creator"`
Source string `json:"source"`
Builder string `json:"builder"`
} }
// NewCodeInfo fills a new Contract struct // NewCodeInfo fills a new Contract struct
func NewCodeInfo(codeHash []byte, creator sdk.AccAddress) CodeInfo { func NewCodeInfo(codeHash []byte, creator sdk.AccAddress, source string, builder string) CodeInfo {
return CodeInfo{ return CodeInfo{
CodeHash: codeHash, CodeHash: codeHash,
Creator: creator, Creator: creator,
Source: source,
Builder: builder,
} }
} }