Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test : add additional crosschain operations [Do not merge] #3207

Draft
wants to merge 13 commits into
base: crosschain-simulation-params
Choose a base branch
from
5 changes: 5 additions & 0 deletions pkg/chains/chain_filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ func FilterByConsensus(cs Consensus) ChainFilter {
return func(chain Chain) bool { return chain.Consensus == cs }
}

// FilterByVM filters chains by VM type
func FilterByVM(vm Vm) ChainFilter {
return func(chain Chain) bool { return chain.Vm == vm }
}

// FilterChains applies a list of filters to a list of chains
func FilterChains(chainList []Chain, filters ...ChainFilter) []Chain {
// Apply each filter to the list of supported chains
Expand Down
68 changes: 63 additions & 5 deletions simulation/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import (
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/stretchr/testify/require"
evmtypes "github.com/zeta-chain/ethermint/x/evm/types"
zetachains "github.com/zeta-chain/node/pkg/chains"
"github.com/zeta-chain/node/pkg/coin"
crosschaintypes "github.com/zeta-chain/node/x/crosschain/types"

zetaapp "github.com/zeta-chain/node/app"
"github.com/zeta-chain/node/testutil/sample"
Expand Down Expand Up @@ -118,7 +121,7 @@ func updateObserverState(t *testing.T, rawState map[string]json.RawMessage, cdc
observers[i], observers[j] = observers[j], observers[i]
})

numObservers := r.Intn(11) + 5
numObservers := r.Intn(21) + 5
if numObservers > len(observers) {
numObservers = len(observers)
}
Expand All @@ -127,11 +130,31 @@ func updateObserverState(t *testing.T, rawState map[string]json.RawMessage, cdc
observerState.Observers.ObserverList = observers
observerState.CrosschainFlags.IsInboundEnabled = true
observerState.CrosschainFlags.IsOutboundEnabled = true

tss := sample.TSSRandom(t, r)
tss.OperatorAddressList = observers
observerState.Tss = &tss

chains := zetachains.DefaultChainsList()
chainsNonces := make([]observertypes.ChainNonces, 0)
pendingNonces := make([]observertypes.PendingNonces, 0)
for _, chain := range chains {
chainNonce := observertypes.ChainNonces{
ChainId: chain.ChainId,
Nonce: 0,
}
chainsNonces = append(chainsNonces, chainNonce)
pendingNonce := observertypes.PendingNonces{
NonceLow: 0,
NonceHigh: 0,
ChainId: chain.ChainId,
Tss: tss.TssPubkey,
}
pendingNonces = append(pendingNonces, pendingNonce)
}

observerState.ChainNonces = chainsNonces
observerState.PendingNonces = pendingNonces

return observerState
}

Expand Down Expand Up @@ -164,17 +187,51 @@ func updateAuthorityState(t *testing.T, rawState map[string]json.RawMessage, cdc
return authorityState
}

func updateCrossChainState(t *testing.T, rawState map[string]json.RawMessage, cdc codec.Codec, r *rand.Rand) *crosschaintypes.GenesisState {
crossChainStateBz, ok := rawState[crosschaintypes.ModuleName]
require.True(t, ok, "crosschain genesis state is missing")

crossChainState := new(crosschaintypes.GenesisState)
cdc.MustUnmarshalJSON(crossChainStateBz, crossChainState)

gasPriceList := []crosschaintypes.GasPrice{}

chains := zetachains.DefaultChainsList()
for _, chain := range chains {
gasPriceList = append(gasPriceList, sample.GasPriceFromRand(r, chain.ChainId))
}

return crossChainState
}

func updateFungibleState(t *testing.T, rawState map[string]json.RawMessage, cdc codec.Codec, r *rand.Rand) *fungibletypes.GenesisState {
fungibleStateBz, ok := rawState[fungibletypes.ModuleName]
require.True(t, ok, "fungible genesis state is missing")

fungibleState := new(fungibletypes.GenesisState)
cdc.MustUnmarshalJSON(fungibleStateBz, fungibleState)
fungibleState.SystemContract = &fungibletypes.SystemContract{
SystemContract: sample.EthAddressRandom(r).String(),
ConnectorZevm: sample.EthAddressRandom(r).String(),
Gateway: sample.EthAddressRandom(r).String(),
SystemContract: sample.EthAddressFromRand(r).String(),
ConnectorZevm: sample.EthAddressFromRand(r).String(),
Gateway: sample.EthAddressFromRand(r).String(),
}

foreignCoins := make([]fungibletypes.ForeignCoins, 0)
chains := zetachains.DefaultChainsList()

for _, chain := range chains {
foreignCoin := fungibletypes.ForeignCoins{
ForeignChainId: chain.ChainId,
Asset: sample.EthAddressFromRand(r).String(),
Zrc20ContractAddress: sample.EthAddressFromRand(r).String(),
Decimals: 18,
Paused: false,
CoinType: coin.CoinType_Gas,
LiquidityCap: math.ZeroUint(),
}
foreignCoins = append(foreignCoins, foreignCoin)
}
fungibleState.ForeignCoinsList = foreignCoins

return fungibleState
}
Expand All @@ -193,6 +250,7 @@ func updateRawState(t *testing.T, rawState map[string]json.RawMessage, cdc codec
rawState[observertypes.ModuleName] = cdc.MustMarshalJSON(observerState)
rawState[authoritytypes.ModuleName] = cdc.MustMarshalJSON(authorityState)
rawState[fungibletypes.ModuleName] = cdc.MustMarshalJSON(fungibleState)
rawState[crosschaintypes.ModuleName] = cdc.MustMarshalJSON(updateCrossChainState(t, rawState, cdc, r))
}

// AppStateFn returns the initial application state using a genesis or the simulation parameters.
Expand Down
32 changes: 31 additions & 1 deletion testutil/keeper/mocks/crosschain/authority.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

118 changes: 107 additions & 11 deletions testutil/sample/crosschain.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,20 @@ func GasPriceWithChainID(t *testing.T, chainID int64) types.GasPrice {
}
}

func GasPriceFromRand(r *rand.Rand, chainID int64) types.GasPrice {
price := r.Uint64()
priorityFee := r.Uint64() % price
return types.GasPrice{
Creator: "",
ChainId: chainID,
Signers: []string{AccAddressFromRand(r), AccAddressFromRand(r)},
BlockNums: []uint64{r.Uint64()},
Prices: []uint64{price},
MedianIndex: 0,
PriorityFees: []uint64{priorityFee},
}
}

func InboundParams(r *rand.Rand) *types.InboundParams {
return &types.InboundParams{
Sender: EthAddress().String(),
Expand Down Expand Up @@ -297,29 +311,111 @@ func InboundVote(coinType coin.CoinType, from, to int64) types.MsgVoteInbound {
}
}

func CoinTypeFromRand(r *rand.Rand) coin.CoinType {
coinTypes := []coin.CoinType{coin.CoinType_Gas, coin.CoinType_ERC20, coin.CoinType_Zeta}
coinType := coinTypes[r.Intn(len(coinTypes))]
return coinType
}

// InboundVoteSim creates a simulated inbound vote message. This function uses the provided source of randomness to generate
func InboundVoteSim(coinType coin.CoinType, from, to int64, r *rand.Rand) types.MsgVoteInbound {
EthAddress()
func InboundVoteSim(from, to int64, r *rand.Rand, asset string) types.MsgVoteInbound {
coinType := CoinTypeFromRand(r)
return types.MsgVoteInbound{
Creator: "",
Sender: EthAddressRandom(r).String(),
SenderChainId: from,
Receiver: EthAddressRandom(r).String(),
ReceiverChain: to,
Amount: math.NewUint(r.Uint64()),
Message: base64.StdEncoding.EncodeToString(RandomBytes(r)),
Creator: "",
Sender: EthAddressFromRand(r).String(),
SenderChainId: from,
Receiver: EthAddressFromRand(r).String(),
ReceiverChain: to,
Amount: math.NewUint(r.Uint64()),
Message: "95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5", // Refactor this
// to use ProtocolContractVersion_V2 format
InboundBlockHeight: r.Uint64(),
CallOptions: &types.CallOptions{
GasLimit: 1000000000,
},
InboundHash: ethcommon.BytesToHash(RandomBytes(r)).String(),
CoinType: coinType,
TxOrigin: EthAddressRandom(r).String(),
Asset: StringRandom(r, 32),
TxOrigin: EthAddressFromRand(r).String(),
Asset: asset,
EventIndex: r.Uint64(),
}
}

func CCTXfromRand(r *rand.Rand,
creator string,
index string,
to int64,
from int64,
tssPubkey string,
) types.CrossChainTx {
coinType := CoinTypeFromRand(r)

amount := math.NewUint(uint64(r.Int63()))
inbound := &types.InboundParams{
Sender: EthAddressFromRand(r).String(),
SenderChainId: from,
TxOrigin: EthAddressFromRand(r).String(),
CoinType: coinType,
Asset: StringRandom(r, 32),
Amount: amount,
ObservedHash: StringRandom(r, 32),
ObservedExternalHeight: r.Uint64(),
BallotIndex: StringRandom(r, 32),
FinalizedZetaHeight: r.Uint64(),
}

outbound := &types.OutboundParams{
Receiver: EthAddressFromRand(r).String(),
ReceiverChainId: to,
CoinType: coinType,
Amount: math.NewUint(uint64(r.Int63())),
TssNonce: 0,
TssPubkey: tssPubkey,
CallOptions: &types.CallOptions{
GasLimit: r.Uint64(),
},
GasPrice: math.NewUint(uint64(r.Int63())).String(),
Hash: StringRandom(r, 32),
BallotIndex: StringRandom(r, 32),
ObservedExternalHeight: r.Uint64(),
GasUsed: 100,
EffectiveGasPrice: math.NewInt(r.Int63()),
EffectiveGasLimit: 100,
}

cctx := types.CrossChainTx{
Creator: creator,
Index: index,
ZetaFees: sdk.NewUint(1),
RelayedMessage: base64.StdEncoding.EncodeToString(RandomBytes(r)),
CctxStatus: &types.Status{Status: types.CctxStatus_PendingOutbound},
InboundParams: inbound,
OutboundParams: []*types.OutboundParams{outbound},
}
return cctx
}

func OutboundVoteSim(r *rand.Rand,
cctx types.CrossChainTx,
) (types.CrossChainTx, types.MsgVoteOutbound) {

msg := types.MsgVoteOutbound{
CctxHash: cctx.Index,
OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce,
OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId,
Status: chains.ReceiveStatus_success,
Creator: cctx.Creator,
ObservedOutboundHash: ethcommon.BytesToHash(EthAddressFromRand(r).Bytes()).String(),
ValueReceived: cctx.GetCurrentOutboundParam().Amount,
ObservedOutboundBlockHeight: cctx.GetCurrentOutboundParam().ObservedExternalHeight,
ObservedOutboundEffectiveGasPrice: cctx.GetCurrentOutboundParam().EffectiveGasPrice,
ObservedOutboundGasUsed: cctx.GetCurrentOutboundParam().GasUsed,
CoinType: cctx.InboundParams.CoinType,
}

return cctx, msg
}

func ZRC20Withdrawal(to []byte, value *big.Int) *zrc20.ZRC20Withdrawal {
return &zrc20.ZRC20Withdrawal{
From: EthAddress(),
Expand Down
22 changes: 21 additions & 1 deletion testutil/sample/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func EthAddress() ethcommon.Address {
return ethcommon.BytesToAddress(sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()).Bytes())
}

func EthAddressRandom(r *rand.Rand) ethcommon.Address {
func EthAddressFromRand(r *rand.Rand) ethcommon.Address {
return ethcommon.BytesToAddress(sdk.AccAddress(PubKey(r).Address()).Bytes())
}

Expand Down Expand Up @@ -90,6 +90,14 @@ func SolanaAddress(t *testing.T) string {
return privKey.PublicKey().String()
}

func SolAddressFromRand(t *testing.T, r *rand.Rand) string {
privKey, err := solana.NewRandomPrivateKey()
if err != nil {
panic(err)
}
return privKey.PublicKey().String()
}

// SolanaSignature returns a sample solana signature
func SolanaSignature(t *testing.T) solana.Signature {
// Generate a random keypair
Expand All @@ -113,6 +121,11 @@ func Hash() ethcommon.Hash {
return ethcommon.BytesToHash(EthAddress().Bytes())
}

// Hash returns a sample hash
func HashFromRand(r *rand.Rand) ethcommon.Hash {
return ethcommon.BytesToHash(EthAddressFromRand(r).Bytes())
}

// BtcHash returns a sample btc hash
func BtcHash() chainhash.Hash {
return chainhash.Hash(Hash())
Expand All @@ -138,6 +151,13 @@ func AccAddress() string {
return sdk.AccAddress(addr).String()
}

// AccAddressFromRand returns a sample account address in string
func AccAddressFromRand(r *rand.Rand) string {
pk := PubKey(r)
addr := pk.Address()
return sdk.AccAddress(addr).String()
}

// ValAddress returns a sample validator operator address
func ValAddress(r *rand.Rand) sdk.ValAddress {
return sdk.ValAddress(PubKey(r).Address())
Expand Down
1 change: 0 additions & 1 deletion x/crosschain/keeper/cctx_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ func (k Keeper) SetObserverOutboundInfo(ctx sdk.Context, receiveChainID int64, c
"identifiers: %s (chain %q)", cctx.LogIdentifierForCCTX(), chain.Name,
)
}

// SET nonce
cctx.GetCurrentOutboundParam().TssNonce = nonce.Nonce
tss, found := k.GetObserverKeeper().GetTSS(ctx)
Expand Down
3 changes: 3 additions & 0 deletions x/crosschain/keeper/msg_server_abort_stuck_cctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper

import (
"context"
"fmt"

"cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -40,6 +41,8 @@ func (k msgServer) AbortStuckCCTX(
cctx.CctxStatus.Status == types.CctxStatus_PendingInbound ||
cctx.CctxStatus.Status == types.CctxStatus_PendingRevert
if !isPending {
fmt.Println("CCTX not in pending", cctx.Index, cctx.CctxStatus.Status)

return nil, types.ErrStatusNotPending
}

Expand Down
Loading
Loading