github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/wasm/keeper/legacy_querier.go (about) 1 package keeper 2 3 import ( 4 "encoding/json" 5 "reflect" 6 "strconv" 7 8 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 9 sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors" 10 abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 11 12 "github.com/fibonacci-chain/fbc/x/wasm/types" 13 ) 14 15 const ( 16 QueryListContractByCode = "list-contracts-by-code" 17 QueryGetContract = "contract-info" 18 QueryGetContractState = "contract-state" 19 QueryGetCode = "code" 20 QueryListCode = "list-code" 21 QueryContractHistory = "contract-history" 22 QueryListContractBlockedMethod = "list-contract-blocked-method" 23 QueryParams = "params" 24 ) 25 26 const ( 27 QueryMethodContractStateSmart = "smart" 28 QueryMethodContractStateAll = "all" 29 QueryMethodContractStateRaw = "raw" 30 ) 31 32 // NewLegacyQuerier creates a new querier 33 func NewLegacyQuerier(keeper types.ViewKeeper, gasLimit sdk.Gas) sdk.Querier { 34 return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { 35 var ( 36 rsp interface{} 37 err error 38 ) 39 switch path[0] { 40 case QueryGetContract: 41 addr, addrErr := sdk.AccAddressFromBech32(path[1]) 42 if addrErr != nil { 43 return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, addrErr.Error()) 44 } 45 rsp, err = queryContractInfo(ctx, addr, keeper) 46 case QueryListContractByCode: 47 codeID, parseErr := strconv.ParseUint(path[1], 10, 64) 48 if parseErr != nil { 49 return nil, sdkerrors.Wrapf(types.ErrInvalid, "code id: %s", parseErr.Error()) 50 } 51 rsp = queryContractListByCode(ctx, codeID, keeper) 52 case QueryGetContractState: 53 if len(path) < 3 { 54 return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown data query endpoint") 55 } 56 return queryContractState(ctx, path[1], path[2], req.Data, gasLimit, keeper) 57 case QueryGetCode: 58 codeID, parseErr := strconv.ParseUint(path[1], 10, 64) 59 if parseErr != nil { 60 return nil, sdkerrors.Wrapf(types.ErrInvalid, "code id: %s", parseErr.Error()) 61 } 62 rsp, err = queryCode(ctx, codeID, keeper) 63 case QueryListCode: 64 rsp, err = queryCodeList(ctx, keeper) 65 case QueryContractHistory: 66 contractAddr, addrErr := sdk.AccAddressFromBech32(path[1]) 67 if addrErr != nil { 68 return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, addrErr.Error()) 69 } 70 rsp, err = queryContractHistory(ctx, contractAddr, keeper) 71 case QueryListContractBlockedMethod: 72 contractAddr, addrErr := sdk.AccAddressFromBech32(path[1]) 73 if addrErr != nil { 74 return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, addrErr.Error()) 75 } 76 rsp = queryListContractBlockedMethod(ctx, contractAddr, keeper) 77 case QueryParams: 78 rsp = queryParams(ctx, keeper) 79 default: 80 return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown data query endpoint") 81 } 82 if err != nil { 83 return nil, err 84 } 85 if rsp == nil || reflect.ValueOf(rsp).IsNil() { 86 return nil, nil 87 } 88 bz, err := json.MarshalIndent(rsp, "", " ") 89 if err != nil { 90 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 91 } 92 return bz, nil 93 } 94 } 95 96 func queryContractState(ctx sdk.Context, bech, queryMethod string, data []byte, gasLimit sdk.Gas, keeper types.ViewKeeper) (json.RawMessage, error) { 97 contractAddr, err := sdk.AccAddressFromBech32(bech) 98 if err != nil { 99 return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, bech) 100 } 101 102 switch queryMethod { 103 case QueryMethodContractStateAll: 104 resultData := make([]types.Model, 0) 105 // this returns a serialized json object (which internally encoded binary fields properly) 106 keeper.IterateContractState(ctx, contractAddr, func(key, value []byte) bool { 107 resultData = append(resultData, types.Model{Key: key, Value: value}) 108 return false 109 }) 110 bz, err := json.Marshal(resultData) 111 if err != nil { 112 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 113 } 114 return bz, nil 115 case QueryMethodContractStateRaw: 116 // this returns the raw data from the state, base64-encoded 117 return keeper.QueryRaw(ctx, contractAddr, data), nil 118 case QueryMethodContractStateSmart: 119 // we enforce a subjective gas limit on all queries to avoid infinite loops 120 ctx.SetGasMeter(sdk.NewGasMeter(gasLimit)) 121 msg := types.RawContractMessage(data) 122 if err := msg.ValidateBasic(); err != nil { 123 return nil, sdkerrors.Wrap(err, "json msg") 124 } 125 // this returns raw bytes (must be base64-encoded) 126 bz, err := keeper.QuerySmart(ctx, contractAddr, msg) 127 return bz, err 128 default: 129 return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, queryMethod) 130 } 131 } 132 133 func queryCodeList(ctx sdk.Context, keeper types.ViewKeeper) ([]types.CodeInfoResponse, error) { 134 var info []types.CodeInfoResponse 135 keeper.IterateCodeInfos(ctx, func(i uint64, res types.CodeInfo) bool { 136 info = append(info, types.CodeInfoResponse{ 137 CodeID: i, 138 Creator: res.Creator, 139 DataHash: res.CodeHash, 140 InstantiatePermission: res.InstantiateConfig, 141 }) 142 return false 143 }) 144 return info, nil 145 } 146 147 func queryContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress, keeper types.ViewKeeper) ([]types.ContractCodeHistoryEntry, error) { 148 history := keeper.GetContractHistory(ctx, contractAddr) 149 // redact response 150 for i := range history { 151 history[i].Updated = nil 152 } 153 return history, nil 154 } 155 156 func queryContractListByCode(ctx sdk.Context, codeID uint64, keeper types.ViewKeeper) []string { 157 var contracts []string 158 keeper.IterateContractsByCode(ctx, codeID, func(addr sdk.AccAddress) bool { 159 contracts = append(contracts, addr.String()) 160 return false 161 }) 162 return contracts 163 } 164 165 func queryListContractBlockedMethod(ctx sdk.Context, contractAddr sdk.AccAddress, keeper types.ViewKeeper) *types.ContractMethods { 166 cmbl := keeper.GetContractMethodBlockedList(ctx, contractAddr.String()) 167 return cmbl 168 } 169 170 func queryParams(ctx sdk.Context, keeper types.ViewKeeper) *types.Params { 171 params := keeper.GetParams(ctx) 172 return ¶ms 173 }