Handle contract info query
This commit is contained in:
@@ -81,6 +81,7 @@ type wasmQueryKeeper interface {
|
|||||||
contractMetaDataSource
|
contractMetaDataSource
|
||||||
QueryRaw(ctx sdk.Context, contractAddress sdk.AccAddress, key []byte) []byte
|
QueryRaw(ctx sdk.Context, contractAddress sdk.AccAddress, key []byte) []byte
|
||||||
QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []byte) ([]byte, error)
|
QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []byte) ([]byte, error)
|
||||||
|
IsPinnedCode(ctx sdk.Context, codeID uint64) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultQueryPlugins(
|
func DefaultQueryPlugins(
|
||||||
@@ -459,21 +460,39 @@ func getAccumulatedRewards(ctx sdk.Context, distKeeper types.DistributionKeeper,
|
|||||||
return rewards, nil
|
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) {
|
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)
|
addr, err := sdk.AccAddressFromBech32(request.Smart.ContractAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, request.Smart.ContractAddr)
|
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, request.Smart.ContractAddr)
|
||||||
}
|
}
|
||||||
return wasm.QuerySmart(ctx, addr, request.Smart.Msg)
|
return k.QuerySmart(ctx, addr, request.Smart.Msg)
|
||||||
}
|
case request.Raw != nil:
|
||||||
if request.Raw != nil {
|
|
||||||
addr, err := sdk.AccAddressFromBech32(request.Raw.ContractAddr)
|
addr, err := sdk.AccAddressFromBech32(request.Raw.ContractAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, request.Raw.ContractAddr)
|
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"}
|
return nil, wasmvmtypes.UnsupportedRequest{Kind: "unknown WasmQuery variant"}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ func TestIBCQuerier(t *testing.T) {
|
|||||||
}
|
}
|
||||||
specs := map[string]struct {
|
specs := map[string]struct {
|
||||||
srcQuery *wasmvmtypes.IBCQuery
|
srcQuery *wasmvmtypes.IBCQuery
|
||||||
wasmKeeper *wasmKeeperMock
|
wasmKeeper *mockWasmQueryKeeper
|
||||||
channelKeeper *wasmtesting.MockChannelKeeper
|
channelKeeper *wasmtesting.MockChannelKeeper
|
||||||
expJsonResult string
|
expJsonResult string
|
||||||
expErr *sdkerrors.Error
|
expErr *sdkerrors.Error
|
||||||
@@ -78,11 +78,11 @@ func TestIBCQuerier(t *testing.T) {
|
|||||||
srcQuery: &wasmvmtypes.IBCQuery{
|
srcQuery: &wasmvmtypes.IBCQuery{
|
||||||
PortID: &wasmvmtypes.PortIDQuery{},
|
PortID: &wasmvmtypes.PortIDQuery{},
|
||||||
},
|
},
|
||||||
wasmKeeper: newWasmKeeperMock(
|
wasmKeeper: &mockWasmQueryKeeper{
|
||||||
func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
GetContractInfoFn: func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
||||||
return &types.ContractInfo{IBCPortID: "myIBCPortID"}
|
return &types.ContractInfo{IBCPortID: "myIBCPortID"}
|
||||||
},
|
},
|
||||||
),
|
},
|
||||||
channelKeeper: &wasmtesting.MockChannelKeeper{},
|
channelKeeper: &wasmtesting.MockChannelKeeper{},
|
||||||
expJsonResult: `{"port_id":"myIBCPortID"}`,
|
expJsonResult: `{"port_id":"myIBCPortID"}`,
|
||||||
},
|
},
|
||||||
@@ -205,9 +205,11 @@ func TestIBCQuerier(t *testing.T) {
|
|||||||
ChannelID: "myQueryChannelID",
|
ChannelID: "myQueryChannelID",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wasmKeeper: newWasmKeeperMock(func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
wasmKeeper: &mockWasmQueryKeeper{
|
||||||
return &types.ContractInfo{IBCPortID: "myLoadedPortID"}
|
GetContractInfoFn: func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
||||||
}),
|
return &types.ContractInfo{IBCPortID: "myLoadedPortID"}
|
||||||
|
},
|
||||||
|
},
|
||||||
channelKeeper: &wasmtesting.MockChannelKeeper{
|
channelKeeper: &wasmtesting.MockChannelKeeper{
|
||||||
GetChannelFn: func(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) {
|
GetChannelFn: func(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) {
|
||||||
return channeltypes.Channel{
|
return channeltypes.Channel{
|
||||||
@@ -337,21 +339,142 @@ func TestBankQuerierBalance(t *testing.T) {
|
|||||||
assert.Equal(t, exp, got)
|
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
|
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 {
|
func (m mockWasmQueryKeeper) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
||||||
return &wasmKeeperMock{GetContractInfoFn: f}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m wasmKeeperMock) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
|
|
||||||
if m.GetContractInfoFn == nil {
|
if m.GetContractInfoFn == nil {
|
||||||
panic("not expected to be called")
|
panic("not expected to be called")
|
||||||
}
|
}
|
||||||
return m.GetContractInfoFn(ctx, contractAddress)
|
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 {
|
type bankKeeperMock struct {
|
||||||
GetBalanceFn func(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin
|
GetBalanceFn func(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin
|
||||||
GetAllBalancesFn func(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
|
GetAllBalancesFn func(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
|
||||||
|
|||||||
Reference in New Issue
Block a user