From 3566293520f761274d558ac50f1152110bc49b24 Mon Sep 17 00:00:00 2001 From: Albert Chon Date: Thu, 26 Jan 2023 17:47:05 -0500 Subject: [PATCH] fix: relay native Cosmos denoms deployed on Ethereum --- orchestrator/cosmos/broadcast.go | 65 ++++++++++++++++++++++++++++--- orchestrator/eth_event_watcher.go | 56 ++++++++++++++++++++++++-- 2 files changed, 112 insertions(+), 9 deletions(-) diff --git a/orchestrator/cosmos/broadcast.go b/orchestrator/cosmos/broadcast.go index 3b1879bd..b998af99 100644 --- a/orchestrator/cosmos/broadcast.go +++ b/orchestrator/cosmos/broadcast.go @@ -14,6 +14,7 @@ import ( chainclient "github.com/InjectiveLabs/sdk-go/client/chain" "github.com/InjectiveLabs/metrics" + "github.com/InjectiveLabs/peggo/orchestrator/ethereum/keystore" "github.com/InjectiveLabs/peggo/orchestrator/ethereum/peggy" @@ -55,6 +56,7 @@ type PeggyBroadcastClient interface { oldDeposits []*wrappers.PeggySendToCosmosEvent, deposits []*wrappers.PeggySendToInjectiveEvent, withdraws []*wrappers.PeggyTransactionBatchExecutedEvent, + erc20Deployed []*wrappers.PeggyERC20DeployedEvent, valsetUpdates []*wrappers.PeggyValsetUpdatedEvent, ) error @@ -274,7 +276,7 @@ func (s *peggyBroadcastClient) sendOldDepositClaims( log.WithFields(log.Fields{ "event_nonce": oldDeposit.EventNonce.String(), "txHash": txResponse.TxResponse.TxHash, - }).Infoln("Oracle sent old deposit event succesfully") + }).Infoln("Oracle sent old deposit event successfully") } return nil @@ -320,7 +322,7 @@ func (s *peggyBroadcastClient) sendDepositClaims( log.WithFields(log.Fields{ "event_nonce": deposit.EventNonce.String(), "txHash": txResponse.TxResponse.TxHash, - }).Infoln("Oracle sent deposit event succesfully") + }).Infoln("Oracle sent deposit event successfully") } return nil @@ -358,7 +360,7 @@ func (s *peggyBroadcastClient) sendWithdrawClaims( log.WithFields(log.Fields{ "event_nonce": withdraw.EventNonce.String(), "txHash": txResponse.TxResponse.TxHash, - }).Infoln("Oracle sent Withdraw event succesfully") + }).Infoln("Oracle sent Withdraw event successfully") } return nil @@ -407,7 +409,49 @@ func (s *peggyBroadcastClient) sendValsetUpdateClaims( log.WithFields(log.Fields{ "event_nonce": valsetUpdate.EventNonce.String(), "txHash": txResponse.TxResponse.TxHash, - }).Infoln("Oracle sent ValsetUpdate event succesfully") + }).Infoln("Oracle sent ValsetUpdate event successfully") + } + + return nil +} + +func (s *peggyBroadcastClient) sendErc20DeployedClaims( + ctx context.Context, + erc20Deployed *wrappers.PeggyERC20DeployedEvent, +) error { + metrics.ReportFuncCall(s.svcTags) + doneFn := metrics.ReportFuncTiming(s.svcTags) + defer doneFn() + + log.WithFields(log.Fields{ + "EventNonce": erc20Deployed.EventNonce.Uint64(), + "CosmosDenom": erc20Deployed.CosmosDenom, + "TokenContract": erc20Deployed.TokenContract.Hex(), + "Name": erc20Deployed.Name, + "Symbol": erc20Deployed.Symbol, + "Decimals": erc20Deployed.Decimals, + }).Infoln("Oracle observed a erc20Deployed event. Sending MsgERC20DeployedClaim") + + msg := &types.MsgERC20DeployedClaim{ + EventNonce: erc20Deployed.EventNonce.Uint64(), + BlockHeight: erc20Deployed.Raw.BlockNumber, + CosmosDenom: erc20Deployed.CosmosDenom, + TokenContract: erc20Deployed.TokenContract.Hex(), + Name: erc20Deployed.Name, + Symbol: erc20Deployed.Symbol, + Decimals: uint64(erc20Deployed.Decimals), + Orchestrator: s.AccFromAddress().String(), + } + + if txResponse, err := s.broadcastClient.SyncBroadcastMsg(msg); err != nil { + metrics.ReportFuncError(s.svcTags) + log.WithError(err).Errorln("broadcasting MsgERC20DeployedClaim failed") + return err + } else { + log.WithFields(log.Fields{ + "event_nonce": erc20Deployed.EventNonce.String(), + "txHash": txResponse.TxResponse.TxHash, + }).Infoln("Oracle sent ERC20DeployedEvent event successfully") } return nil @@ -419,14 +463,15 @@ func (s *peggyBroadcastClient) SendEthereumClaims( oldDeposits []*wrappers.PeggySendToCosmosEvent, deposits []*wrappers.PeggySendToInjectiveEvent, withdraws []*wrappers.PeggyTransactionBatchExecutedEvent, + erc20Deployed []*wrappers.PeggyERC20DeployedEvent, valsetUpdates []*wrappers.PeggyValsetUpdatedEvent, ) error { metrics.ReportFuncCall(s.svcTags) doneFn := metrics.ReportFuncTiming(s.svcTags) defer doneFn() - totalClaimEvents := len(oldDeposits) + len(deposits) + len(withdraws) + len(valsetUpdates) - var count, h, i, j, k int + totalClaimEvents := len(oldDeposits) + len(deposits) + len(withdraws) + len(erc20Deployed) + len(valsetUpdates) + var count, h, i, j, k, l int // Individual arrays (oldDeposits, deposits, withdraws, valsetUpdates) are sorted. // Broadcast claim events sequentially starting with eventNonce = lastClaimEvent + 1. @@ -464,6 +509,14 @@ func (s *peggyBroadcastClient) SendEthereumClaims( return err } k++ + } else if l < len(erc20Deployed) && erc20Deployed[l].EventNonce.Uint64() == lastClaimEvent+1 { + // send erc20 deployed claim + if err := s.sendErc20DeployedClaims(ctx, erc20Deployed[l]); err != nil { + metrics.ReportFuncError(s.svcTags) + log.WithError(err).Errorln("broadcasting MsgERC20DeployedClaim failed") + return err + } + l++ } count = count + 1 lastClaimEvent = lastClaimEvent + 1 diff --git a/orchestrator/eth_event_watcher.go b/orchestrator/eth_event_watcher.go index 33536352..8be16582 100644 --- a/orchestrator/eth_event_watcher.go +++ b/orchestrator/eth_event_watcher.go @@ -9,6 +9,7 @@ import ( log "github.com/xlab/suplog" "github.com/InjectiveLabs/metrics" + wrappers "github.com/InjectiveLabs/peggo/solidity/wrappers/Peggy.sol" ) @@ -157,6 +158,39 @@ func (s *peggyOrchestrator) CheckForEvents( "Withdraws": transactionBatchExecutedEvents, }).Debugln("Scanned TransactionBatchExecuted events from Ethereum") + var erc20DeployedEvents []*wrappers.PeggyERC20DeployedEvent + { + iter, err := peggyFilterer.FilterERC20DeployedEvent(&bind.FilterOpts{ + Start: startingBlock, + End: ¤tBlock, + }, nil) + if err != nil { + metrics.ReportFuncError(s.svcTags) + log.WithFields(log.Fields{ + "start": startingBlock, + "end": currentBlock, + }).Errorln("failed to scan past FilterERC20Deployed events from Ethereum") + + if !isUnknownBlockErr(err) { + err = errors.Wrap(err, "failed to scan past FilterERC20Deployed events from Ethereum") + return 0, err + } else if iter == nil { + return 0, errors.New("no iterator returned") + } + } + + for iter.Next() { + erc20DeployedEvents = append(erc20DeployedEvents, iter.Event) + } + + iter.Close() + } + log.WithFields(log.Fields{ + "start": startingBlock, + "end": currentBlock, + "erc20Deployed": erc20DeployedEvents, + }).Debugln("Scanned FilterERC20Deployed events from Ethereum") + var valsetUpdatedEvents []*wrappers.PeggyValsetUpdatedEvent { iter, err := peggyFilterer.FilterValsetUpdatedEvent(&bind.FilterOpts{ @@ -191,7 +225,7 @@ func (s *peggyOrchestrator) CheckForEvents( "valsetUpdates": valsetUpdatedEvents, }).Debugln("Scanned ValsetUpdatedEvents events from Ethereum") - // note that starting block overlaps with our last che cked block, because we have to deal with + // note that starting block overlaps with our last checked block, because we have to deal with // the possibility that the relayer was killed after relaying only one of multiple events in a single // block, so we also need this routine so make sure we don't send in the first event in this hypothetical // multi event block again. In theory we only send all events for every block and that will pass of fail @@ -206,11 +240,12 @@ func (s *peggyOrchestrator) CheckForEvents( oldDeposits := filterSendToCosmosEventsByNonce(sendToCosmosEvents, lastClaimEvent.EthereumEventNonce) deposits := filterSendToInjectiveEventsByNonce(sendToInjectiveEvents, lastClaimEvent.EthereumEventNonce) withdraws := filterTransactionBatchExecutedEventsByNonce(transactionBatchExecutedEvents, lastClaimEvent.EthereumEventNonce) + erc20Deployments := filterERC20DeployedEventsByNonce(erc20DeployedEvents, lastClaimEvent.EthereumEventNonce) valsetUpdates := filterValsetUpdateEventsByNonce(valsetUpdatedEvents, lastClaimEvent.EthereumEventNonce) - if len(oldDeposits) > 0 || len(deposits) > 0 || len(withdraws) > 0 || len(valsetUpdates) > 0 { + if len(oldDeposits) > 0 || len(deposits) > 0 || len(withdraws) > 0 || len(erc20Deployments) > 0 || len(valsetUpdates) > 0 { // todo get eth chain id from the chain - if err := s.peggyBroadcastClient.SendEthereumClaims(ctx, lastClaimEvent.EthereumEventNonce, oldDeposits, deposits, withdraws, valsetUpdates); err != nil { + if err := s.peggyBroadcastClient.SendEthereumClaims(ctx, lastClaimEvent.EthereumEventNonce, oldDeposits, deposits, withdraws, erc20Deployments, valsetUpdates); err != nil { metrics.ReportFuncError(s.svcTags) err = errors.Wrap(err, "failed to send ethereum claims to Cosmos chain") return 0, err @@ -265,6 +300,21 @@ func filterTransactionBatchExecutedEventsByNonce( return res } +func filterERC20DeployedEventsByNonce( + events []*wrappers.PeggyERC20DeployedEvent, + nonce uint64, +) []*wrappers.PeggyERC20DeployedEvent { + res := make([]*wrappers.PeggyERC20DeployedEvent, 0, len(events)) + + for _, ev := range events { + if ev.EventNonce.Uint64() > nonce { + res = append(res, ev) + } + } + + return res +} + func filterValsetUpdateEventsByNonce( events []*wrappers.PeggyValsetUpdatedEvent, nonce uint64,