Add contract history query handler

This commit is contained in:
Alex Peters 2020-07-20 14:30:31 +02:00
parent 72a1a45030
commit 00adcb4a58
No known key found for this signature in database
GPG Key ID: BD28388D49EE708D
6 changed files with 130 additions and 6 deletions

View File

@ -454,7 +454,7 @@ func TestImportContractWithCodeHistoryReset(t *testing.T) {
Updated: types.NewAbsoluteTxPosition(ctx),
},
}
assert.Equal(t, expHistory, keeper.getContractHistory(ctx, contractAddr))
assert.Equal(t, expHistory, keeper.GetContractHistory(ctx, contractAddr))
}
func setupKeeper(t *testing.T) (Keeper, sdk.Context, []sdk.StoreKey, func()) {

View File

@ -388,7 +388,7 @@ func (k Keeper) appendToContractHistory(ctx sdk.Context, contractAddr sdk.AccAdd
prefixStore.Set(contractAddr, k.cdc.MustMarshalBinaryBare(&entries))
}
func (k Keeper) getContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress) []types.ContractCodeHistoryEntry {
func (k Keeper) GetContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress) []types.ContractCodeHistoryEntry {
prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.ContractHistoryStorePrefix)
var entries []types.ContractCodeHistoryEntry
bz := prefixStore.Get(contractAddr)

View File

@ -321,7 +321,7 @@ func TestInstantiate(t *testing.T) {
Updated: types.NewAbsoluteTxPosition(ctx),
Msg: json.RawMessage(initMsgBz),
}}
assert.Equal(t, exp, keeper.getContractHistory(ctx, contractAddr))
assert.Equal(t, exp, keeper.GetContractHistory(ctx, contractAddr))
}
func TestInstantiateWithDeposit(t *testing.T) {
@ -896,7 +896,7 @@ func TestMigrate(t *testing.T) {
Updated: types.NewAbsoluteTxPosition(ctx),
Msg: spec.migrateMsg,
}}
assert.Equal(t, expHistory, keeper.getContractHistory(ctx, contractAddr))
assert.Equal(t, expHistory, keeper.GetContractHistory(ctx, contractAddr))
m := keeper.QueryRaw(ctx, contractAddr, []byte("config"))
require.Len(t, m, 1)

View File

@ -110,7 +110,7 @@ func TestInstantiateProposal(t *testing.T) {
Updated: types.NewAbsoluteTxPosition(ctx),
Msg: src.InitMsg,
}}
assert.Equal(t, expHistory, wasmKeeper.getContractHistory(ctx, contractAddr))
assert.Equal(t, expHistory, wasmKeeper.GetContractHistory(ctx, contractAddr))
}
func TestMigrateProposal(t *testing.T) {
@ -187,7 +187,7 @@ func TestMigrateProposal(t *testing.T) {
Updated: types.NewAbsoluteTxPosition(ctx),
Msg: src.MigrateMsg,
}}
assert.Equal(t, expHistory, wasmKeeper.getContractHistory(ctx, contractAddr))
assert.Equal(t, expHistory, wasmKeeper.GetContractHistory(ctx, contractAddr))
}

View File

@ -19,6 +19,7 @@ const (
QueryGetContractState = "contract-state"
QueryGetCode = "code"
QueryListCode = "list-code"
QueryContractHistory = "contract-history"
)
const (
@ -54,6 +55,8 @@ func NewQuerier(keeper Keeper) sdk.Querier {
return queryCode(ctx, path[1], req, keeper)
case QueryListCode:
return queryCodeList(ctx, req, keeper)
case QueryContractHistory:
return queryContractHistory(ctx, path[1], keeper)
default:
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown data query endpoint")
}
@ -226,3 +229,26 @@ func queryCodeList(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byt
}
return bz, nil
}
func queryContractHistory(ctx sdk.Context, bech string, keeper Keeper) ([]byte, error) {
contractAddr, err := sdk.AccAddressFromBech32(bech)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, err.Error())
}
entries := keeper.GetContractHistory(ctx, contractAddr)
if entries == nil {
// nil, nil leads to 404 in rest handler
return nil, nil
}
// redact response
for i := range entries {
entries[i].Updated = nil
entries[i].Msg = nil
}
bz, err := json.MarshalIndent(entries, "", " ")
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
}
return bz, nil
}

View File

@ -1,6 +1,7 @@
package keeper
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
@ -216,3 +217,100 @@ func TestListContractByCodeOrdering(t *testing.T) {
assert.Nil(t, contract.Created)
}
}
func TestQueryContractHistory(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, keepers := CreateTestInput(t, false, tempDir, SupportedFeatures, nil, nil)
keeper := keepers.WasmKeeper
var (
otherAddr sdk.AccAddress = bytes.Repeat([]byte{0x2}, sdk.AddrLen)
)
specs := map[string]struct {
srcQueryAddr sdk.AccAddress
srcHistory []types.ContractCodeHistoryEntry
expContent []types.ContractCodeHistoryEntry
}{
"response with internal fields cleared": {
srcHistory: []types.ContractCodeHistoryEntry{{
Operation: types.GenesisContractCodeHistoryType,
CodeID: 1,
Updated: types.NewAbsoluteTxPosition(ctx),
Msg: []byte(`"init message"`),
}},
expContent: []types.ContractCodeHistoryEntry{{
Operation: types.GenesisContractCodeHistoryType,
CodeID: 1,
}},
},
"response with multiple entries": {
srcHistory: []types.ContractCodeHistoryEntry{{
Operation: types.InitContractCodeHistoryType,
CodeID: 1,
Updated: types.NewAbsoluteTxPosition(ctx),
Msg: []byte(`"init message"`),
}, {
Operation: types.MigrateContractCodeHistoryType,
CodeID: 2,
Updated: types.NewAbsoluteTxPosition(ctx),
Msg: []byte(`"migrate message 1"`),
}, {
Operation: types.MigrateContractCodeHistoryType,
CodeID: 3,
Updated: types.NewAbsoluteTxPosition(ctx),
Msg: []byte(`"migrate message 2"`),
}},
expContent: []types.ContractCodeHistoryEntry{{
Operation: types.InitContractCodeHistoryType,
CodeID: 1,
}, {
Operation: types.MigrateContractCodeHistoryType,
CodeID: 2,
}, {
Operation: types.MigrateContractCodeHistoryType,
CodeID: 3,
}},
},
"unknown contract address": {
srcQueryAddr: otherAddr,
srcHistory: []types.ContractCodeHistoryEntry{{
Operation: types.GenesisContractCodeHistoryType,
CodeID: 1,
Updated: types.NewAbsoluteTxPosition(ctx),
Msg: []byte(`"init message"`),
}},
expContent: nil,
},
}
for msg, spec := range specs {
t.Run(msg, func(t *testing.T) {
_, _, myContractAddr := keyPubAddr()
keeper.appendToContractHistory(ctx, myContractAddr, spec.srcHistory...)
q := NewQuerier(keeper)
queryContractAddr := spec.srcQueryAddr
if queryContractAddr == nil {
queryContractAddr = myContractAddr
}
// when
query := []string{QueryContractHistory, queryContractAddr.String()}
data := abci.RequestQuery{}
resData, err := q(ctx, query, data)
// then
require.NoError(t, err)
if spec.expContent == nil {
require.Nil(t, resData)
return
}
var got []types.ContractCodeHistoryEntry
err = json.Unmarshal(resData, &got)
require.NoError(t, err)
assert.Equal(t, spec.expContent, got)
})
}
}