mirror of https://github.com/certusone/wasmd.git
Add source ref
This commit is contained in:
parent
09016ead0a
commit
62d0c308a8
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue