From ae029c4ca23869ac8f210d726a4cc2df1d96bf3f Mon Sep 17 00:00:00 2001 From: Pavel Soloviev Date: Thu, 6 Oct 2022 19:31:08 +0300 Subject: [PATCH] Added nonce check --- src/service/claim.go | 5 +-- src/service/relayer.go | 2 +- src/service/storage/models.go | 1 + .../workers/eth-compatible/erc20-worker.go | 32 ++++++++++++------- src/service/workers/worker.go | 4 +-- 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/service/claim.go b/src/service/claim.go index c469737..6aff8de 100644 --- a/src/service/claim.go +++ b/src/service/claim.go @@ -14,7 +14,7 @@ import ( func (r *RelayerSRV) emitChainSendClaim() { for { swaps := r.storage.GetSwapsByTypeAndStatuses( - []storage.SwapStatus{storage.SwapStatusDepositConfirmed, storage.SwapStatusClaimConfirmed, storage.SwapStatusDepositInit, storage.SwapStatusClaimSentFailed}) + []storage.SwapStatus{storage.SwapStatusDepositConfirmed, storage.SwapStatusClaimConfirmed, storage.SwapStatusDepositInit, storage.SwapStatusClaimSentFailed, storage.SwapStatusClaimSent}) for _, swap := range swaps { if swap.Status == storage.SwapStatusDepositConfirmed { r.logger.Info("attempting to send claim for swap") @@ -98,7 +98,7 @@ func (r *RelayerSRV) sendClaim(worker workers.IWorker, swap *storage.Swap) (stri r.logger.Infof("claim parameters: depositNonce(%d) | sender(%s) | outAmount(%d) | resourceID(%s)\n", swap.DepositNonce, swap.SenderAddr, amount, swap.ResourceID) - txHash, err := worker.Vote(swap.DepositNonce, utils.StringToBytes8(swap.OriginChainID), utils.StringToBytes8(swap.DestinationChainID), + txHash, nonce, err := worker.Vote(swap.DepositNonce, utils.StringToBytes8(swap.OriginChainID), utils.StringToBytes8(swap.DestinationChainID), utils.StringToBytes32(swap.ResourceID), swap.ReceiverAddr, amount) if err != nil { txSent.ErrMsg = err.Error() @@ -107,6 +107,7 @@ func (r *RelayerSRV) sendClaim(worker workers.IWorker, swap *storage.Swap) (stri return "", fmt.Errorf("could not send claim tx: %w", err) } txSent.TxHash = txHash + txSent.Nonce = nonce r.storage.UpdateSwapStatus(swap, storage.SwapStatusClaimSent, "") r.logger.Infof("send claim tx success | chain=%s, swap_ID=%s, tx_hash=%s", worker.GetChainName(), diff --git a/src/service/relayer.go b/src/service/relayer.go index acc52cf..b5a0eda 100644 --- a/src/service/relayer.go +++ b/src/service/relayer.go @@ -195,7 +195,7 @@ func (r *RelayerSRV) CheckTxSent(worker workers.IWorker) { for _, txSent := range txsSent { // Get status of tx from chain - status := worker.GetSentTxStatus(txSent.TxHash) + status := worker.GetSentTxStatus(txSent.TxHash, txSent.Nonce) if err := r.storage.UpdateTxSentStatus(txSent, status); err != nil { r.logger.WithFields(logrus.Fields{"function": "CheckTxSent() | UpdateTxSentStatus()"}).Errorln(err) return diff --git a/src/service/storage/models.go b/src/service/storage/models.go index 5653443..3d44351 100644 --- a/src/service/storage/models.go +++ b/src/service/storage/models.go @@ -78,6 +78,7 @@ type TxSent struct { TxHash string `json:"tx_hash" gorm:"type:TEXT"` ErrMsg string `json:"err_msg" gorm:"type:TEXT"` Status TxStatus `json:"status" gorm:"type:tx_statuses"` + Nonce string `json:"nonce" gorm:"type:TEXT"` CreateTime int64 `json:"create_time" gorm:"type:BIGINT"` UpdateTime int64 `json:"update_time" gorm:"type:BIGINT"` } diff --git a/src/service/workers/eth-compatible/erc20-worker.go b/src/service/workers/eth-compatible/erc20-worker.go index d2a1f53..c2c1309 100644 --- a/src/service/workers/eth-compatible/erc20-worker.go +++ b/src/service/workers/eth-compatible/erc20-worker.go @@ -6,6 +6,7 @@ import ( "crypto/ecdsa" "fmt" "math/big" + "strconv" "strings" "time" @@ -223,31 +224,31 @@ func (w *Erc20Worker) GetHeight() (int64, error) { } // Vote ... -func (w *Erc20Worker) Vote(depositNonce uint64, originchainID [8]byte, destinationChainID [8]byte, resourceID [32]byte, receiptAddr string, amount string) (string, error) { +func (w *Erc20Worker) Vote(depositNonce uint64, originchainID [8]byte, destinationChainID [8]byte, resourceID [32]byte, receiptAddr string, amount string) (string, string, error) { auth, err := w.getTransactor() if err != nil { - return "", err + return "", "", err } instance, err := labr.NewLabr(w.swapContractAddr, w.client) if err != nil { - return "", err + return "", "", err } value, _ := new(big.Int).SetString(amount, 10) tx, err := instance.VoteProposal(auth, originchainID, destinationChainID, depositNonce, resourceID, common.HexToAddress(receiptAddr), value) if err != nil { - return "", err + return "", "", err } - return tx.Hash().String(), nil + return tx.Hash().String(), auth.Nonce.String(), nil } func (w *Erc20Worker) GetTxCountLatest() (uint64, error) { var result hexutil.Uint64 rpcClient := jsonrpc.NewClient(w.provider) - resp, err := rpcClient.Call("eth_getTransactionCount", w.config.WorkerAddr.Hex(), "pending") + resp, err := rpcClient.Call("eth_getTransactionCount", w.config.WorkerAddr.Hex(), "latest") if err != nil { return 0, err } @@ -302,17 +303,26 @@ func (w *Erc20Worker) GetWorkerAddress() string { } // GetSentTxStatus ... -func (w *Erc20Worker) GetSentTxStatus(hash string) storage.TxStatus { +func (w *Erc20Worker) GetSentTxStatus(hash string, nonce string) storage.TxStatus { txReceipt, err := w.client.TransactionReceipt(context.Background(), common.HexToHash(hash)) if err != nil { - _, isPending, err := w.client.TransactionByHash(context.Background(), common.HexToHash(hash)) + txNonce, err := strconv.ParseUint(nonce, 10, 64) if err != nil { - if err == ethereum.NotFound { - return storage.TxSentStatusLost + _, isPending, err := w.client.TransactionByHash(context.Background(), common.HexToHash(hash)) + if err != nil { + if err == ethereum.NotFound { + return storage.TxSentStatusLost + } + return storage.TxSentStatusNotFound + } + if isPending { + return storage.TxSentStatusPending } return storage.TxSentStatusNotFound } - if isPending { + + txCount, _ := w.GetTxCountLatest() + if txNonce >= txCount { return storage.TxSentStatusPending } return storage.TxSentStatusNotFound diff --git a/src/service/workers/worker.go b/src/service/workers/worker.go index dd7ce00..85881d7 100644 --- a/src/service/workers/worker.go +++ b/src/service/workers/worker.go @@ -31,7 +31,7 @@ type IWorker interface { // // GetColdWalletAddress returns the address of the relayer's cold wallet // GetColdWalletAddress() string // GetSentTxStatus returns status of tx sent - GetSentTxStatus(hash string) storage.TxStatus + GetSentTxStatus(hash string, nonce string) storage.TxStatus // // GetBalance returns balance of swap token for any address // GetBalance(address, tokenSymbol string) (*big.Int, error) // // GetStatus returns status of relayer account(balance eg) @@ -54,5 +54,5 @@ type IWorker interface { // CreateRequest sends wrapped tokens tx // CreateRequest(swapID common.Hash) (string, error) // Vote - Vote(depositNonce uint64, originChainID [8]byte, destinationChainID [8]byte, resourceID [32]byte, receiptAddr string, amount string) (string, error) + Vote(depositNonce uint64, originChainID [8]byte, destinationChainID [8]byte, resourceID [32]byte, receiptAddr string, amount string) (string, string, error) }