Skip to content

Commit

Permalink
add migration test
Browse files Browse the repository at this point in the history
  • Loading branch information
kingpinXD committed Mar 9, 2024
1 parent be6dc4e commit 639f2a4
Show file tree
Hide file tree
Showing 13 changed files with 2,346 additions and 10 deletions.
2 changes: 1 addition & 1 deletion app/setup_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types"
)

const releaseVersion = "v14"
const releaseVersion = "v15"

func SetupHandlers(app *App) {
app.UpgradeKeeper.SetUpgradeHandler(releaseVersion, func(ctx sdk.Context, plan types.Plan, vm module.VersionMap) (module.VersionMap, error) {
Expand Down
8 changes: 6 additions & 2 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
# CHANGELOG

## Unreleased

### Refactor
* [1853](https://github.com/zeta-chain/node/pull/1853) - refactor vote inbound tx . Refactor CCTX struct to remove duplicate CoinType

## Version: v14

### Fixes
- [1817](https://github.com/zeta-chain/node/pull/1817) - Add migration script to fix pending and chain nonces on testnet

## Unreleased

### Breaking Changes

* Admin policies have been moved from `observer` to a new module `authority`.
Expand Down
4 changes: 1 addition & 3 deletions proto/crosschain/cross_chain_tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package zetachain.zetacore.crosschain;
import "common/common.proto";
import "gogoproto/gogo.proto";

//TODO : fix the descriptor numbers for the fields
option go_package = "github.com/zeta-chain/zetacore/x/crosschain/types";

enum CctxStatus {
Expand Down Expand Up @@ -93,6 +94,3 @@ message CrossChainTx {
uint64 event_index = 11;
common.CoinType coin_type = 12;
}



65 changes: 65 additions & 0 deletions proto/crosschain/cross_chain_tx_v14.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
syntax = "proto3";
package zetachain.zetacore.crosschain;

import "common/common.proto";
import "crosschain/cross_chain_tx.proto";
import "gogoproto/gogo.proto";

option go_package = "github.com/zeta-chain/zetacore/x/crosschain/types";

message InboundTxParamsV14 {
string sender = 1; // this address is the immediate contract/EOA that calls the Connector.send()
int64 sender_chain_id = 2;
string tx_origin = 3; // this address is the EOA that signs the inbound tx
common.CoinType coin_type = 4;
string asset = 5; // for ERC20 coin type, the asset is an address of the ERC20 contract
string amount = 6 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint",
(gogoproto.nullable) = false
];
string inbound_tx_observed_hash = 7;
uint64 inbound_tx_observed_external_height = 8;
string inbound_tx_ballot_index = 9;
uint64 inbound_tx_finalized_zeta_height = 10;
TxFinalizationStatus tx_finalization_status = 11;
}

message OutboundTxParamsV14 {
string receiver = 1;
int64 receiver_chainId = 2;
common.CoinType coin_type = 3;
string amount = 4 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint",
(gogoproto.nullable) = false
];
uint64 outbound_tx_tss_nonce = 5;
uint64 outbound_tx_gas_limit = 6;
string outbound_tx_gas_price = 7;
// the above are commands for zetaclients
// the following fields are used when the outbound tx is mined
string outbound_tx_hash = 8;
string outbound_tx_ballot_index = 9;
uint64 outbound_tx_observed_external_height = 10;
uint64 outbound_tx_gas_used = 20;
string outbound_tx_effective_gas_price = 21 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
uint64 outbound_tx_effective_gas_limit = 22;
string tss_pubkey = 11;
TxFinalizationStatus tx_finalization_status = 12;
}

message CrossChainTxV14 {
string creator = 1;
string index = 2;
string zeta_fees = 5 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"zeta_fees\""
];
string relayed_message = 6; // Not used by protocol , just relayed across
Status cctx_status = 8;
InboundTxParamsV14 inbound_tx_params = 9;
repeated OutboundTxParamsV14 outbound_tx_params = 10;
}
1 change: 1 addition & 0 deletions testutil/sample/crosschain.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ func CrossChainTx(t *testing.T, index string) *types.CrossChainTx {
CctxStatus: Status(t, index),
InboundTxParams: InboundTxParams(r),
OutboundTxParams: []*types.OutboundTxParams{OutboundTxParams(r), OutboundTxParams(r)},
EventIndex: r.Uint64(),
}
}

Expand Down
56 changes: 56 additions & 0 deletions testutil/sample/crosschain_legacy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package sample

import (
"math/rand"
"testing"

"cosmossdk.io/math"
"github.com/zeta-chain/zetacore/common"
"github.com/zeta-chain/zetacore/x/crosschain/types"
)

func CrossChainTxV14(t *testing.T, index string) *types.CrossChainTxV14 {
r := newRandFromStringSeed(t, index)
cointType := common.CoinType(r.Intn(100))
return &types.CrossChainTxV14{
Creator: AccAddress(),
Index: GetCctxIndexFromString(index),
ZetaFees: math.NewUint(uint64(r.Int63())),
RelayedMessage: StringRandom(r, 32),
CctxStatus: Status(t, index),
InboundTxParams: InboundTxParamsV14(r, cointType),
OutboundTxParams: []*types.OutboundTxParamsV14{OutboundTxParamsV14(r, cointType), OutboundTxParamsV14(r, cointType)},
}
}

func InboundTxParamsV14(r *rand.Rand, coinType common.CoinType) *types.InboundTxParamsV14 {
return &types.InboundTxParamsV14{
Sender: EthAddress().String(),
SenderChainId: r.Int63(),
TxOrigin: EthAddress().String(),
Asset: StringRandom(r, 32),
Amount: math.NewUint(uint64(r.Int63())),
InboundTxObservedHash: StringRandom(r, 32),
InboundTxObservedExternalHeight: r.Uint64(),
InboundTxBallotIndex: StringRandom(r, 32),
InboundTxFinalizedZetaHeight: r.Uint64(),
CoinType: coinType,
}
}

func OutboundTxParamsV14(r *rand.Rand, coinType common.CoinType) *types.OutboundTxParamsV14 {
return &types.OutboundTxParamsV14{
Receiver: EthAddress().String(),
ReceiverChainId: r.Int63(),
Amount: math.NewUint(uint64(r.Int63())),
OutboundTxTssNonce: r.Uint64(),
OutboundTxGasLimit: r.Uint64(),
OutboundTxGasPrice: math.NewUint(uint64(r.Int63())).String(),
OutboundTxHash: StringRandom(r, 32),
OutboundTxBallotIndex: StringRandom(r, 32),
OutboundTxObservedExternalHeight: r.Uint64(),
OutboundTxGasUsed: r.Uint64(),
OutboundTxEffectiveGasPrice: math.NewInt(r.Int63()),
CoinType: coinType,
}
}
5 changes: 5 additions & 0 deletions x/crosschain/keeper/migrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
v3 "github.com/zeta-chain/zetacore/x/crosschain/migrations/v3"
v4 "github.com/zeta-chain/zetacore/x/crosschain/migrations/v4"
v5 "github.com/zeta-chain/zetacore/x/crosschain/migrations/v5"
v6 "github.com/zeta-chain/zetacore/x/crosschain/migrations/v6"
)

// Migrator is a struct for handling in-place store migrations.
Expand Down Expand Up @@ -39,3 +40,7 @@ func (m Migrator) Migrate3to4(ctx sdk.Context) error {
func (m Migrator) Migrate4to5(ctx sdk.Context) error {
return v5.MigrateStore(ctx, m.crossChainKeeper, m.crossChainKeeper.zetaObserverKeeper)
}

func (m Migrator) Migrate5to6(ctx sdk.Context) error {
return v6.MigrateStore(ctx, m.crossChainKeeper)
}
66 changes: 65 additions & 1 deletion x/crosschain/migrations/v6/migrate.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package v6

import (
"fmt"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/zeta-chain/zetacore/x/crosschain/types"
Expand All @@ -21,7 +24,68 @@ type crosschainKeeper interface {

// MigrateStore migrates the x/crosschain module state from the consensus version 4 to 5
// It resets the aborted zeta amount to use the inbound tx amount instead in situations where the outbound cctx is never created.
func MigrateStore(ctx sdk.Context, crosschainKeeper crosschainKeeper, observerKeeper types.ObserverKeeper) error {
func MigrateStore(ctx sdk.Context, crosschainKeeper crosschainKeeper) error {
cctxListV14 := GetV14CCTX(ctx, crosschainKeeper)
for _, cctx := range cctxListV14 {
OutBoundParamsV15 := make([]*types.OutboundTxParams, len(cctx.OutboundTxParams))
for j, outBoundParams := range cctx.OutboundTxParams {
OutBoundParamsV15[j] = &types.OutboundTxParams{
Receiver: outBoundParams.Receiver,
ReceiverChainId: outBoundParams.ReceiverChainId,
Amount: outBoundParams.Amount,
OutboundTxTssNonce: outBoundParams.OutboundTxTssNonce,
OutboundTxGasLimit: outBoundParams.OutboundTxGasLimit,
OutboundTxGasPrice: outBoundParams.OutboundTxGasPrice,
OutboundTxHash: outBoundParams.OutboundTxHash,
OutboundTxBallotIndex: outBoundParams.OutboundTxBallotIndex,
OutboundTxObservedExternalHeight: outBoundParams.OutboundTxObservedExternalHeight,
OutboundTxGasUsed: outBoundParams.OutboundTxGasUsed,
OutboundTxEffectiveGasPrice: outBoundParams.OutboundTxEffectiveGasPrice,
OutboundTxEffectiveGasLimit: outBoundParams.OutboundTxEffectiveGasLimit,
TssPubkey: outBoundParams.TssPubkey,
TxFinalizationStatus: outBoundParams.TxFinalizationStatus,
}
}

cctxV15 := types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
Sender: cctx.InboundTxParams.Sender,
SenderChainId: cctx.InboundTxParams.SenderChainId,
TxOrigin: cctx.InboundTxParams.TxOrigin,
Asset: cctx.InboundTxParams.Asset,
Amount: cctx.InboundTxParams.Amount,
InboundTxObservedHash: cctx.InboundTxParams.InboundTxObservedHash,
InboundTxObservedExternalHeight: cctx.InboundTxParams.InboundTxObservedExternalHeight,
InboundTxBallotIndex: cctx.InboundTxParams.InboundTxBallotIndex,
InboundTxFinalizedZetaHeight: cctx.InboundTxParams.InboundTxFinalizedZetaHeight,
TxFinalizationStatus: cctx.InboundTxParams.TxFinalizationStatus,
},
Index: cctx.Index,
Creator: cctx.Creator,
OutboundTxParams: OutBoundParamsV15,
CctxStatus: cctx.CctxStatus,
CoinType: cctx.InboundTxParams.CoinType,
ZetaFees: cctx.ZetaFees,
RelayedMessage: cctx.RelayedMessage,
EventIndex: 1, // We don't have this information in the old version
}
crosschainKeeper.SetCrossChainTx(ctx, cctxV15)
}
return nil
}

func GetV14CCTX(ctx sdk.Context, crosschainKeeper crosschainKeeper) (list []types.CrossChainTxV14) {
p := types.KeyPrefix(fmt.Sprintf("%s", types.SendKey))
store := prefix.NewStore(ctx.KVStore(crosschainKeeper.GetStoreKey()), p)

iterator := sdk.KVStorePrefixIterator(store, []byte{})

defer iterator.Close()

for ; iterator.Valid(); iterator.Next() {
var val types.CrossChainTxV14
crosschainKeeper.GetCodec().MustUnmarshal(iterator.Value(), &val)
list = append(list, val)
}
return list
}
75 changes: 75 additions & 0 deletions x/crosschain/migrations/v6/migrate_test.go
Original file line number Diff line number Diff line change
@@ -1 +1,76 @@
package v6_test

import (
"fmt"
"sort"
"testing"

"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
keepertest "github.com/zeta-chain/zetacore/testutil/keeper"
"github.com/zeta-chain/zetacore/testutil/sample"
"github.com/zeta-chain/zetacore/x/crosschain/keeper"
v6 "github.com/zeta-chain/zetacore/x/crosschain/migrations/v6"
"github.com/zeta-chain/zetacore/x/crosschain/types"
)

func TestMigrateStore(t *testing.T) {
t.Run("sucessfull migrate cctx from v14 to v15", func(t *testing.T) {
k, ctx, _, _ := keepertest.CrosschainKeeper(t)
v14cctxList := make([]*types.CrossChainTxV14, 10)
for i := 0; i < 10; i++ {
v14cctxList[i] = sample.CrossChainTxV14(t, fmt.Sprintf("%d-%s", i, "v14"))
SetCrossChainTxV14(ctx, *v14cctxList[i], k)
}
err := v6.MigrateStore(ctx, k)
require.NoError(t, err)
cctxListv15 := k.GetAllCrossChainTx(ctx)
require.Len(t, cctxListv15, 10)
sort.Slice(cctxListv15, func(i, j int) bool {
return cctxListv15[i].Index < cctxListv15[j].Index
})
sort.Slice(v14cctxList, func(i, j int) bool {
return v14cctxList[i].Index < v14cctxList[j].Index
})
for i := 0; i < 10; i++ {
require.Equal(t, v14cctxList[i].Index, cctxListv15[i].Index)
require.Equal(t, v14cctxList[i].Creator, cctxListv15[i].Creator)
require.Equal(t, v14cctxList[i].ZetaFees, cctxListv15[i].ZetaFees)
require.Equal(t, v14cctxList[i].RelayedMessage, cctxListv15[i].RelayedMessage)
require.Equal(t, v14cctxList[i].CctxStatus, cctxListv15[i].CctxStatus)
require.Equal(t, v14cctxList[i].InboundTxParams.Sender, cctxListv15[i].InboundTxParams.Sender)
require.Equal(t, v14cctxList[i].InboundTxParams.SenderChainId, cctxListv15[i].InboundTxParams.SenderChainId)
require.Equal(t, v14cctxList[i].InboundTxParams.TxOrigin, cctxListv15[i].InboundTxParams.TxOrigin)
require.Equal(t, v14cctxList[i].InboundTxParams.Asset, cctxListv15[i].InboundTxParams.Asset)
require.Equal(t, v14cctxList[i].InboundTxParams.Amount, cctxListv15[i].InboundTxParams.Amount)
require.Equal(t, v14cctxList[i].InboundTxParams.InboundTxObservedHash, cctxListv15[i].InboundTxParams.InboundTxObservedHash)
require.Equal(t, v14cctxList[i].InboundTxParams.InboundTxObservedExternalHeight, cctxListv15[i].InboundTxParams.InboundTxObservedExternalHeight)
require.Equal(t, v14cctxList[i].InboundTxParams.InboundTxBallotIndex, cctxListv15[i].InboundTxParams.InboundTxBallotIndex)
require.Equal(t, v14cctxList[i].InboundTxParams.InboundTxFinalizedZetaHeight, cctxListv15[i].InboundTxParams.InboundTxFinalizedZetaHeight)
require.Equal(t, v14cctxList[i].InboundTxParams.CoinType, cctxListv15[i].CoinType)
require.Len(t, v14cctxList[i].OutboundTxParams, len(cctxListv15[i].OutboundTxParams))
for j := 0; j < len(cctxListv15[i].OutboundTxParams); j++ {
require.Equal(t, v14cctxList[i].OutboundTxParams[j].Receiver, cctxListv15[i].OutboundTxParams[j].Receiver)
require.Equal(t, v14cctxList[i].OutboundTxParams[j].ReceiverChainId, cctxListv15[i].OutboundTxParams[j].ReceiverChainId)
require.Equal(t, v14cctxList[i].OutboundTxParams[j].Amount, cctxListv15[i].OutboundTxParams[j].Amount)
require.Equal(t, v14cctxList[i].OutboundTxParams[j].OutboundTxTssNonce, cctxListv15[i].OutboundTxParams[j].OutboundTxTssNonce)
require.Equal(t, v14cctxList[i].OutboundTxParams[j].OutboundTxGasLimit, cctxListv15[i].OutboundTxParams[j].OutboundTxGasLimit)
require.Equal(t, v14cctxList[i].OutboundTxParams[j].OutboundTxGasPrice, cctxListv15[i].OutboundTxParams[j].OutboundTxGasPrice)
require.Equal(t, v14cctxList[i].OutboundTxParams[j].OutboundTxHash, cctxListv15[i].OutboundTxParams[j].OutboundTxHash)
require.Equal(t, v14cctxList[i].OutboundTxParams[j].OutboundTxBallotIndex, cctxListv15[i].OutboundTxParams[j].OutboundTxBallotIndex)
require.Equal(t, v14cctxList[i].OutboundTxParams[j].OutboundTxObservedExternalHeight, cctxListv15[i].OutboundTxParams[j].OutboundTxObservedExternalHeight)
require.Equal(t, v14cctxList[i].OutboundTxParams[j].OutboundTxGasUsed, cctxListv15[i].OutboundTxParams[j].OutboundTxGasUsed)
require.Equal(t, v14cctxList[i].OutboundTxParams[j].OutboundTxEffectiveGasPrice, cctxListv15[i].OutboundTxParams[j].OutboundTxEffectiveGasPrice)
require.Equal(t, v14cctxList[i].OutboundTxParams[j].CoinType, cctxListv15[i].CoinType)
}
}
})
}

func SetCrossChainTxV14(ctx sdk.Context, cctx types.CrossChainTxV14, k *keeper.Keeper) {
p := types.KeyPrefix(fmt.Sprintf("%s", types.SendKey))
store := prefix.NewStore(ctx.KVStore(k.GetStoreKey()), p)
b := k.GetCodec().MustMarshal(&cctx)
store.Set(types.KeyPrefix(cctx.Index), b)
}
6 changes: 5 additions & 1 deletion x/crosschain/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
if err := cfg.RegisterMigration(types.ModuleName, 4, m.Migrate4to5); err != nil {
panic(err)
}
if err := cfg.RegisterMigration(types.ModuleName, 4, m.Migrate5to6); err != nil {
panic(err)
}

}

// RegisterInvariants registers the crosschain module's invariants.
Expand Down Expand Up @@ -181,7 +185,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule) ConsensusVersion() uint64 { return 5 }
func (AppModule) ConsensusVersion() uint64 { return 6 }

// BeginBlock executes all ABCI BeginBlock logic respective to the crosschain module.
func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) {
Expand Down
Loading

0 comments on commit 639f2a4

Please sign in to comment.