-
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
Add nonce validation after broadcast for Hedera #13957
Add nonce validation after broadcast for Hedera #13957
Conversation
…ailed-transactions
common/txmgr/broadcaster.go
Outdated
return errType, err | ||
} | ||
// Check that the transaction count has incremented on-chain to include the broadcasted transaction | ||
// Insufficient transaction fee is a common scenario in which the sequence is not incremented by the chain |
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.
Let's be even more explicit about this
// Insufficient transaction fee is a common scenario in which the sequence is not incremented by the chain | |
// Insufficient transaction fee is a common scenario in which the sequence is not incremented by the chain even though we got a successful response |
// Check that the transaction count has incremented on-chain to include the broadcasted transaction | ||
// Insufficient transaction fee is a common scenario in which the sequence is not incremented by the chain | ||
// If the sequence failed to increment and hasn't reached the max retries, return the Underpriced error to try again with a bumped attempt | ||
if nextSeqOnChain.Int64() == txSeq.Int64() && retryCount < maxHederaBroadcastRetries { |
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.
nit: in theory if nextSeqOnChain is < txSeq we can mark tx as Successful
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.
nextSeqOnChain < txSeq
I think would be an indicator of a nonce gap which wouldn't return a successful errType
so we would have exited early. But for a belts and braces approach, I added the condition just in case and mark the tx as Fatal in this case.
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.
Maybe @dhaidashenko you meant nextSeqOnChain > txSeq
?
I agree that nextSeqOnChain < txSeq
would be incorrect and caught by SendTransactionReturnCode
early, and probably due to a reorg in this case ? otherwise not sure about how this is possible.
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.
Ah if that's the case then classifying that as Successful
is ok because we process TransactionAlreadyKnown
as the same.
Also unsure if nextSeqOnChain < txSeq
is a scenario we could realistically hit for this chain. I believe re-orgs aren't possible because of instant finality. But there could be some obscure scenario so this check should help.
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.
Retryable
is also another option for the nextSeqOnChain < txSeq
case. There are two scenarios:
- We have a nonce gap: fatal will alert us sooner, but we might miss reorg cases and it won't recover anyway
- There was a reorg or RPC was lagging: retryable will handle this, although I found out that Hedera doesn't handle nonce too high errors gracefully, so it will throw a bunch of errors during this process.
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.
lgtm except one small nit, but due to the limited knowledge/context I have now, I will just comment instead of approve :)
@@ -600,6 +615,44 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) hand | |||
} | |||
} | |||
|
|||
func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) validateOnChainSequence(ctx context.Context, lgr logger.SugaredLogger, errType client.SendTxReturnCode, err error, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], retryCount int) (client.SendTxReturnCode, error) { |
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.
shall we rename this function to imply it's only meant for Hedara
, or it's better to be generic ?
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.
I think it's alright either way. I considered that actually but opted to leave it implicit. I'm not against changing it though if others agree
// Check that the transaction count has incremented on-chain to include the broadcasted transaction | ||
// Insufficient transaction fee is a common scenario in which the sequence is not incremented by the chain | ||
// If the sequence failed to increment and hasn't reached the max retries, return the Underpriced error to try again with a bumped attempt | ||
if nextSeqOnChain.Int64() == txSeq.Int64() && retryCount < maxHederaBroadcastRetries { |
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.
Maybe @dhaidashenko you meant nextSeqOnChain > txSeq
?
I agree that nextSeqOnChain < txSeq
would be incorrect and caught by SendTransactionReturnCode
early, and probably due to a reorg in this case ? otherwise not sure about how this is possible.
…ailed-transactions
Quality Gate passedIssues Measures |
l.Warnw("transaction reverted on-chain unable to extract revert reason", "hash", receipt.GetTxHash(), "err", err) | ||
rpcError, errExtract := ec.client.CallContract(ctx, attempt, receipt.GetBlockNumber()) | ||
if errExtract == nil { | ||
l.Warnw("transaction reverted on-chain", "hash", receipt.GetTxHash(), "rpcError", rpcError.String()) |
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.
nit: It might make sense to set this reason back on the receipt struct right?
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.
I think it makes sense to leave this as a log instead of adding it to the Receipt struct. Since the TXM is indifferent to a tx reverting, I don't think we should try to store this to avoid adding another column.
## Motivation Cherry-pick of smartcontractkit/chainlink#14021 cherry-pick of smartcontractkit/chainlink#13957 cherry-pick of smartcontractkit/chainlink#13876 cherry-pick of smartcontractkit/chainlink#13907
* Added post-broadcast nonce validation for Hedera * Added changeset * Updated chaintype docs for Hedera * Fixed lint errors * Added condition to handle on-chain seq less than tx seq and updated comment
BCI-3843
RevertReason
field was added to theReceipt
struct to track this additional message provided by Hedera.