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: trackers #1320

Merged
merged 48 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
fdda86d
add msgs and query for inTxTracker
kingpinXD Sep 8, 2023
b989fe4
add unit tests
kingpinXD Sep 8, 2023
e3beb86
Generate specs
kingpinXD Sep 9, 2023
065bdc1
add intx tracker to genesis export
kingpinXD Sep 9, 2023
b764bf7
feat: zetaclient read logs functions (#1118)
kingpinXD Sep 27, 2023
ae379a6
add function to delete intx trackers
kingpinXD Sep 27, 2023
acfc130
change to remove tracker if exists
kingpinXD Sep 27, 2023
3d86a5e
add debug cli
kingpinXD Sep 28, 2023
83290a7
add debug cli
kingpinXD Sep 30, 2023
306f5ef
add btc inboud tracker
kingpinXD Oct 2, 2023
994ec15
add intx debugger for btc
kingpinXD Oct 3, 2023
f96feeb
rebase develop and fix smoketest
kingpinXD Oct 3, 2023
978c742
add optional block header verification on inbound tracker
kingpinXD Oct 4, 2023
5bbb371
fix lint
kingpinXD Oct 4, 2023
1bdd724
remove keeper prefix
kingpinXD Oct 4, 2023
eb9aef8
fix comments
kingpinXD Oct 4, 2023
33751fe
Merge branch 'develop' into inbound-tracker
kingpinXD Oct 4, 2023
28b5f1c
fix comments
kingpinXD Oct 4, 2023
1269476
modify cli commands
kingpinXD Oct 4, 2023
fc4198e
resolve comments 1
kingpinXD Oct 9, 2023
509b655
add check for cointype
kingpinXD Oct 9, 2023
e22b41b
Merge branch 'develop' into inbound-tracker
kingpinXD Oct 9, 2023
feaecc1
Merge branch 'develop' into inbound-tracker
kingpinXD Oct 10, 2023
14fe715
add flag to disable block header based verifications
kingpinXD Oct 10, 2023
5e50e89
Merge remote-tracking branch 'origin/inbound-tracker' into inbound-tr…
kingpinXD Oct 10, 2023
f957401
add upgrade script for legacy crosschain flags
kingpinXD Oct 10, 2023
1bc7e56
add test for upgrade script
kingpinXD Oct 10, 2023
8db3339
add issue to track intx tracker tests
kingpinXD Oct 11, 2023
fe4d213
removed redundant add to intx tracker list
kingpinXD Oct 11, 2023
30b8199
modify to iterating of receipt.logs
kingpinXD Oct 12, 2023
1ab1338
fix: merge develop into inbound-tracker and unified proof verificatio…
ws4charlie Oct 13, 2023
7ff5275
fixed typo in intx cli command
kingpinXD Oct 18, 2023
a09c006
add unit tests for in_tx_tracker
kingpinXD Oct 18, 2023
9e71b6a
refactor verify_proof.go
kingpinXD Oct 18, 2023
2df1e78
outtx tracker test
kingpinXD Oct 19, 2023
e31659d
add tests for out_tx_Tracker
kingpinXD Oct 19, 2023
8a53b8d
rebase develop
kingpinXD Oct 19, 2023
911943d
lint fix
kingpinXD Oct 19, 2023
d5dfdb9
lint fix 2
kingpinXD Oct 19, 2023
5b4bcde
set config when initializing test keeper
kingpinXD Oct 19, 2023
fd85152
use msgServer for in andout tx tracker handlers
kingpinXD Oct 19, 2023
b695c48
Update x/crosschain/keeper/msg_server_add_to_intx_tracker.go
kingpinXD Oct 20, 2023
fe9debe
add ErrorIs verfication to proofs
kingpinXD Oct 20, 2023
5d87fef
Merge remote-tracking branch 'origin/intx_tracker-tests' into intx_tr…
kingpinXD Oct 20, 2023
efea1f3
Merge branch 'develop' into intx_tracker-tests
kingpinXD Oct 23, 2023
c26bdfd
Merge branch 'develop' into intx_tracker-tests
kingpinXD Oct 23, 2023
58bdcaa
rebase develop
kingpinXD Oct 25, 2023
52e7bc7
rebase develop
kingpinXD Oct 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions testutil/keeper/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package keeper

import sdk "github.com/cosmos/cosmos-sdk/types"

const (
AccountAddressPrefix = "zeta"
)

var (
AccountPubKeyPrefix = AccountAddressPrefix + "pub"
ValidatorAddressPrefix = AccountAddressPrefix + "valoper"
ValidatorPubKeyPrefix = AccountAddressPrefix + "valoperpub"
ConsNodeAddressPrefix = AccountAddressPrefix + "valcons"
ConsNodePubKeyPrefix = AccountAddressPrefix + "valconspub"
)

func SetConfig(seal bool) {
config := sdk.GetConfig()
config.SetBech32PrefixForAccount(AccountAddressPrefix, AccountPubKeyPrefix)
config.SetBech32PrefixForValidator(ValidatorAddressPrefix, ValidatorPubKeyPrefix)
config.SetBech32PrefixForConsensusNode(ConsNodeAddressPrefix, ConsNodePubKeyPrefix)
if seal {
config.Seal()
}
}
1 change: 1 addition & 0 deletions testutil/keeper/crosschain.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func CrosschainKeeperWithMocks(
t testing.TB,
mockOptions CrosschainMockOptions,
) (*keeper.Keeper, sdk.Context, SDKKeepers, ZetaKeepers) {
SetConfig(false)
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved
storeKey := sdk.NewKVStoreKey(types.StoreKey)
memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey)

Expand Down
32 changes: 32 additions & 0 deletions testutil/sample/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
"math/big"

"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rlp"
"github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/zeta-chain/zetacore/common"
"github.com/zeta-chain/zetacore/common/ethereum"
)

func Chain(chainID int64) *common.Chain {
Expand Down Expand Up @@ -42,3 +44,33 @@ func EthHeader() (headerRLP []byte, err error) {
headerRLP, _ = rlp.EncodeToBytes(block.Header())
return
}

func Proof() (txIndex int64, block *ethtypes.Block, header ethtypes.Header, headerRLP []byte, proof *common.Proof, tx *ethtypes.Transaction, err error) {
txIndex = int64(9)
url := "https://rpc.ankr.com/eth_goerli"
client, err := ethclient.Dial(url)
if err != nil {
return
}
bn := int64(9889649)
block, err = client.BlockByNumber(context.Background(), big.NewInt(bn))
if err != nil {
return
}
headerRLP, _ = rlp.EncodeToBytes(block.Header())
err = rlp.DecodeBytes(headerRLP, &header)
if err != nil {
return
}
tr := ethereum.NewTrie(block.Transactions())
var b []byte
ib := rlp.AppendUint64(b, uint64(txIndex))
p := ethereum.NewProof()
err = tr.Prove(ib, 0, p)
if err != nil {
return
}
proof = common.NewEthereumProof(p)
tx = block.Transactions()[txIndex]
return
}
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg
}
commit()
cctx.CctxStatus.ChangeStatus(types.CctxStatus_PendingOutbound, "")
k.RemoveInTxTrackerIfExists(ctx, cctx.InboundTxParams.SenderChainId, cctx.InboundTxParams.InboundTxObservedHash)
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved
return &types.MsgVoteOnObservedInboundTxResponse{}, nil
}
}
70 changes: 10 additions & 60 deletions x/crosschain/keeper/msg_server_add_to_intx_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import (

errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
eth "github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/zeta-chain/zetacore/common"
"github.com/zeta-chain/zetacore/x/crosschain/types"
observertypes "github.com/zeta-chain/zetacore/x/observer/types"
Expand All @@ -29,11 +27,16 @@ func (k msgServer) AddToInTxTracker(goCtx context.Context, msg *types.MsgAddToIn
if !(isAdmin || isObserver) && msg.Proof != nil {
txBytes, err := k.VerifyProof(ctx, msg.Proof, msg.ChainId, msg.BlockHash, msg.TxIndex)
if err != nil {
return nil, types.ErrCannotVerifyProof.Wrapf(err.Error())
return nil, types.ErrProofVerificationFail.Wrapf(err.Error())
}
err = k.VerifyInTxBody(ctx, msg, txBytes)
if err != nil {
return nil, types.ErrCannotVerifyProof.Wrapf(err.Error())

if common.IsEVMChain(msg.ChainId) {
err = k.VerifyEVMInTxBody(ctx, msg, txBytes)
if err != nil {
return nil, types.ErrTxBodyVerificationFail.Wrapf(err.Error())
}
} else {
return nil, types.ErrTxBodyVerificationFail.Wrapf(fmt.Sprintf("cannot verify inTx body for chain %d", msg.ChainId))
}
isProven = true
}
Expand All @@ -43,63 +46,10 @@ func (k msgServer) AddToInTxTracker(goCtx context.Context, msg *types.MsgAddToIn
return nil, errorsmod.Wrap(observertypes.ErrNotAuthorized, fmt.Sprintf("Creator %s", msg.Creator))
}

k.Keeper.SetInTxTracker(ctx, types.InTxTracker{
k.SetInTxTracker(ctx, types.InTxTracker{
ChainId: msg.ChainId,
TxHash: msg.TxHash,
CoinType: msg.CoinType,
})
return &types.MsgAddToInTxTrackerResponse{}, nil
}

// https://github.com/zeta-chain/node/issues/1254
func (k Keeper) VerifyInTxBody(ctx sdk.Context, msg *types.MsgAddToInTxTracker, txBytes []byte) error {
// get core params and tss address
coreParams, found := k.zetaObserverKeeper.GetCoreParamsByChainID(ctx, msg.ChainId)
if !found {
return types.ErrUnsupportedChain.Wrapf("core params not found for chain %d", msg.ChainId)
}
tss, err := k.GetTssAddress(ctx, &types.QueryGetTssAddressRequest{})
if err != nil {
return err
}

// verify message against transaction body
if common.IsEVMChain(msg.ChainId) {
err = VerifyEVMInTxBody(coreParams, msg, txBytes, tss.Eth)
} else {
return fmt.Errorf("cannot verify inTx body for chain %d", msg.ChainId)
}
return err
}

func VerifyEVMInTxBody(coreParams *observertypes.CoreParams, msg *types.MsgAddToInTxTracker, txBytes []byte, tssEth string) error {
var txx ethtypes.Transaction
err := txx.UnmarshalBinary(txBytes)
if err != nil {
return err
}
tssAddr := eth.HexToAddress(tssEth)
if tssAddr == (eth.Address{}) {
return fmt.Errorf("tss address not found")
}

switch msg.CoinType {
case common.CoinType_Zeta:
if txx.To().Hex() != coreParams.ConnectorContractAddress {
return fmt.Errorf("receiver is not connector contract for coin type %s", msg.CoinType)
}
return nil
case common.CoinType_ERC20:
if txx.To().Hex() != coreParams.Erc20CustodyContractAddress {
return fmt.Errorf("receiver is not erc20Custory contract for coin type %s", msg.CoinType)
}
return nil
case common.CoinType_Gas:
if txx.To().Hex() != tssAddr.Hex() {
return fmt.Errorf("receiver is not tssAddress contract for coin type %s", msg.CoinType)
}
return nil
default:
return fmt.Errorf("coin type %s not supported", msg.CoinType)
}
}
176 changes: 176 additions & 0 deletions x/crosschain/keeper/msg_server_add_to_intx_tracker_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
//go:build TESTNET
// +build TESTNET
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved

package keeper_test

import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/require"
"github.com/zeta-chain/zetacore/common"
keepertest "github.com/zeta-chain/zetacore/testutil/keeper"
"github.com/zeta-chain/zetacore/testutil/sample"
"github.com/zeta-chain/zetacore/x/crosschain/keeper"
"github.com/zeta-chain/zetacore/x/crosschain/types"
observerTypes "github.com/zeta-chain/zetacore/x/observer/types"
)

func TestMsgServer_AddToInTxTracker(t *testing.T) {
t.Run("add proof based tracker with correct proof", func(t *testing.T) {
k, ctx, _, zk := keepertest.CrosschainKeeper(t)
chainID := int64(5)
txIndex, block, header, headerRLP, proof, tx, err := sample.Proof()
require.NoError(t, err)
setupVerificationParams(zk, ctx, txIndex, chainID, header, headerRLP, block)
msgServer := keeper.NewMsgServerImpl(*k)
_, err = msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{
Creator: sample.AccAddress(),
ChainId: chainID,
TxHash: tx.Hash().Hex(),
CoinType: common.CoinType_Zeta,
Proof: proof,
BlockHash: block.Hash().Hex(),
TxIndex: txIndex,
})
require.NoError(t, err)
_, found := k.GetInTxTracker(ctx, chainID, tx.Hash().Hex())
require.True(t, found)
})

t.Run("fail to add proof based tracker with wrong tx hash", func(t *testing.T) {
k, ctx, _, zk := keepertest.CrosschainKeeper(t)
chainID := int64(5)
txIndex, block, header, headerRLP, proof, tx, err := sample.Proof()
require.NoError(t, err)
setupVerificationParams(zk, ctx, txIndex, chainID, header, headerRLP, block)
msgServer := keeper.NewMsgServerImpl(*k)
_, err = msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{
Creator: sample.AccAddress(),
ChainId: chainID,
TxHash: "fake_hash",
CoinType: common.CoinType_Zeta,
Proof: proof,
BlockHash: block.Hash().Hex(),
TxIndex: txIndex,
})
require.ErrorIs(t, types.ErrTxBodyVerificationFail, err)
_, found := k.GetInTxTracker(ctx, chainID, tx.Hash().Hex())
require.False(t, found)
})

t.Run("fail to add proof based tracker with wrong chain id", func(t *testing.T) {
k, ctx, _, zk := keepertest.CrosschainKeeper(t)
chainID := int64(5)
txIndex, block, header, headerRLP, proof, tx, err := sample.Proof()
require.NoError(t, err)
setupVerificationParams(zk, ctx, txIndex, chainID, header, headerRLP, block)
msgServer := keeper.NewMsgServerImpl(*k)
_, err = msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{
Creator: sample.AccAddress(),
ChainId: 97,
TxHash: tx.Hash().Hex(),
CoinType: common.CoinType_Zeta,
Proof: proof,
BlockHash: block.Hash().Hex(),
TxIndex: txIndex,
})
require.ErrorIs(t, types.ErrTxBodyVerificationFail, err)
_, found := k.GetInTxTracker(ctx, chainID, tx.Hash().Hex())
require.False(t, found)
})
t.Run("fail normal user submit without proof", func(t *testing.T) {
k, ctx, _, _ := keepertest.CrosschainKeeper(t)
tx_hash := "string"
chainID := int64(5)
msgServer := keeper.NewMsgServerImpl(*k)
_, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{
Creator: sample.AccAddress(),
ChainId: chainID,
TxHash: tx_hash,
CoinType: common.CoinType_Zeta,
Proof: nil,
BlockHash: "",
TxIndex: 0,
})
require.ErrorIs(t, observerTypes.ErrNotAuthorized, err)
_, found := k.GetInTxTracker(ctx, chainID, tx_hash)
require.False(t, found)
})
t.Run("admin add tx tracker", func(t *testing.T) {
k, ctx, _, zk := keepertest.CrosschainKeeper(t)
admin := sample.AccAddress()
setAdminPolicies(ctx, zk, admin)
tx_hash := "string"
chainID := int64(5)
msgServer := keeper.NewMsgServerImpl(*k)
_, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{
Creator: admin,
ChainId: chainID,
TxHash: tx_hash,
CoinType: common.CoinType_Zeta,
Proof: nil,
BlockHash: "",
TxIndex: 0,
})
require.NoError(t, err)
_, found := k.GetInTxTracker(ctx, chainID, tx_hash)
require.True(t, found)
})
t.Run("admin submit fake tracker", func(t *testing.T) {
k, ctx, _, zk := keepertest.CrosschainKeeper(t)
admin := sample.AccAddress()
setAdminPolicies(ctx, zk, admin)
tx_hash := "string"
chainID := int64(5)
msgServer := keeper.NewMsgServerImpl(*k)
_, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{
Creator: admin,
ChainId: chainID,
TxHash: "Malicious TX HASH",
CoinType: common.CoinType_Zeta,
Proof: nil,
BlockHash: "",
TxIndex: 0,
})
require.NoError(t, err)
_, found := k.GetInTxTracker(ctx, chainID, "Malicious TX HASH")
require.True(t, found)
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved
_, found = k.GetInTxTracker(ctx, chainID, tx_hash)
require.False(t, found)
})
}

func setupVerificationParams(zk keepertest.ZetaKeepers, ctx sdk.Context, tx_index int64, chainID int64, header ethtypes.Header, headerRLP []byte, block *ethtypes.Block) {
params := zk.ObserverKeeper.GetParams(ctx)
params.ObserverParams = append(params.ObserverParams, &observerTypes.ObserverParams{
Chain: &common.Chain{
ChainId: chainID,
ChainName: common.ChainName_goerli_testnet,
},
BallotThreshold: sdk.OneDec(),
MinObserverDelegation: sdk.OneDec(),
IsSupported: true,
})
zk.ObserverKeeper.SetParams(ctx, params)
zk.ObserverKeeper.SetBlockHeader(ctx, common.BlockHeader{
Height: block.Number().Int64(),
Hash: block.Hash().Bytes(),
ParentHash: header.ParentHash.Bytes(),
ChainId: chainID,
Header: common.NewEthereumHeader(headerRLP),
})
zk.ObserverKeeper.SetCoreParams(ctx, observerTypes.CoreParamsList{CoreParams: []*observerTypes.CoreParams{
{
ChainId: chainID,
ConnectorContractAddress: block.Transactions()[tx_index].To().Hex(),
},
}})
zk.ObserverKeeper.SetCrosschainFlags(ctx, observerTypes.CrosschainFlags{
BlockHeaderVerificationFlags: &observerTypes.BlockHeaderVerificationFlags{
IsEthTypeChainEnabled: true,
IsBtcTypeChainEnabled: false,
},
})
}
Loading
Loading