-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Fix batch tx send encoding #11500
Fix batch tx send encoding #11500
Changes from 5 commits
3533802
6cfd636
9a344d1
fee5ee9
c01b243
6f4e4dc
fc715bb
cd63e08
839b06c
bab739a
a23125c
07994cc
0fc4c3d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -413,20 +413,21 @@ func ExtractRPCError(baseErr error) (*JsonError, error) { | |
return &jErr, nil | ||
} | ||
|
||
func ClassifySendError(err error, lggr logger.Logger, tx *types.Transaction, fromAddress common.Address, isL2 bool) (commonclient.SendTxReturnCode, error) { | ||
func ClassifySendError(err error, lggr logger.Logger, tx *types.Transaction, fromAddress common.Address, isL2 bool) commonclient.SendTxReturnCode { | ||
sendError := NewSendError(err) | ||
if sendError == nil { | ||
return commonclient.Successful, err | ||
return commonclient.Successful | ||
} | ||
if sendError.Fatal() { | ||
logger.Criticalw(lggr, "Fatal error sending transaction", "err", sendError, "etx", tx) | ||
// Attempt is thrown away in this case; we don't need it since it never got accepted by a node | ||
return commonclient.Fatal, err | ||
return commonclient.Fatal | ||
} | ||
if sendError.IsNonceTooLowError() || sendError.IsTransactionAlreadyMined() { | ||
lggr.Debugw("Transaction already confirmed for this nonce: %d", tx.Nonce(), "err", sendError) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For some of these messages we already log on the caller side, so you might want to aggregate those. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it be alright to keep both? The caller would be able to provide more info potentially and it'd also make tracing the call easier. And keeping it the logs in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not against it, but if we keep them let's try to differentiate the 2 messages to get more context. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've updated the error logging in the broadcaster and confirmer to avoid re-logging the same thing as the |
||
// Nonce too low indicated that a transaction at this nonce was confirmed already. | ||
// Mark it as TransactionAlreadyKnown. | ||
return commonclient.TransactionAlreadyKnown, err | ||
return commonclient.TransactionAlreadyKnown | ||
} | ||
if sendError.IsReplacementUnderpriced() { | ||
lggr.Errorw(fmt.Sprintf("Replacement transaction underpriced for eth_tx %x. "+ | ||
|
@@ -435,51 +436,56 @@ func ClassifySendError(err error, lggr logger.Logger, tx *types.Transaction, fro | |
tx.Hash(), err), "gasPrice", tx.GasPrice, "gasTipCap", tx.GasTipCap, "gasFeeCap", tx.GasFeeCap) | ||
|
||
// Assume success and hand off to the next cycle. | ||
return commonclient.Successful, err | ||
return commonclient.Successful | ||
} | ||
if sendError.IsTransactionAlreadyInMempool() { | ||
lggr.Debugw("Transaction already in mempool", "txHash", tx.Hash, "nodeErr", sendError.Error()) | ||
return commonclient.Successful, err | ||
return commonclient.Successful | ||
} | ||
if sendError.IsTemporarilyUnderpriced() { | ||
lggr.Infow("Transaction temporarily underpriced", "err", sendError.Error()) | ||
return commonclient.Successful, err | ||
return commonclient.Successful | ||
} | ||
if sendError.IsTerminallyUnderpriced() { | ||
return commonclient.Underpriced, err | ||
lggr.Errorw("Transaction terminally underpriced", "txHash", tx.Hash, "err", sendError) | ||
return commonclient.Underpriced | ||
} | ||
if sendError.L2FeeTooLow() || sendError.IsL2FeeTooHigh() || sendError.IsL2Full() { | ||
if isL2 { | ||
return commonclient.FeeOutOfValidRange, err | ||
lggr.Errorw("Transaction fee out of range", "err", sendError) | ||
return commonclient.FeeOutOfValidRange | ||
} | ||
return commonclient.Unsupported, errors.Wrap(sendError, "this error type only handled for L2s") | ||
lggr.Errorw("this error type only handled for L2s", "err", sendError) | ||
return commonclient.Unsupported | ||
} | ||
if sendError.IsNonceTooHighError() { | ||
// This error occurs when the tx nonce is greater than current_nonce + tx_count_in_mempool, | ||
// instead of keeping the tx in mempool. This can happen if previous transactions haven't | ||
// reached the client yet. The correct thing to do is to mark it as retryable. | ||
lggr.Warnw("Transaction has a nonce gap.", "err", err) | ||
return commonclient.Retryable, err | ||
return commonclient.Retryable | ||
} | ||
if sendError.IsInsufficientEth() { | ||
logger.Criticalw(lggr, fmt.Sprintf("Tx %x with type 0x%d was rejected due to insufficient eth: %s\n"+ | ||
"ACTION REQUIRED: Chainlink wallet with address 0x%x is OUT OF FUNDS", | ||
tx.Hash(), tx.Type(), sendError.Error(), fromAddress, | ||
), "err", sendError) | ||
return commonclient.InsufficientFunds, err | ||
return commonclient.InsufficientFunds | ||
} | ||
if sendError.IsTimeout() { | ||
return commonclient.Retryable, errors.Wrapf(sendError, "timeout while sending transaction %s", tx.Hash().Hex()) | ||
lggr.Errorw("timeout while sending transaction %s", tx.Hash().Hex(), "err", sendError) | ||
return commonclient.Retryable | ||
} | ||
if sendError.IsTxFeeExceedsCap() { | ||
logger.Criticalw(lggr, fmt.Sprintf("Sending transaction failed: %s", label.RPCTxFeeCapConfiguredIncorrectlyWarning), | ||
"etx", tx, | ||
"err", sendError, | ||
"id", "RPCTxFeeCapExceeded", | ||
) | ||
return commonclient.ExceedsMaxFee, err | ||
return commonclient.ExceedsMaxFee | ||
} | ||
return commonclient.Unknown, err | ||
lggr.Errorw("Unknown error encountered when sending transaction", "err", err) | ||
return commonclient.Unknown | ||
} | ||
|
||
// ClassifySendOnlyError handles SendOnly nodes error codes. In that case, we don't assume there is another transaction that will be correctly | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,10 +77,14 @@ func (c *evmTxmClient) BatchSendTransactions( | |
// convert to tx for logging purposes - exits early if error occurs | ||
tx, signedErr := GetGethSignedTx(attempts[i].SignedRawTx) | ||
if signedErr != nil { | ||
processingErr[i] = fmt.Errorf("failed to process tx (index %d): %w", i, signedErr) | ||
signedErrMsg := fmt.Sprintf("failed to process tx (index %d)", i) | ||
lggr.Errorw(signedErrMsg, "err", signedErr) | ||
processingErr[i] = fmt.Errorf("%s: %w", signedErrMsg, signedErr) | ||
return | ||
} | ||
codes[i], txErrs[i] = client.ClassifySendError(reqs[i].Error, lggr, tx, attempts[i].Tx.FromAddress, c.client.IsL2()) | ||
sendErr := reqs[i].Error | ||
codes[i] = client.ClassifySendError(sendErr, lggr, tx, attempts[i].Tx.FromAddress, c.client.IsL2()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what scenarios can the attempt.FromAddress differ from the tx.FromAddress? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we're just resorting to getting the from address from the attempt here because you can't get it through the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry didnt see you previous message :) |
||
txErrs[i] = sendErr | ||
}(index) | ||
} | ||
wg.Wait() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice cleanup here :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
out of curiosity is there any reason we dont grab the
fromAddress
from thetx
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. I think it's because this
Transaction
type isn't our internal one but thego-ethereum
one which doesn't expose the from address.