diff --git a/custom/wasm/legacy_store.go b/custom/wasm/legacy_store.go index 21779038e..55fcc5610 100644 --- a/custom/wasm/legacy_store.go +++ b/custom/wasm/legacy_store.go @@ -4,6 +4,8 @@ import ( "bytes" "io" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + legacytypes "github.com/classic-terra/core/v4/custom/wasm/types/legacy" storetypes "cosmossdk.io/store/types" coretypes "github.com/classic-terra/core/v4/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -206,10 +208,60 @@ func stripLegacyLenPrefix(b []byte) []byte { return b } +func translateLegacyValueForKey(newKey, value []byte) []byte { + if len(newKey) == 0 || value == nil { + return value + } + + switch newKey[0] { + case 0x01: + return translateLegacyCodeInfoValue(value) + case 0x02: + return translateLegacyContractInfoValue(value) + default: + return value + } +} + +func translateLegacyCodeInfoValue(value []byte) []byte { + var legacyInfo legacytypes.LegacyCodeInfo + if err := legacyInfo.Unmarshal(value); err != nil { + return value + } + + translated := wasmtypes.CodeInfo{ + CodeHash: append([]byte(nil), legacyInfo.CodeHash...), + Creator: legacyInfo.Creator, + } + marshaled, err := translated.Marshal() + if err != nil { + return value + } + return marshaled +} + +func translateLegacyContractInfoValue(value []byte) []byte { + var legacyInfo legacytypes.LegacyContractInfo + if err := legacyInfo.Unmarshal(value); err != nil { + return value + } + + translated := wasmtypes.ContractInfo{ + CodeID: legacyInfo.CodeID, + Creator: legacyInfo.Creator, + Admin: legacyInfo.Admin, + } + marshaled, err := translated.Marshal() + if err != nil { + return value + } + return marshaled +} + func (s *legacyWasmStore) Get(key []byte) []byte { for _, cand := range translateNewToOld(key) { if bz := s.parent.Get(cand); bz != nil { - return bz + return translateLegacyValueForKey(key, bz) } } return nil @@ -351,7 +403,7 @@ func (it *legacyIterator) advance() { continue } it.key = newKey - it.val = it.under.Value() + it.val = translateLegacyValueForKey(newKey, it.under.Value()) it.valid = true it.under.Next() // Advance before returning, since post-statement won't run return diff --git a/custom/wasm/query_handler_test.go b/custom/wasm/query_handler_test.go index 525f9063b..8976c9cff 100644 --- a/custom/wasm/query_handler_test.go +++ b/custom/wasm/query_handler_test.go @@ -9,6 +9,9 @@ import ( storetypes "cosmossdk.io/store/types" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + legacytypes "github.com/classic-terra/core/v4/custom/wasm/types/legacy" + dbm "github.com/cometbft/cometbft-db" + "github.com/cometbft/cometbft/libs/log" wasmvmtypes "github.com/CosmWasm/wasmvm/v3/types" coretypes "github.com/classic-terra/core/v4/types" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" @@ -451,6 +454,91 @@ func (suite *LegacyQueryHandlerTestSuite) TestHandleQuery_LegacyStoreIntegration }) } +func (suite *LegacyQueryHandlerTestSuite) TestLegacyStore_TranslatesLegacyMetadataValues() { + ctx := suite.ctx.WithChainID(coretypes.ColumbusChainID).WithBlockHeight(25619229) + parent := ctx.KVStore(suite.storeKey) + legacyStore := &legacyWasmStore{parent: parent} + + contractAddr := make([]byte, 20) + for i := range contractAddr { + contractAddr[i] = byte(i + 1) + } + codeID := uint64(77) + + oldContractKey := append([]byte{0x04, 0x14}, contractAddr...) + oldContractValue, err := (&legacytypes.LegacyContractInfo{ + Address: "terra1legacycontract", + Creator: "terra1creator", + Admin: "terra1admin", + CodeID: codeID, + InitMsg: []byte(`{"count":1}`), + }).Marshal() + require.NoError(suite.T(), err) + parent.Set(oldContractKey, oldContractValue) + + oldCodeKey := append([]byte{0x03}, sdk.Uint64ToBigEndian(codeID)...) + oldCodeValue, err := (&legacytypes.LegacyCodeInfo{ + CodeID: codeID, + CodeHash: []byte("legacy-hash"), + Creator: "terra1creator", + }).Marshal() + require.NoError(suite.T(), err) + parent.Set(oldCodeKey, oldCodeValue) + + newContractKey := append([]byte{0x02}, contractAddr...) + contractBz := legacyStore.Get(newContractKey) + require.NotNil(suite.T(), contractBz) + + var contractInfo wasmtypes.ContractInfo + require.NoError(suite.T(), contractInfo.Unmarshal(contractBz)) + require.Equal(suite.T(), codeID, contractInfo.CodeID) + require.Equal(suite.T(), "terra1creator", contractInfo.Creator) + require.Equal(suite.T(), "terra1admin", contractInfo.Admin) + require.Empty(suite.T(), contractInfo.Label) + + newCodeKey := append([]byte{0x01}, sdk.Uint64ToBigEndian(codeID)...) + codeBz := legacyStore.Get(newCodeKey) + require.NotNil(suite.T(), codeBz) + + var codeInfo wasmtypes.CodeInfo + require.NoError(suite.T(), codeInfo.Unmarshal(codeBz)) + require.Equal(suite.T(), []byte("legacy-hash"), codeInfo.CodeHash) + require.Equal(suite.T(), "terra1creator", codeInfo.Creator) +} + +func (suite *LegacyQueryHandlerTestSuite) TestLegacyStore_IteratorTranslatesLegacyMetadataValues() { + ctx := suite.ctx.WithChainID(coretypes.ColumbusChainID).WithBlockHeight(25619229) + parent := ctx.KVStore(suite.storeKey) + legacyStore := &legacyWasmStore{parent: parent} + + contractAddr := make([]byte, 20) + for i := range contractAddr { + contractAddr[i] = byte(20 - i) + } + + oldContractKey := append([]byte{0x04, 0x14}, contractAddr...) + oldContractValue, err := (&legacytypes.LegacyContractInfo{ + Address: "terra1legacycontract", + Creator: "terra1creator", + CodeID: 9, + }).Marshal() + require.NoError(suite.T(), err) + parent.Set(oldContractKey, oldContractValue) + + iter := legacyStore.Iterator([]byte{0x02}, []byte{0x03}) + defer iter.Close() + + require.True(suite.T(), iter.Valid()) + require.Equal(suite.T(), append([]byte{0x02}, contractAddr...), iter.Key()) + + var contractInfo wasmtypes.ContractInfo + require.NoError(suite.T(), contractInfo.Unmarshal(iter.Value())) + require.Equal(suite.T(), uint64(9), contractInfo.CodeID) + require.Equal(suite.T(), "terra1creator", contractInfo.Creator) + iter.Next() + require.False(suite.T(), iter.Valid()) +} + // Test the isPreWasmKeyMigration function directly func (suite *LegacyQueryHandlerTestSuite) TestIsPreWasmKeyMigration() { testCases := []struct {