From 0615bf6dfc9d5109c7a70d55dd57e79c2a69925f Mon Sep 17 00:00:00 2001 From: jeff <113397187+cyberhorsey@users.noreply.github.com> Date: Tue, 16 May 2023 00:31:47 -0700 Subject: [PATCH] feat(relayer): hardcode gas limit to determine if a message needs extra gas to deploy a contract (#13764) Co-authored-by: Roger <50648015+RogerLamTd@users.noreply.github.com> --- packages/relayer/.default.env | 8 ++- packages/relayer/.golangci.yml | 6 +- packages/relayer/cli/cli.go | 4 ++ packages/relayer/indexer/handle_event.go | 55 +----------------- packages/relayer/indexer/handle_event_test.go | 56 ------------------- packages/relayer/indexer/service.go | 16 ++++-- packages/relayer/indexer/service_test.go | 1 + packages/relayer/message/process_message.go | 47 ++++++++++++++-- packages/relayer/message/processor.go | 4 ++ packages/relayer/message/processor_test.go | 1 + packages/relayer/mock/token_vault.go | 20 +++++++ packages/relayer/token_vault.go | 16 ++++++ packages/relayer/types.go | 56 ++++++++++++++++++- packages/relayer/types_test.go | 56 +++++++++++++++++++ 14 files changed, 221 insertions(+), 125 deletions(-) create mode 100644 packages/relayer/mock/token_vault.go create mode 100644 packages/relayer/token_vault.go diff --git a/packages/relayer/.default.env b/packages/relayer/.default.env index 9b1e28b1e1a..3f0469cf009 100644 --- a/packages/relayer/.default.env +++ b/packages/relayer/.default.env @@ -9,11 +9,13 @@ MYSQL_MAX_OPEN_CONNS=3000 MYSQL_CONN_MAX_LIFETIME_IN_MS=100000 RELAYER_ECDSA_KEY= L1_BRIDGE_ADDRESS=0x3612E284D763f42f5E4CB72B1602b23DAEC3cA60 -L2_BRIDGE_ADDRESS=0x0000777700000000000000000000000000000004 +L2_BRIDGE_ADDRESS=0x1000777700000000000000000000000000000004 +L1_TOKEN_VAULT_ADDRESS=0x3612E284D763f42f5E4CB72B1602b23DAEC3cA60 +L2_TOKEN_VAULT_ADDRESS=0x1000777700000000000000000000000000000002 L1_TAIKO_ADDRESS=0x7B3AF414448ba906f02a1CA307C56c4ADFF27ce7 -L2_TAIKO_ADDRESS=0x0000777700000000000000000000000000000001 +L2_TAIKO_ADDRESS=0x1000777700000000000000000000000000000001 L1_SIGNAL_SERVICE_ADDRESS=0x403cc7802725928652a3d116Bb1781005e2e76d3 -L2_SIGNAL_SERVICE_ADDRESS=0x8BDa62dc6c0160Bce2C3a9360755dF030575985a +L2_SIGNAL_SERVICE_ADDRESS=0x1000777700000000000000000000000000000007 L1_RPC_URL=wss://l1ws.a1.taiko.xyz L2_RPC_URL=wss://l2ws.a1.taiko.xyz CONFIRMATIONS_BEFORE_PROCESSING=13 diff --git a/packages/relayer/.golangci.yml b/packages/relayer/.golangci.yml index d29ee22f926..cd7bacf64a3 100644 --- a/packages/relayer/.golangci.yml +++ b/packages/relayer/.golangci.yml @@ -28,10 +28,10 @@ linters: linters-settings: funlen: - lines: 137 - statements: 54 + lines: 145 + statements: 60 gocognit: - min-complexity: 43 + min-complexity: 50 issues: exclude-rules: diff --git a/packages/relayer/cli/cli.go b/packages/relayer/cli/cli.go index 27669b0fb2f..08a79a5b90c 100644 --- a/packages/relayer/cli/cli.go +++ b/packages/relayer/cli/cli.go @@ -32,6 +32,8 @@ var ( "L1_BRIDGE_ADDRESS", "L2_BRIDGE_ADDRESS", "L2_TAIKO_ADDRESS", + "L1_TOKEN_VAULT_ADDRESS", + "L2_TOKEN_VAULT_ADDRESS", "L1_RPC_URL", "L2_RPC_URL", "MYSQL_USER", @@ -220,6 +222,7 @@ func makeIndexers( DestTaikoAddress: common.HexToAddress(os.Getenv("L2_TAIKO_ADDRESS")), SrcTaikoAddress: common.HexToAddress(os.Getenv("L1_TAIKO_ADDRESS")), SrcSignalServiceAddress: common.HexToAddress(os.Getenv("L1_SIGNAL_SERVICE_ADDRESS")), + DestTokenVaultAddress: common.HexToAddress(os.Getenv("L2_TOKEN_VAULT_ADDRESS")), BlockBatchSize: uint64(blockBatchSize), NumGoroutines: numGoroutines, SubscriptionBackoff: subscriptionBackoff, @@ -249,6 +252,7 @@ func makeIndexers( DestBridgeAddress: common.HexToAddress(os.Getenv("L1_BRIDGE_ADDRESS")), DestTaikoAddress: common.HexToAddress(os.Getenv("L1_TAIKO_ADDRESS")), SrcSignalServiceAddress: common.HexToAddress(os.Getenv("L2_SIGNAL_SERVICE_ADDRESS")), + DestTokenVaultAddress: common.HexToAddress(os.Getenv("L1_TOKEN_VAULT_ADDRESS")), BlockBatchSize: uint64(blockBatchSize), NumGoroutines: numGoroutines, SubscriptionBackoff: subscriptionBackoff, diff --git a/packages/relayer/indexer/handle_event.go b/packages/relayer/indexer/handle_event.go index 8095d68f8e3..a0f447db988 100644 --- a/packages/relayer/indexer/handle_event.go +++ b/packages/relayer/indexer/handle_event.go @@ -5,13 +5,11 @@ import ( "encoding/json" "math/big" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" log "github.com/sirupsen/logrus" "github.com/taikoxyz/taiko-mono/packages/relayer" "github.com/taikoxyz/taiko-mono/packages/relayer/contracts/bridge" - "github.com/taikoxyz/taiko-mono/packages/relayer/contracts/tokenvault" ) // handleEvent handles an individual MessageSent event @@ -46,7 +44,7 @@ func (svc *Service) handleEvent( return errors.Wrap(err, "json.Marshal(event)") } - eventType, canonicalToken, amount, err := eventTypeAmountAndCanonicalTokenFromEvent(event) + eventType, canonicalToken, amount, err := relayer.DecodeMessageSentData(event) if err != nil { return errors.Wrap(err, "eventTypeAmountAndCanonicalTokenFromEvent(event)") } @@ -83,57 +81,6 @@ func (svc *Service) handleEvent( return nil } -func eventTypeAmountAndCanonicalTokenFromEvent( - event *bridge.BridgeMessageSent, -) (relayer.EventType, relayer.CanonicalToken, *big.Int, error) { - eventType := relayer.EventTypeSendETH - - var canonicalToken relayer.CanonicalToken - - var amount *big.Int - - if event.Message.Data != nil && common.BytesToHash(event.Message.Data) != relayer.ZeroHash { - tokenVaultMD := bind.MetaData{ - ABI: tokenvault.TokenVaultABI, - } - - tokenVaultABI, err := tokenVaultMD.GetAbi() - if err != nil { - return eventType, relayer.CanonicalToken{}, big.NewInt(0), errors.Wrap(err, "tokenVaultMD.GetAbi()") - } - - method, err := tokenVaultABI.MethodById(event.Message.Data[:4]) - if err != nil { - return eventType, relayer.CanonicalToken{}, big.NewInt(0), errors.Wrap(err, "tokenVaultABI.MethodById") - } - - inputsMap := make(map[string]interface{}) - - if err := method.Inputs.UnpackIntoMap(inputsMap, event.Message.Data[4:]); err != nil { - return eventType, relayer.CanonicalToken{}, big.NewInt(0), errors.Wrap(err, "method.Inputs.UnpackIntoMap") - } - - if method.Name == "receiveERC20" { - eventType = relayer.EventTypeSendERC20 - - canonicalToken = inputsMap["canonicalToken"].(struct { - // nolint - ChainId *big.Int `json:"chainId"` - Addr common.Address `json:"addr"` - Decimals uint8 `json:"decimals"` - Symbol string `json:"symbol"` - Name string `json:"name"` - }) - - amount = inputsMap["amount"].(*big.Int) - } - } else { - amount = event.Message.DepositValue - } - - return eventType, canonicalToken, amount, nil -} - func canProcessMessage( ctx context.Context, eventStatus relayer.EventStatus, diff --git a/packages/relayer/indexer/handle_event_test.go b/packages/relayer/indexer/handle_event_test.go index e098d564230..a09ff9db718 100644 --- a/packages/relayer/indexer/handle_event_test.go +++ b/packages/relayer/indexer/handle_event_test.go @@ -8,7 +8,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" "github.com/taikoxyz/taiko-mono/packages/relayer" - "github.com/taikoxyz/taiko-mono/packages/relayer/contracts/bridge" "github.com/taikoxyz/taiko-mono/packages/relayer/mock" ) @@ -148,58 +147,3 @@ func Test_eventStatusFromMsgHash(t *testing.T) { }) } } - -func Test_eventTypeAmountAndCanonicalTokenFromEvent(t *testing.T) { - tests := []struct { - name string - event *bridge.BridgeMessageSent - wantEventType relayer.EventType - wantCanonicalToken relayer.CanonicalToken - wantAmount *big.Int - wantError error - }{ - { - "receiveERC20", - &bridge.BridgeMessageSent{ - Message: bridge.IBridgeMessage{ - // nolint lll - Data: common.Hex2Bytes("0c6fab8200000000000000000000000000000000000000000000000000000000000000800000000000000000000000004ec242468812b6ffc8be8ff423af7bd23108d9910000000000000000000000004ec242468812b6ffc8be8ff423af7bd23108d99100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000007a68000000000000000000000000e4337137828c93d0046212ebda8a82a24356b67b000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000004544553540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000095465737445524332300000000000000000000000000000000000000000000000"), - }, - }, - relayer.EventTypeSendERC20, - relayer.CanonicalToken{ - ChainId: big.NewInt(31336), - Addr: common.HexToAddress("0xe4337137828c93D0046212ebDa8a82a24356b67B"), - Decimals: uint8(18), - Symbol: "TEST", - Name: "TestERC20", - }, - big.NewInt(1), - nil, - }, - { - "nilData", - &bridge.BridgeMessageSent{ - Message: bridge.IBridgeMessage{ - // nolint lll - DepositValue: big.NewInt(1), - Data: common.Hex2Bytes("00"), - }, - }, - relayer.EventTypeSendETH, - relayer.CanonicalToken{}, - big.NewInt(1), - nil, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - eventType, canonicalToken, amount, err := eventTypeAmountAndCanonicalTokenFromEvent(tt.event) - assert.Equal(t, tt.wantEventType, eventType) - assert.Equal(t, tt.wantCanonicalToken, canonicalToken) - assert.Equal(t, tt.wantAmount, amount) - assert.Equal(t, tt.wantError, err) - }) - } -} diff --git a/packages/relayer/indexer/service.go b/packages/relayer/indexer/service.go index c7206925278..5e1b15dd301 100644 --- a/packages/relayer/indexer/service.go +++ b/packages/relayer/indexer/service.go @@ -17,6 +17,7 @@ import ( "github.com/taikoxyz/taiko-mono/packages/relayer/contracts/bridge" "github.com/taikoxyz/taiko-mono/packages/relayer/contracts/icrosschainsync" "github.com/taikoxyz/taiko-mono/packages/relayer/contracts/taikol1" + "github.com/taikoxyz/taiko-mono/packages/relayer/contracts/tokenvault" "github.com/taikoxyz/taiko-mono/packages/relayer/message" "github.com/taikoxyz/taiko-mono/packages/relayer/proof" ) @@ -65,6 +66,7 @@ type NewServiceOpts struct { DestBridgeAddress common.Address SrcTaikoAddress common.Address DestTaikoAddress common.Address + DestTokenVaultAddress common.Address SrcSignalServiceAddress common.Address BlockBatchSize uint64 NumGoroutines int @@ -124,12 +126,12 @@ func NewService(opts NewServiceOpts) (*Service, error) { srcBridge, err := bridge.NewBridge(opts.BridgeAddress, opts.EthClient) if err != nil { - return nil, errors.Wrap(err, "contracts.NewBridge") + return nil, errors.Wrap(err, "bridge.NewBridge") } destBridge, err := bridge.NewBridge(opts.DestBridgeAddress, opts.DestEthClient) if err != nil { - return nil, errors.Wrap(err, "contracts.NewBridge") + return nil, errors.Wrap(err, "bridge.NewBridge") } prover, err := proof.New(opts.EthClient) @@ -139,17 +141,22 @@ func NewService(opts NewServiceOpts) (*Service, error) { destHeaderSyncer, err := icrosschainsync.NewICrossChainSync(opts.DestTaikoAddress, opts.DestEthClient) if err != nil { - return nil, errors.Wrap(err, "contracts.NewTaikoL2") + return nil, errors.Wrap(err, "icrosschainsync.NewTaikoL2") } var taikoL1 *taikol1.TaikoL1 if opts.SrcTaikoAddress != ZeroAddress { taikoL1, err = taikol1.NewTaikoL1(opts.SrcTaikoAddress, opts.EthClient) if err != nil { - return nil, errors.Wrap(err, "contracts.NewTaikoL1") + return nil, errors.Wrap(err, "taikol1.NewTaikoL1") } } + destTokenVault, err := tokenvault.NewTokenVault(opts.DestTokenVaultAddress, opts.DestEthClient) + if err != nil { + return nil, errors.Wrap(err, "tokenvault.NewTokenVault") + } + processor, err := message.NewProcessor(message.NewProcessorOpts{ Prover: prover, ECDSAKey: privateKey, @@ -165,6 +172,7 @@ func NewService(opts NewServiceOpts) (*Service, error) { HeaderSyncIntervalSeconds: opts.HeaderSyncIntervalInSeconds, SrcSignalServiceAddress: opts.SrcSignalServiceAddress, ConfirmationsTimeoutInSeconds: opts.ConfirmationsTimeoutInSeconds, + DestTokenVault: destTokenVault, }) if err != nil { return nil, errors.Wrap(err, "message.NewProcessor") diff --git a/packages/relayer/indexer/service_test.go b/packages/relayer/indexer/service_test.go index a3eb14b7ffa..1e230a7668b 100644 --- a/packages/relayer/indexer/service_test.go +++ b/packages/relayer/indexer/service_test.go @@ -33,6 +33,7 @@ func newTestService() (*Service, relayer.Bridge) { DestBridge: &mock.Bridge{}, SrcETHClient: &mock.EthClient{}, DestETHClient: &mock.EthClient{}, + DestTokenVault: &mock.TokenVault{}, ECDSAKey: privateKey, DestHeaderSyncer: &mock.HeaderSyncer{}, Prover: prover, diff --git a/packages/relayer/message/process_message.go b/packages/relayer/message/process_message.go index 7a389732528..0bc6b74d360 100644 --- a/packages/relayer/message/process_message.go +++ b/packages/relayer/message/process_message.go @@ -158,10 +158,9 @@ func (p *Processor) sendProcessMessageCall( gas, cost, err := p.estimateGas(ctx, event.Message, proof) if err != nil || gas == 0 { - // we can get unable to estimet gas for contract deployments within the contract code. - // if we get an error or the gas is 0, lets manual set high gas limit and ignore error, - // and try to actually send. - auth.GasLimit = 1500000 + if err := p.hardcodeGasLimit(ctx, auth, event); err != nil { + return nil, errors.Wrap(err, "p.hardcodeGasLimit") + } } if bool(p.profitableOnly) { @@ -189,6 +188,46 @@ func (p *Processor) sendProcessMessageCall( return tx, nil } +// hardcodeGasLimit determines a viable gas limit when we can get +// unable to estimate gas for contract deployments within the contract code. +// if we get an error or the gas is 0, lets manual set high gas limit and ignore error, +// and try to actually send. +// if contract has not been deployed, we need much higher gas limit, otherwise, we can +// send lower. +func (p *Processor) hardcodeGasLimit( + ctx context.Context, + auth *bind.TransactOpts, + event *bridge.BridgeMessageSent, +) error { + eventType, canonicalToken, _, err := relayer.DecodeMessageSentData(event) + if err != nil { + return errors.Wrap(err, "relayer.DecodeMessageSentData") + } + + if eventType == relayer.EventTypeSendETH { + // eth bridges take much less gas, from 250k to 450k. + auth.GasLimit = 500000 + } else { + // determine whether the canonical token is bridged or not on this chain + bridgedAddress, err := p.destTokenVault.CanonicalToBridged(nil, canonicalToken.ChainId, canonicalToken.Addr) + if err != nil { + return errors.Wrap(err, "p.destTokenVault.IsBridgedToken") + } + + if bridgedAddress == relayer.ZeroAddress { + // needs large gas limit because it has to deploy an ERC20 contract on destination + // chain. deploying ERC20 can be 2 mil by itself. + auth.GasLimit = 3000000 + } else { + // needs larger than ETH gas limit but not as much as deploying ERC20. + // takes 450-550k gas after signalRoot refactors. + auth.GasLimit = 600000 + } + } + + return nil +} + func (p *Processor) setLatestNonce(nonce uint64) { p.destNonce = nonce } diff --git a/packages/relayer/message/processor.go b/packages/relayer/message/processor.go index e17e050a1f0..11a918bb06d 100644 --- a/packages/relayer/message/processor.go +++ b/packages/relayer/message/processor.go @@ -20,6 +20,7 @@ type ethClient interface { HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) SuggestGasPrice(ctx context.Context) (*big.Int, error) } + type Processor struct { eventRepo relayer.EventRepository srcEthClient ethClient @@ -29,6 +30,7 @@ type Processor struct { destBridge relayer.Bridge destHeaderSyncer relayer.HeaderSyncer + destTokenVault relayer.TokenVault prover *proof.Prover @@ -54,6 +56,7 @@ type NewProcessorOpts struct { DestBridge relayer.Bridge EventRepo relayer.EventRepository DestHeaderSyncer relayer.HeaderSyncer + DestTokenVault relayer.TokenVault RelayerAddress common.Address SrcSignalServiceAddress common.Address Confirmations uint64 @@ -114,6 +117,7 @@ func NewProcessor(opts NewProcessorOpts) (*Processor, error) { destEthClient: opts.DestETHClient, destBridge: opts.DestBridge, destHeaderSyncer: opts.DestHeaderSyncer, + destTokenVault: opts.DestTokenVault, mu: &sync.Mutex{}, diff --git a/packages/relayer/message/processor_test.go b/packages/relayer/message/processor_test.go index d8becaa1b5f..4c326e00a00 100644 --- a/packages/relayer/message/processor_test.go +++ b/packages/relayer/message/processor_test.go @@ -31,6 +31,7 @@ func newTestProcessor(profitableOnly relayer.ProfitableOnly) *Processor { destBridge: &mock.Bridge{}, srcEthClient: &mock.EthClient{}, destEthClient: &mock.EthClient{}, + destTokenVault: &mock.TokenVault{}, mu: &sync.Mutex{}, ecdsaKey: privateKey, destHeaderSyncer: &mock.HeaderSyncer{}, diff --git a/packages/relayer/mock/token_vault.go b/packages/relayer/mock/token_vault.go new file mode 100644 index 00000000000..5384e1830fa --- /dev/null +++ b/packages/relayer/mock/token_vault.go @@ -0,0 +1,20 @@ +package mock + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/taikoxyz/taiko-mono/packages/relayer" +) + +type TokenVault struct { +} + +func (t *TokenVault) CanonicalToBridged( + opts *bind.CallOpts, + chainID *big.Int, + canonicalAddress common.Address, +) (common.Address, error) { + return relayer.ZeroAddress, nil +} diff --git a/packages/relayer/token_vault.go b/packages/relayer/token_vault.go new file mode 100644 index 00000000000..e351e199400 --- /dev/null +++ b/packages/relayer/token_vault.go @@ -0,0 +1,16 @@ +package relayer + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" +) + +type TokenVault interface { + CanonicalToBridged( + opts *bind.CallOpts, + chainID *big.Int, + canonicalAddress common.Address, + ) (common.Address, error) +} diff --git a/packages/relayer/types.go b/packages/relayer/types.go index 81ccf346669..f89dcfe6c93 100644 --- a/packages/relayer/types.go +++ b/packages/relayer/types.go @@ -7,13 +7,18 @@ import ( "time" "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/pkg/errors" log "github.com/sirupsen/logrus" + "github.com/taikoxyz/taiko-mono/packages/relayer/contracts/bridge" + "github.com/taikoxyz/taiko-mono/packages/relayer/contracts/tokenvault" ) var ( - ZeroHash = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000") + ZeroHash = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000") + ZeroAddress = common.HexToAddress("0x0000000000000000000000000000000000000000") ) // IsInSlice determines whether v is in slice s @@ -111,6 +116,55 @@ func WaitConfirmations(ctx context.Context, confirmer confirmer, confirmations u } } +func DecodeMessageSentData(event *bridge.BridgeMessageSent) (EventType, CanonicalToken, *big.Int, error) { + eventType := EventTypeSendETH + + var canonicalToken CanonicalToken + + var amount *big.Int + + if event.Message.Data != nil && common.BytesToHash(event.Message.Data) != ZeroHash { + tokenVaultMD := bind.MetaData{ + ABI: tokenvault.TokenVaultABI, + } + + tokenVaultABI, err := tokenVaultMD.GetAbi() + if err != nil { + return eventType, CanonicalToken{}, big.NewInt(0), errors.Wrap(err, "tokenVaultMD.GetAbi()") + } + + method, err := tokenVaultABI.MethodById(event.Message.Data[:4]) + if err != nil { + return eventType, CanonicalToken{}, big.NewInt(0), errors.Wrap(err, "tokenVaultABI.MethodById") + } + + inputsMap := make(map[string]interface{}) + + if err := method.Inputs.UnpackIntoMap(inputsMap, event.Message.Data[4:]); err != nil { + return eventType, CanonicalToken{}, big.NewInt(0), errors.Wrap(err, "method.Inputs.UnpackIntoMap") + } + + if method.Name == "receiveERC20" { + eventType = EventTypeSendERC20 + + canonicalToken = inputsMap["canonicalToken"].(struct { + // nolint + ChainId *big.Int `json:"chainId"` + Addr common.Address `json:"addr"` + Decimals uint8 `json:"decimals"` + Symbol string `json:"symbol"` + Name string `json:"name"` + }) + + amount = inputsMap["amount"].(*big.Int) + } + } else { + amount = event.Message.DepositValue + } + + return eventType, canonicalToken, amount, nil +} + type CanonicalToken struct { // nolint ChainId *big.Int `json:"chainId"` diff --git a/packages/relayer/types_test.go b/packages/relayer/types_test.go index bfe9d895633..e26cbfdd8ab 100644 --- a/packages/relayer/types_test.go +++ b/packages/relayer/types_test.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/assert" + "github.com/taikoxyz/taiko-mono/packages/relayer/contracts/bridge" ) func Test_IsInSlice(t *testing.T) { @@ -144,3 +145,58 @@ func Test_WaitConfirmations(t *testing.T) { }) } } + +func Test_DecodeMessageSentData(t *testing.T) { + tests := []struct { + name string + event *bridge.BridgeMessageSent + wantEventType EventType + wantCanonicalToken CanonicalToken + wantAmount *big.Int + wantError error + }{ + { + "receiveERC20", + &bridge.BridgeMessageSent{ + Message: bridge.IBridgeMessage{ + // nolint lll + Data: common.Hex2Bytes("0c6fab8200000000000000000000000000000000000000000000000000000000000000800000000000000000000000004ec242468812b6ffc8be8ff423af7bd23108d9910000000000000000000000004ec242468812b6ffc8be8ff423af7bd23108d99100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000007a68000000000000000000000000e4337137828c93d0046212ebda8a82a24356b67b000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000004544553540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000095465737445524332300000000000000000000000000000000000000000000000"), + }, + }, + EventTypeSendERC20, + CanonicalToken{ + ChainId: big.NewInt(31336), + Addr: common.HexToAddress("0xe4337137828c93D0046212ebDa8a82a24356b67B"), + Decimals: uint8(18), + Symbol: "TEST", + Name: "TestERC20", + }, + big.NewInt(1), + nil, + }, + { + "nilData", + &bridge.BridgeMessageSent{ + Message: bridge.IBridgeMessage{ + // nolint lll + DepositValue: big.NewInt(1), + Data: common.Hex2Bytes("00"), + }, + }, + EventTypeSendETH, + CanonicalToken{}, + big.NewInt(1), + nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + eventType, canonicalToken, amount, err := DecodeMessageSentData(tt.event) + assert.Equal(t, tt.wantEventType, eventType) + assert.Equal(t, tt.wantCanonicalToken, canonicalToken) + assert.Equal(t, tt.wantAmount, amount) + assert.Equal(t, tt.wantError, err) + }) + } +}