Skip to content

Commit

Permalink
Store the Funding Trading Bridge smart contract as part of the umber …
Browse files Browse the repository at this point in the history
…upgrade. (#2102)

* Add the rc of the contract to load.

* Store the wasm code as part of the umber upgrade.

* Add changelog entry.

* Add some missing TODO comments and lower-case smart contract in the log messages.

* Get v1.0.3 of the smart contract, which should be the one to use.
  • Loading branch information
SpicyLemon authored Jul 19, 2024
1 parent eb052c3 commit 387ffe5
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

* Remove the warnings about some config settings [2095](https://github.com/provenance-io/provenance/pull/2095).
* Record several scope NAVs with the umber upgrade [#2085](https://github.com/provenance-io/provenance/pull/2085).
* Store the Figure Funding Trading Bridge Smart Contract as part of the umber upgrade [2102](https://github.com/provenance-io/provenance/pull/2102).

### Dependencies

Expand Down
Binary file not shown.
46 changes: 46 additions & 0 deletions app/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"time"

wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
"github.com/google/uuid"

sdkmath "cosmossdk.io/math"
Expand Down Expand Up @@ -154,6 +156,8 @@ var upgrades = map[string]appUpgrade{

removeInactiveValidatorDelegations(ctx, app)

storeWasmCode(ctx, app)

return vm, nil
},
},
Expand Down Expand Up @@ -623,3 +627,45 @@ func addScopeNAVsWithHeight(ctx sdk.Context, app *App, scopeNAVs []ScopeNAV) {

ctx.Logger().Info(fmt.Sprintf("Successfully added %d of %d scope net asset value entries.", totalAdded, count))
}

// storeWasmCode will store the provided wasm contract.
// TODO: Remove with the umber handlers.
func storeWasmCode(ctx sdk.Context, app *App) {
ctx.Logger().Info("Storing the Funding Trading Bridge smart contract.")
defer func() {
ctx.Logger().Info("Done storing the Funding Trading Bridge smart contract.")
}()

codeBz, err := UpgradeFiles.ReadFile("upgrade_files/umber/funding_trading_bridge_smart_contract.wasm")
if err != nil {
ctx.Logger().Error("Could not read smart contract.", "error", err)
return
}

msg := &wasmtypes.MsgStoreCode{
Sender: app.GovKeeper.GetAuthority(),
WASMByteCode: codeBz,
InstantiatePermission: &wasmtypes.AccessConfig{Permission: wasmtypes.AccessTypeEverybody},
}
executeStoreCodeMsg(ctx, wasmkeeper.NewMsgServerImpl(app.WasmKeeper), msg)
}

// wasmMsgSrvr has just the StoreCode endpoint needed for this upgrade.
// TODO: Remove with the umber handlers.
type wasmMsgSrvr interface {
StoreCode(context.Context, *wasmtypes.MsgStoreCode) (*wasmtypes.MsgStoreCodeResponse, error)
}

// executeStoreCodeMsg executes a MsgStoreCode.
// TODO: Remove with the umber handlers.
func executeStoreCodeMsg(ctx sdk.Context, wasmMsgServer wasmMsgSrvr, msg *wasmtypes.MsgStoreCode) {
cacheCtx, writeCache := ctx.CacheContext()
resp, err := wasmMsgServer.StoreCode(cacheCtx, msg)
if err != nil {
ctx.Logger().Error("Could not store smart contract.", "error", err)
return
}
writeCache()
ctx.Logger().Info(fmt.Sprintf("Smart contract stored with codeID: %d and checksum: %q.",
resp.CodeID, fmt.Sprintf("%x", resp.Checksum)))
}
113 changes: 113 additions & 0 deletions app/upgrades_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ package app

import (
"bytes"
"context"
"embed"
"errors"
"fmt"
"regexp"
"sort"
"strings"
"testing"
"time"

wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
"github.com/google/uuid"
"github.com/stretchr/testify/suite"

Expand Down Expand Up @@ -446,6 +451,8 @@ func (s *UpgradeTestSuite) TestUmber() {
"INF Removing inactive validator delegations.",
"INF Threshold: 21 days",
"INF A total of 0 inactive (unbonded) validators have had all their delegators removed.",
"INF Storing the Funding Trading Bridge smart contract.",
"INF Done storing the Funding Trading Bridge smart contract.",
}

s.AssertUpgradeHandlerLogs("umber", expInLog, nil)
Expand Down Expand Up @@ -909,3 +916,109 @@ func (s *UpgradeTestSuite) TestAddScopeNAVsWithHeight() {
})
}
}

// wrappedWasmMsgSrvr is a wasmtypes.MsgServer that lets us inject an error to return from StoreCode.
type wrappedWasmMsgSrvr struct {
wasmMsgServer wasmtypes.MsgServer
storeCodeErr string
}

func newWrappedWasmMsgSrvr(wasmKeeper *wasmkeeper.Keeper) *wrappedWasmMsgSrvr {
return &wrappedWasmMsgSrvr{wasmMsgServer: wasmkeeper.NewMsgServerImpl(wasmKeeper)}
}

func (w *wrappedWasmMsgSrvr) WithStoreCodeErr(str string) *wrappedWasmMsgSrvr {
w.storeCodeErr = str
return w
}

func (w *wrappedWasmMsgSrvr) StoreCode(ctx context.Context, msg *wasmtypes.MsgStoreCode) (*wasmtypes.MsgStoreCodeResponse, error) {
if len(w.storeCodeErr) > 0 {
return nil, errors.New(w.storeCodeErr)
}
return w.wasmMsgServer.StoreCode(ctx, msg)
}

func (s *UpgradeTestSuite) TestStoreWasmCode() {
origUpgradeFiles := UpgradeFiles
defer func() {
UpgradeFiles = origUpgradeFiles
}()

tests := []struct {
name string
upgradeFiles embed.FS
expLogs []string
}{
{
name: "success",
upgradeFiles: UpgradeFiles,
expLogs: []string{
"INF Storing the Funding Trading Bridge smart contract.",
"INF Smart contract stored with codeID: 1 and checksum: \"7e643e228169980aff5d75d576873d34b368d30a154dc617d2ed9b0093c97128\".",
"INF Done storing the Funding Trading Bridge smart contract.",
},
},
{
name: "failed to read file",
upgradeFiles: embed.FS{},
expLogs: []string{
"INF Storing the Funding Trading Bridge smart contract.",
"ERR Could not read smart contract. error=\"open upgrade_files/umber/funding_trading_bridge_smart_contract.wasm: file does not exist\"",
"INF Done storing the Funding Trading Bridge smart contract.",
},
},
}

for _, tc := range tests {
s.Run(tc.name, func() {
UpgradeFiles = tc.upgradeFiles
s.logBuffer.Reset()
testFunc := func() {
storeWasmCode(s.ctx, s.app)
}
s.Require().NotPanics(testFunc, "storeWasmCode")
actLogs := splitLogOutput(s.GetLogOutput("executeStoreCodeMsg"))
s.Assert().Equal(tc.expLogs, actLogs, "log messages during executeStoreCodeMsg")
})
}
}

func (s *UpgradeTestSuite) TestExecuteStoreCodeMsg() {
codeBz, err := UpgradeFiles.ReadFile("upgrade_files/umber/funding_trading_bridge_smart_contract.wasm")
s.Require().NoError(err, "reading wasm file")
msg := &wasmtypes.MsgStoreCode{
Sender: s.app.GovKeeper.GetAuthority(),
WASMByteCode: codeBz,
InstantiatePermission: &wasmtypes.AccessConfig{Permission: wasmtypes.AccessTypeEverybody},
}

tests := []struct {
name string
errMsg string
expLogs []string
}{
{
name: "storage fails",
errMsg: "dang no worky",
expLogs: []string{"ERR Could not store smart contract. error=\"dang no worky\""},
},
{
name: "storage succeeds",
expLogs: []string{"INF Smart contract stored with codeID: 1 and checksum: \"7e643e228169980aff5d75d576873d34b368d30a154dc617d2ed9b0093c97128\"."},
},
}

for _, tc := range tests {
s.Run(tc.name, func() {
msgServer := newWrappedWasmMsgSrvr(s.app.WasmKeeper).WithStoreCodeErr(tc.errMsg)
s.logBuffer.Reset()
testFunc := func() {
executeStoreCodeMsg(s.ctx, msgServer, msg)
}
s.Require().NotPanics(testFunc, "executeStoreCodeMsg")
actLogs := splitLogOutput(s.GetLogOutput("executeStoreCodeMsg"))
s.Assert().Equal(tc.expLogs, actLogs, "log messages during executeStoreCodeMsg")
})
}
}

0 comments on commit 387ffe5

Please sign in to comment.