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

refactor(e2e): use strict event typing #3079

Merged
merged 2 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 4 additions & 6 deletions e2e/e2etests/test_migrate_chain_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,10 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) {
))
require.NoError(r, err)

// retrieve zrc20 and cctx from event
whitelistCCTXIndex, err := txserver.FetchAttributeFromTxResponse(res, "whitelist_cctx_index")
require.NoError(r, err)

erc20zrc20Addr, err := txserver.FetchAttributeFromTxResponse(res, "zrc20_address")
require.NoError(r, err)
event, ok := txserver.EventOfType[*crosschaintypes.EventERC20Whitelist](res.Events)
require.True(r, ok, "no EventERC20Whitelist in %s", res.TxHash)
erc20zrc20Addr := event.Zrc20Address
whitelistCCTXIndex := event.WhitelistCctxIndex

// wait for the whitelist cctx to be mined
newRunner.WaitForMinedCCTXFromIndex(whitelistCCTXIndex)
Expand Down
9 changes: 4 additions & 5 deletions e2e/e2etests/test_migrate_erc20_custody_funds.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,17 @@ func TestMigrateERC20CustodyFunds(r *runner.E2ERunner, _ []string) {
res, err := r.ZetaTxServer.BroadcastTx(utils.AdminPolicyName, msg)
require.NoError(r, err)

// fetch cctx index from tx response
cctxIndex, err := txserver.FetchAttributeFromTxResponse(res, "cctx_index")
require.NoError(r, err)
event, ok := txserver.EventOfType[*crosschaintypes.EventERC20CustodyFundsMigration](res.Events)
require.True(r, ok, "no EventERC20CustodyFundsMigration in %s", res.TxHash)

cctxRes, err := r.CctxClient.Cctx(r.Ctx, &crosschaintypes.QueryGetCctxRequest{Index: cctxIndex})
cctxRes, err := r.CctxClient.Cctx(r.Ctx, &crosschaintypes.QueryGetCctxRequest{Index: event.CctxIndex})
require.NoError(r, err)

cctx := cctxRes.CrossChainTx
r.Logger.CCTX(*cctx, "migration")

// wait for the cctx to be mined
r.WaitForMinedCCTXFromIndex(cctxIndex)
r.WaitForMinedCCTXFromIndex(event.CctxIndex)

// check ERC20 balance on new address
newAddrBalance, err := r.ERC20.BalanceOf(&bind.CallOpts{}, newAddr)
Expand Down
22 changes: 12 additions & 10 deletions e2e/e2etests/test_pause_erc20_custody.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,19 @@ func TestPauseERC20Custody(r *runner.E2ERunner, _ []string) {
res, err := r.ZetaTxServer.BroadcastTx(utils.AdminPolicyName, msg)
require.NoError(r, err)

// fetch cctx index from tx response
cctxIndex, err := txserver.FetchAttributeFromTxResponse(res, "cctx_index")
require.NoError(r, err)
event, ok := txserver.EventOfType[*crosschaintypes.EventERC20CustodyPausing](res.Events)
require.True(r, ok, "no EventERC20CustodyPausing in %s", res.TxHash)

require.True(r, event.Pause, "should be paused")

cctxRes, err := r.CctxClient.Cctx(r.Ctx, &crosschaintypes.QueryGetCctxRequest{Index: cctxIndex})
cctxRes, err := r.CctxClient.Cctx(r.Ctx, &crosschaintypes.QueryGetCctxRequest{Index: event.CctxIndex})
require.NoError(r, err)

cctx := cctxRes.CrossChainTx
r.Logger.CCTX(*cctx, "pausing")

// wait for the cctx to be mined
r.WaitForMinedCCTXFromIndex(cctxIndex)
r.WaitForMinedCCTXFromIndex(event.CctxIndex)

// check ERC20 custody contract is paused
paused, err = r.ERC20Custody.Paused(&bind.CallOpts{})
Expand All @@ -61,18 +62,19 @@ func TestPauseERC20Custody(r *runner.E2ERunner, _ []string) {
res, err = r.ZetaTxServer.BroadcastTx(utils.AdminPolicyName, msg)
require.NoError(r, err)

// fetch cctx index from tx response
cctxIndex, err = txserver.FetchAttributeFromTxResponse(res, "cctx_index")
require.NoError(r, err)
event, ok = txserver.EventOfType[*crosschaintypes.EventERC20CustodyPausing](res.Events)
require.True(r, ok, "no EventERC20CustodyPausing in %s", res.TxHash)

require.False(r, event.Pause, "should be unpaused")
gartnera marked this conversation as resolved.
Show resolved Hide resolved

cctxRes, err = r.CctxClient.Cctx(r.Ctx, &crosschaintypes.QueryGetCctxRequest{Index: cctxIndex})
cctxRes, err = r.CctxClient.Cctx(r.Ctx, &crosschaintypes.QueryGetCctxRequest{Index: event.CctxIndex})
require.NoError(r, err)

cctx = cctxRes.CrossChainTx
r.Logger.CCTX(*cctx, "unpausing")

// wait for the cctx to be mined
r.WaitForMinedCCTXFromIndex(cctxIndex)
r.WaitForMinedCCTXFromIndex(event.CctxIndex)
gartnera marked this conversation as resolved.
Show resolved Hide resolved

// check ERC20 custody contract is unpaused
paused, err = r.ERC20Custody.Paused(&bind.CallOpts{})
Expand Down
10 changes: 4 additions & 6 deletions e2e/e2etests/test_whitelist_erc20.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,10 @@ func TestWhitelistERC20(r *runner.E2ERunner, _ []string) {
))
require.NoError(r, err)

// retrieve zrc20 and cctx from event
whitelistCCTXIndex, err := txserver.FetchAttributeFromTxResponse(res, "whitelist_cctx_index")
require.NoError(r, err)

erc20zrc20Addr, err := txserver.FetchAttributeFromTxResponse(res, "zrc20_address")
require.NoError(r, err)
event, ok := txserver.EventOfType[*crosschaintypes.EventERC20Whitelist](res.Events)
require.True(r, ok, "no EventERC20Whitelist in %s", res.TxHash)
erc20zrc20Addr := event.Zrc20Address
whitelistCCTXIndex := event.WhitelistCctxIndex

err = r.ZetaTxServer.InitializeLiquidityCaps(erc20zrc20Addr)
require.NoError(r, err)
Expand Down
12 changes: 6 additions & 6 deletions e2e/runner/v2_migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ func (r *E2ERunner) migrateERC20CustodyFunds() {
res, err := r.ZetaTxServer.BroadcastTx(utils.AdminPolicyName, msgPausing)
require.NoError(r, err)

// fetch cctx index from tx response
cctxIndex, err := txserver.FetchAttributeFromTxResponse(res, "cctx_index")
require.NoError(r, err)
migrationEvent, ok := txserver.EventOfType[*crosschaintypes.EventERC20CustodyFundsMigration](res.Events)
require.True(r, ok, "no EventERC20CustodyFundsMigration in %s", res.TxHash)
cctxIndex := migrationEvent.CctxIndex

cctxRes, err := r.CctxClient.Cctx(r.Ctx, &crosschaintypes.QueryGetCctxRequest{Index: cctxIndex})
require.NoError(r, err)
Expand Down Expand Up @@ -188,9 +188,9 @@ func (r *E2ERunner) migrateERC20CustodyFunds() {
res, err = r.ZetaTxServer.BroadcastTx(utils.AdminPolicyName, msgMigration)
require.NoError(r, err)

// fetch cctx index from tx response
cctxIndex, err = txserver.FetchAttributeFromTxResponse(res, "cctx_index")
require.NoError(r, err)
migrationEvent, ok = txserver.EventOfType[*crosschaintypes.EventERC20CustodyFundsMigration](res.Events)
require.True(r, ok, "no EventERC20CustodyFundsMigration in %s", res.TxHash)
cctxIndex = migrationEvent.CctxIndex

cctxRes, err = r.CctxClient.Cctx(r.Ctx, &crosschaintypes.QueryGetCctxRequest{Index: cctxIndex})
require.NoError(r, err)
Expand Down
128 changes: 37 additions & 91 deletions e2e/txserver/zeta_tx_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package txserver
import (
"context"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"math/big"
Expand Down Expand Up @@ -33,6 +32,7 @@ import (
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/cosmos/gogoproto/proto"
"github.com/samber/lo"
"github.com/zeta-chain/ethermint/crypto/hd"
etherminttypes "github.com/zeta-chain/ethermint/types"
Expand Down Expand Up @@ -358,59 +358,25 @@ func (zts ZetaTxServer) DeploySystemContracts(
return SystemContractAddresses{}, fmt.Errorf("failed to deploy system contracts: %s", err.Error())
}

systemContractAddress, err := FetchAttributeFromTxResponse(res, "system_contract")
if err != nil {
return SystemContractAddresses{}, fmt.Errorf(
"failed to fetch system contract address: %s; rawlog %s",
err.Error(),
res.RawLog,
)
deployedEvent, ok := EventOfType[*fungibletypes.EventSystemContractsDeployed](res.Events)
if !ok {
return SystemContractAddresses{}, fmt.Errorf("no EventSystemContractsDeployed in %s", res.TxHash)
}

// get system contract
_, err = zts.BroadcastTx(
accountAdmin,
fungibletypes.NewMsgUpdateSystemContract(addrAdmin.String(), systemContractAddress),
fungibletypes.NewMsgUpdateSystemContract(addrAdmin.String(), deployedEvent.SystemContract),
)
if err != nil {
return SystemContractAddresses{}, fmt.Errorf("failed to set system contract: %s", err.Error())
}

// get uniswap contract addresses
uniswapV2FactoryAddr, err := FetchAttributeFromTxResponse(res, "uniswap_v2_factory")
if err != nil {
return SystemContractAddresses{}, fmt.Errorf("failed to fetch uniswap v2 factory address: %s", err.Error())
}
uniswapV2RouterAddr, err := FetchAttributeFromTxResponse(res, "uniswap_v2_router")
if err != nil {
return SystemContractAddresses{}, fmt.Errorf("failed to fetch uniswap v2 router address: %s", err.Error())
}

// get zevm connector address
zevmConnectorAddr, err := FetchAttributeFromTxResponse(res, "connector_zevm")
if err != nil {
return SystemContractAddresses{}, fmt.Errorf(
"failed to fetch zevm connector address: %s, txResponse: %s",
err.Error(),
res.String(),
)
}

// get wzeta address
wzetaAddr, err := FetchAttributeFromTxResponse(res, "wzeta")
if err != nil {
return SystemContractAddresses{}, fmt.Errorf(
"failed to fetch wzeta address: %s, txResponse: %s",
err.Error(),
res.String(),
)
}

return SystemContractAddresses{
UniswapV2FactoryAddr: uniswapV2FactoryAddr,
UniswapV2RouterAddr: uniswapV2RouterAddr,
ZEVMConnectorAddr: zevmConnectorAddr,
WZETAAddr: wzetaAddr,
UniswapV2FactoryAddr: deployedEvent.UniswapV2Factory,
UniswapV2RouterAddr: deployedEvent.UniswapV2Router,
ZEVMConnectorAddr: deployedEvent.ConnectorZevm,
WZETAAddr: deployedEvent.Wzeta,
}, nil
}

Expand Down Expand Up @@ -521,14 +487,10 @@ func (zts ZetaTxServer) DeployZRC20s(
return "", fmt.Errorf("deploy zrc20s: %w", err)
}

deployedEvents := lo.FilterMap(res.Events, func(ev abci.Event, _ int) (*fungibletypes.EventZRC20Deployed, bool) {
pEvent, err := sdktypes.ParseTypedEvent(ev)
if err != nil {
return nil, false
}
deployedEvent, ok := pEvent.(*fungibletypes.EventZRC20Deployed)
return deployedEvent, ok
})
deployedEvents, ok := EventsOfType[*fungibletypes.EventZRC20Deployed](res.Events)
if !ok {
return "", fmt.Errorf("no EventZRC20Deployed in %s", res.TxHash)
}

zrc20Addrs := lo.Map(deployedEvents, func(ev *fungibletypes.EventZRC20Deployed, _ int) string {
return ev.Contract
Expand Down Expand Up @@ -699,48 +661,32 @@ func newFactory(clientCtx client.Context) tx.Factory {
WithFees("100000000000000000azeta")
}

type messageLog struct {
Events []event `json:"events"`
}

type event struct {
Type string `json:"type"`
Attributes []attribute `json:"attributes"`
}

type attribute struct {
Key string `json:"key"`
Value string `json:"value"`
}

// FetchAttributeFromTxResponse fetches the attribute from the tx response
func FetchAttributeFromTxResponse(res *sdktypes.TxResponse, key string) (string, error) {
var logs []messageLog
err := json.Unmarshal([]byte(res.RawLog), &logs)
if err != nil {
return "", fmt.Errorf("failed to unmarshal logs: %s, logs content: %s", err.Error(), res.RawLog)
// EventsOfType gets events of a specified type
func EventsOfType[T proto.Message](events []abci.Event) ([]T, bool) {
var filteredEvents []T
for _, ev := range events {
pEvent, err := sdktypes.ParseTypedEvent(ev)
if err != nil {
continue
}
if typedEvent, ok := pEvent.(T); ok {
filteredEvents = append(filteredEvents, typedEvent)
}
}
return filteredEvents, len(filteredEvents) > 0
}

var attributes []string
for _, log := range logs {
for _, event := range log.Events {
for _, attr := range event.Attributes {
attributes = append(attributes, attr.Key)
if strings.EqualFold(attr.Key, key) {
address := attr.Value

if len(address) < 2 {
return "", fmt.Errorf("invalid address: %s", address)
}

// trim the quotes
address = address[1 : len(address)-1]

return address, nil
}
}
// EventOfType gets one event of a specific type
func EventOfType[T proto.Message](events []abci.Event) (T, bool) {
var event T
for _, ev := range events {
pEvent, err := sdktypes.ParseTypedEvent(ev)
if err != nil {
continue
}
if typedEvent, ok := pEvent.(T); ok {
return typedEvent, true
}
}

return "", fmt.Errorf("attribute %s not found, attributes: %+v", key, attributes)
return event, false
}
Loading