Skip to content

Commit

Permalink
Merge pull request #436 from CosmWasm/contract_pinning_401
Browse files Browse the repository at this point in the history
Start Pin/Unpin contract
  • Loading branch information
ethanfrey authored Mar 9, 2021
2 parents d51a1b8 + 6c3c197 commit 4072abf
Show file tree
Hide file tree
Showing 27 changed files with 1,543 additions and 153 deletions.
5 changes: 5 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,11 @@ func NewWasmApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b
// `loadLatest` is set to true.
ctx := app.BaseApp.NewUncachedContext(true, tmproto.Header{})
app.capabilityKeeper.InitializeAndSeal(ctx)

// Initialize pinned codes in wasmvm as they are not persisted there
if err := app.wasmKeeper.InitializePinnedCodes(ctx); err != nil {
panic(err)
}
}

app.scopedIBCKeeper = scopedIBCKeeper
Expand Down
39 changes: 38 additions & 1 deletion doc/proto.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
- [ClearAdminProposal](#cosmwasm.wasm.v1beta1.ClearAdminProposal)
- [InstantiateContractProposal](#cosmwasm.wasm.v1beta1.InstantiateContractProposal)
- [MigrateContractProposal](#cosmwasm.wasm.v1beta1.MigrateContractProposal)
- [PinCodesProposal](#cosmwasm.wasm.v1beta1.PinCodesProposal)
- [StoreCodeProposal](#cosmwasm.wasm.v1beta1.StoreCodeProposal)
- [UnpinCodesProposal](#cosmwasm.wasm.v1beta1.UnpinCodesProposal)
- [UpdateAdminProposal](#cosmwasm.wasm.v1beta1.UpdateAdminProposal)

- [x/wasm/internal/types/query.proto](#x/wasm/internal/types/query.proto)
Expand Down Expand Up @@ -94,6 +96,7 @@ Code struct encompasses CodeInfo and CodeBytes
| code_id | [uint64](#uint64) | | |
| code_info | [CodeInfo](#cosmwasm.wasm.v1beta1.CodeInfo) | | |
| code_bytes | [bytes](#bytes) | | |
| pinned | [bool](#bool) | | Pinned to wasmvm cache |



Expand Down Expand Up @@ -294,6 +297,23 @@ MigrateContractProposal gov proposal content type to migrate a contract.



<a name="cosmwasm.wasm.v1beta1.PinCodesProposal"></a>

### PinCodesProposal
PinCodesProposal gov proposal content type to pin a set of code ids in the wasmvm cache.


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| title | [string](#string) | | Title is a short summary |
| description | [string](#string) | | Description is a human readable text |
| code_ids | [uint64](#uint64) | repeated | CodeIDs references the new WASM codes |






<a name="cosmwasm.wasm.v1beta1.StoreCodeProposal"></a>

### StoreCodeProposal
Expand All @@ -315,6 +335,23 @@ StoreCodeProposal gov proposal content type to submit WASM code to the system



<a name="cosmwasm.wasm.v1beta1.UnpinCodesProposal"></a>

### UnpinCodesProposal
UnpinCodesProposal gov proposal content type to unpin a set of code ids in the wasmvm cache.


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| title | [string](#string) | | Title is a short summary |
| description | [string](#string) | | Description is a human readable text |
| code_ids | [uint64](#uint64) | repeated | CodeIDs references the WASM codes |






<a name="cosmwasm.wasm.v1beta1.UpdateAdminProposal"></a>

### UpdateAdminProposal
Expand Down Expand Up @@ -943,7 +980,7 @@ CodeInfo is data for the uploaded contract WASM code

| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| code_hash | [bytes](#bytes) | | CodeHash is the unique CodeID |
| code_hash | [bytes](#bytes) | | CodeHash is the unique identifier created by wasmvm |
| creator | [string](#string) | | Creator address who initially stored the code |
| source | [string](#string) | | Source is a valid absolute HTTPS URI to the contract&#39;s source code, optional |
| builder | [string](#string) | | Builder is a valid docker image name with tag, optional |
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ require (
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.7.1
github.com/stretchr/testify v1.7.0
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca
github.com/tendermint/tendermint v0.34.8
github.com/tendermint/tm-db v0.6.4
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11 // indirect
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4=
github.com/CosmWasm/wasmvm v0.13.1-0.20210125204657-16df1fdaf712 h1:8gMCeYi0In+3R+ox44SfXoY9a7KXngH8sDwsg+eLwB4=
github.com/CosmWasm/wasmvm v0.13.1-0.20210125204657-16df1fdaf712/go.mod h1:Id107qllDJyJjVQQsKMOy2YYF98sqPJ2t+jX1QES40A=
github.com/CosmWasm/wasmvm v0.14.0-alpha1 h1:n6cKrufXvaAzDaUfw1wEr39hNBLv3BY2usUnShmAFwQ=
github.com/CosmWasm/wasmvm v0.14.0-alpha1/go.mod h1:Id107qllDJyJjVQQsKMOy2YYF98sqPJ2t+jX1QES40A=
github.com/CosmWasm/wasmvm v0.14.0-alpha2 h1:IF+ZNYe6XxKmAZaAzX/Y2dXB1v3l+J0+Vyz69CtojOQ=
github.com/CosmWasm/wasmvm v0.14.0-alpha2/go.mod h1:Id107qllDJyJjVQQsKMOy2YYF98sqPJ2t+jX1QES40A=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
Expand Down
55 changes: 55 additions & 0 deletions x/wasm/internal/keeper/bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package keeper

import (
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
"github.com/stretchr/testify/require"
"github.com/syndtr/goleveldb/leveldb/opt"
dbm "github.com/tendermint/tm-db"
"testing"
)

func BenchmarkExecution(b *testing.B) {

specs := map[string]struct {
pinned bool
db func() dbm.DB
}{
"unpinned, memory db": {
db: func() dbm.DB { return dbm.NewMemDB() },
},
"pinned, memory db": {
db: func() dbm.DB { return dbm.NewMemDB() },
pinned: true,
},
"unpinned, level db": {
db: func() dbm.DB {
levelDB, err := dbm.NewGoLevelDBWithOpts("testing", b.TempDir(), &opt.Options{BlockCacher: opt.NoCacher})
require.NoError(b, err)
return levelDB
},
},
"pinned, level db": {
db: func() dbm.DB {
levelDB, err := dbm.NewGoLevelDBWithOpts("testing", b.TempDir(), &opt.Options{BlockCacher: opt.NoCacher})
require.NoError(b, err)
return levelDB
},
pinned: true,
},
}
for name, spec := range specs {
b.Run(name, func(b *testing.B) {
wasmConfig := types.WasmConfig{MemoryCacheSize: 0}
ctx, keepers := createTestInput(b, false, SupportedFeatures, nil, nil, wasmConfig, spec.db())
example := InstantiateHackatomExampleContract(b, ctx, keepers)
if spec.pinned {
require.NoError(b, keepers.WasmKeeper.PinCode(ctx, example.CodeID))
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := keepers.WasmKeeper.QuerySmart(ctx, example.Contract, []byte(`{"verifier":{}}`))
require.NoError(b, err)
}
})
}
}
7 changes: 6 additions & 1 deletion x/wasm/internal/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState, staki
if code.CodeID > maxCodeID {
maxCodeID = code.CodeID
}
if code.Pinned {
if err := keeper.PinCode(ctx, code.CodeID); err != nil {
return nil, sdkerrors.Wrapf(err, "contract number %d", i)
}
}
}

var maxContractID int
Expand Down Expand Up @@ -88,6 +93,7 @@ func ExportGenesis(ctx sdk.Context, keeper *Keeper) *types.GenesisState {
CodeID: codeID,
CodeInfo: info,
CodeBytes: bytecode,
Pinned: keeper.IsPinnedCode(ctx, codeID),
})
return false
})
Expand All @@ -104,7 +110,6 @@ func ExportGenesis(ctx sdk.Context, keeper *Keeper) *types.GenesisState {
}
// redact contract info
contract.Created = nil

genState.Contracts = append(genState.Contracts, types.Contract{
ContractAddress: addr.String(),
ContractInfo: contract,
Expand Down
27 changes: 27 additions & 0 deletions x/wasm/internal/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,21 @@ func TestGenesisExportImport(t *testing.T) {
contract types.ContractInfo
stateModels []types.Model
history []types.ContractCodeHistoryEntry
pinned bool
)
f.Fuzz(&codeInfo)
f.Fuzz(&contract)
f.Fuzz(&stateModels)
f.NilChance(0).Fuzz(&history)
f.Fuzz(&pinned)
creatorAddr, err := sdk.AccAddressFromBech32(codeInfo.Creator)
require.NoError(t, err)
codeID, err := srcKeeper.Create(srcCtx, creatorAddr, wasmCode, codeInfo.Source, codeInfo.Builder, &codeInfo.InstantiateConfig)
require.NoError(t, err)
if pinned {
srcKeeper.PinCode(srcCtx, codeID)
}

contract.CodeID = codeID
contractAddr := srcKeeper.generateContractAddress(srcCtx, codeID)
srcKeeper.storeContractInfo(srcCtx, contractAddr, &contract)
Expand Down Expand Up @@ -217,6 +223,24 @@ func TestGenesisInit(t *testing.T) {
},
Params: types.DefaultParams(),
}},
"codes with same checksum can be pinned": {
src: types.GenesisState{
Codes: []types.Code{
{
CodeID: firstCodeID,
CodeInfo: myCodeInfo,
CodeBytes: wasmCode,
Pinned: true,
},
{
CodeID: 2,
CodeInfo: myCodeInfo,
CodeBytes: wasmCode,
Pinned: true,
},
},
Params: types.DefaultParams(),
}},
"happy path: code id in info and contract do match": {
src: types.GenesisState{
Codes: []types.Code{{
Expand Down Expand Up @@ -405,6 +429,9 @@ func TestGenesisInit(t *testing.T) {
spec.msgHandlerMock.verifyCalls(t)
spec.stakingMock.verifyCalls(t)
assert.Equal(t, spec.stakingMock.validatorUpdate, gotValidatorSet)
for _, c := range spec.src.Codes {
assert.Equal(t, c.Pinned, keeper.IsPinnedCode(ctx, c.CodeID))
}
})
}
}
Expand Down
Loading

0 comments on commit 4072abf

Please sign in to comment.