Handle contract info query
This commit is contained in:
@@ -81,6 +81,7 @@ type wasmQueryKeeper interface {
|
||||
contractMetaDataSource
|
||||
QueryRaw(ctx sdk.Context, contractAddress sdk.AccAddress, key []byte) []byte
|
||||
QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []byte) ([]byte, error)
|
||||
IsPinnedCode(ctx sdk.Context, codeID uint64) bool
|
||||
}
|
||||
|
||||
func DefaultQueryPlugins(
|
||||
@@ -459,21 +460,39 @@ func getAccumulatedRewards(ctx sdk.Context, distKeeper types.DistributionKeeper,
|
||||
return rewards, nil
|
||||
}
|
||||
|
||||
func WasmQuerier(wasm wasmQueryKeeper) func(ctx sdk.Context, request *wasmvmtypes.WasmQuery) ([]byte, error) {
|
||||
func WasmQuerier(k wasmQueryKeeper) func(ctx sdk.Context, request *wasmvmtypes.WasmQuery) ([]byte, error) {
|
||||
return func(ctx sdk.Context, request *wasmvmtypes.WasmQuery) ([]byte, error) {
|
||||
if request.Smart != nil {
|
||||
switch {
|
||||
case request.Smart != nil:
|
||||
addr, err := sdk.AccAddressFromBech32(request.Smart.ContractAddr)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, request.Smart.ContractAddr)
|
||||
}
|
||||
return wasm.QuerySmart(ctx, addr, request.Smart.Msg)
|
||||
}
|
||||
if request.Raw != nil {
|
||||
return k.QuerySmart(ctx, addr, request.Smart.Msg)
|
||||
case request.Raw != nil:
|
||||
addr, err := sdk.AccAddressFromBech32(request.Raw.ContractAddr)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, request.Raw.ContractAddr)
|
||||
}
|
||||
return wasm.QueryRaw(ctx, addr, request.Raw.Key), nil
|
||||
return k.QueryRaw(ctx, addr, request.Raw.Key), nil
|
||||
case request.ContractInfo != nil:
|
||||
addr, err := sdk.AccAddressFromBech32(request.ContractInfo.ContractAddr)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, request.ContractInfo.ContractAddr)
|
||||
}
|
||||
info := k.GetContractInfo(ctx, addr)
|
||||
if info == nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownAddress, request.ContractInfo.ContractAddr)
|
||||
}
|
||||
|
||||
res := wasmvmtypes.ContractInfoResponse{
|
||||
CodeID: info.CodeID,
|
||||
Creator: info.Creator,
|
||||
Admin: info.Admin,
|
||||
Pinned: k.IsPinnedCode(ctx, info.CodeID),
|
||||
IBCPort: info.IBCPortID,
|
||||
}
|
||||
return json.Marshal(res)
|
||||
}
|
||||
return nil, wasmvmtypes.UnsupportedRequest{Kind: "unknown WasmQuery variant"}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ func TestIBCQuerier(t *testing.T) {
|
||||
}
|
||||
specs := map[string]struct {
|
||||
srcQuery *wasmvmtypes.IBCQuery
|
||||
wasmKeeper *wasmKeeperMock
|
||||
wasmKeeper *mockWasmQueryKeeper
|
||||
channelKeeper *wasmtesting.MockChannelKeeper
|
||||
expJsonResult string
|
||||
expErr *sdkerrors.Error
|
||||
@@ -78,11 +78,11 @@ func TestIBCQuerier(t *testing.T) {
|
||||
srcQuery: &wasmvmtypes.IBCQuery{
|
||||
PortID: &wasmvmtypes.PortIDQuery{},
|
||||
},
|
||||
wasmKeeper: newWasmKeeperMock(
|
||||
func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
||||
wasmKeeper: &mockWasmQueryKeeper{
|
||||
GetContractInfoFn: func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
||||
return &types.ContractInfo{IBCPortID: "myIBCPortID"}
|
||||
},
|
||||
),
|
||||
},
|
||||
channelKeeper: &wasmtesting.MockChannelKeeper{},
|
||||
expJsonResult: `{"port_id":"myIBCPortID"}`,
|
||||
},
|
||||
@@ -205,9 +205,11 @@ func TestIBCQuerier(t *testing.T) {
|
||||
ChannelID: "myQueryChannelID",
|
||||
},
|
||||
},
|
||||
wasmKeeper: newWasmKeeperMock(func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
||||
return &types.ContractInfo{IBCPortID: "myLoadedPortID"}
|
||||
}),
|
||||
wasmKeeper: &mockWasmQueryKeeper{
|
||||
GetContractInfoFn: func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
||||
return &types.ContractInfo{IBCPortID: "myLoadedPortID"}
|
||||
},
|
||||
},
|
||||
channelKeeper: &wasmtesting.MockChannelKeeper{
|
||||
GetChannelFn: func(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) {
|
||||
return channeltypes.Channel{
|
||||
@@ -337,21 +339,142 @@ func TestBankQuerierBalance(t *testing.T) {
|
||||
assert.Equal(t, exp, got)
|
||||
}
|
||||
|
||||
type wasmKeeperMock struct {
|
||||
func TestContractInfoWasmQuerier(t *testing.T) {
|
||||
var myValidContractAddr = RandomBech32AccountAddress(t)
|
||||
var myCreatorAddr = RandomBech32AccountAddress(t)
|
||||
var myAdminAddr = RandomBech32AccountAddress(t)
|
||||
var ctx sdk.Context
|
||||
|
||||
specs := map[string]struct {
|
||||
req *wasmvmtypes.WasmQuery
|
||||
mock mockWasmQueryKeeper
|
||||
expRes wasmvmtypes.ContractInfoResponse
|
||||
expErr bool
|
||||
}{
|
||||
"all good": {
|
||||
req: &wasmvmtypes.WasmQuery{
|
||||
ContractInfo: &wasmvmtypes.ContractInfoQuery{ContractAddr: myValidContractAddr},
|
||||
},
|
||||
mock: mockWasmQueryKeeper{GetContractInfoFn: func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
||||
val := types.ContractInfoFixture(func(i *types.ContractInfo) {
|
||||
i.Admin, i.Creator, i.IBCPortID = myAdminAddr, myCreatorAddr, "myIBCPort"
|
||||
})
|
||||
return &val
|
||||
},
|
||||
IsPinnedCodeFn: func(ctx sdk.Context, codeID uint64) bool { return true },
|
||||
},
|
||||
expRes: wasmvmtypes.ContractInfoResponse{
|
||||
CodeID: 1,
|
||||
Creator: myCreatorAddr,
|
||||
Admin: myAdminAddr,
|
||||
Pinned: true,
|
||||
IBCPort: "myIBCPort",
|
||||
},
|
||||
},
|
||||
"invalid addr": {
|
||||
req: &wasmvmtypes.WasmQuery{
|
||||
ContractInfo: &wasmvmtypes.ContractInfoQuery{ContractAddr: "not a valid addr"},
|
||||
},
|
||||
expErr: true,
|
||||
},
|
||||
"unknown addr": {
|
||||
req: &wasmvmtypes.WasmQuery{
|
||||
ContractInfo: &wasmvmtypes.ContractInfoQuery{ContractAddr: myValidContractAddr},
|
||||
},
|
||||
mock: mockWasmQueryKeeper{GetContractInfoFn: func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
||||
return nil
|
||||
}},
|
||||
expErr: true,
|
||||
},
|
||||
"not pinned": {
|
||||
req: &wasmvmtypes.WasmQuery{
|
||||
ContractInfo: &wasmvmtypes.ContractInfoQuery{ContractAddr: myValidContractAddr},
|
||||
},
|
||||
mock: mockWasmQueryKeeper{GetContractInfoFn: func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
||||
val := types.ContractInfoFixture(func(i *types.ContractInfo) {
|
||||
i.Admin, i.Creator = myAdminAddr, myCreatorAddr
|
||||
})
|
||||
return &val
|
||||
},
|
||||
IsPinnedCodeFn: func(ctx sdk.Context, codeID uint64) bool { return false },
|
||||
},
|
||||
expRes: wasmvmtypes.ContractInfoResponse{
|
||||
CodeID: 1,
|
||||
Creator: myCreatorAddr,
|
||||
Admin: myAdminAddr,
|
||||
Pinned: false,
|
||||
},
|
||||
},
|
||||
"without admin": {
|
||||
req: &wasmvmtypes.WasmQuery{
|
||||
ContractInfo: &wasmvmtypes.ContractInfoQuery{ContractAddr: myValidContractAddr},
|
||||
},
|
||||
mock: mockWasmQueryKeeper{GetContractInfoFn: func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
||||
val := types.ContractInfoFixture(func(i *types.ContractInfo) {
|
||||
i.Creator = myCreatorAddr
|
||||
})
|
||||
return &val
|
||||
},
|
||||
IsPinnedCodeFn: func(ctx sdk.Context, codeID uint64) bool { return true },
|
||||
},
|
||||
expRes: wasmvmtypes.ContractInfoResponse{
|
||||
CodeID: 1,
|
||||
Creator: myCreatorAddr,
|
||||
Pinned: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
q := WasmQuerier(spec.mock)
|
||||
gotBz, gotErr := q(ctx, spec.req)
|
||||
if spec.expErr {
|
||||
require.Error(t, gotErr)
|
||||
return
|
||||
}
|
||||
require.NoError(t, gotErr)
|
||||
var gotRes wasmvmtypes.ContractInfoResponse
|
||||
require.NoError(t, json.Unmarshal(gotBz, &gotRes))
|
||||
assert.Equal(t, spec.expRes, gotRes)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type mockWasmQueryKeeper struct {
|
||||
GetContractInfoFn func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo
|
||||
QueryRawFn func(ctx sdk.Context, contractAddress sdk.AccAddress, key []byte) []byte
|
||||
QuerySmartFn func(ctx sdk.Context, contractAddr sdk.AccAddress, req []byte) ([]byte, error)
|
||||
IsPinnedCodeFn func(ctx sdk.Context, codeID uint64) bool
|
||||
}
|
||||
|
||||
func newWasmKeeperMock(f func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo) *wasmKeeperMock {
|
||||
return &wasmKeeperMock{GetContractInfoFn: f}
|
||||
}
|
||||
|
||||
func (m wasmKeeperMock) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
||||
func (m mockWasmQueryKeeper) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
||||
if m.GetContractInfoFn == nil {
|
||||
panic("not expected to be called")
|
||||
}
|
||||
return m.GetContractInfoFn(ctx, contractAddress)
|
||||
}
|
||||
|
||||
func (m mockWasmQueryKeeper) QueryRaw(ctx sdk.Context, contractAddress sdk.AccAddress, key []byte) []byte {
|
||||
if m.QueryRawFn == nil {
|
||||
panic("not expected to be called")
|
||||
}
|
||||
return m.QueryRawFn(ctx, contractAddress, key)
|
||||
}
|
||||
|
||||
func (m mockWasmQueryKeeper) QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []byte) ([]byte, error) {
|
||||
if m.QuerySmartFn == nil {
|
||||
panic("not expected to be called")
|
||||
}
|
||||
return m.QuerySmartFn(ctx, contractAddr, req)
|
||||
}
|
||||
|
||||
func (m mockWasmQueryKeeper) IsPinnedCode(ctx sdk.Context, codeID uint64) bool {
|
||||
if m.IsPinnedCodeFn == nil {
|
||||
panic("not expected to be called")
|
||||
}
|
||||
return m.IsPinnedCodeFn(ctx, codeID)
|
||||
}
|
||||
|
||||
type bankKeeperMock struct {
|
||||
GetBalanceFn func(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin
|
||||
GetAllBalancesFn func(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
|
||||
|
||||
Reference in New Issue
Block a user