-
Notifications
You must be signed in to change notification settings - Fork 28
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
Wallet handle txs with conflicting account nonces #1864
base: master
Are you sure you want to change the base?
Conversation
bfbe582
to
3a2fd08
Compare
3a2fd08
to
6c83ac1
Compare
|
||
conflicting_txs.push(unconfirmed); | ||
if let Some((confirmed_account, confirmed_account_nonce)) = confirmed_account_nonce |
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.
this can probably be an else if, as the transactions that use a token id will be a superset of the transactions that use the token id and have a specific nonce.
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 that it'd make the code more confusing especially when modifying in the future. I replaced the vec with set to avoid duplicates.
8be3bb5
to
3327b22
Compare
Fixed the problem when abandoning a tx that is already marked as conflicted leads to invalid state of internal fields of OutputCache (like account nonces). |
} | ||
}, | ||
}, | ||
Entry::Vacant(_) => Err(WalletError::CannotFindTransactionWithId(tx_id)), |
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.
Is this also an invariant? If so, it deserves its own error.
But I also see that remove_tx
removes the tx from txs
unconditionally, possibly leaving it inside unconfirmed_descendants
. If this situation is legitimate, we probably shouldn't return an error 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.
To me it looks like an invariant. Because removing a tx removes its descendants as well.
TxState::Abandoned | ||
| TxState::Confirmed(..) | ||
| TxState::InMempool(..) | ||
| TxState::Conflicted(..) => { | ||
Err(WalletError::CannotChangeTransactionState( | ||
*tx.state(), | ||
TxState::Conflicted(block_id), | ||
)) | ||
} |
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.
This doesn't look nice. This whole function is called during block processing, so if this situation happens, the wallet will stop working, right?
Abandoned
, Confirmed
and Conflicted
probably can't happen here and are invariant violations, am I right? If so, a separate error would be nice.
But what about InMempool
? It sounds like it should be possible. If so, we must handle it somehow. Would it be wrong to change the state from InMempool
to Conflicted
?
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.
Looks like InMempool
-> Conflicted
is theoretically possible. Changed the logic to mark it as conflicted.
Unconfirmed txs in the wallet which uses outdated nonce are marked as conflicted now if confirmed tx is encountered on mainchain and the state of OutputCache is updated accordingly.
The behaviour is similar to abandoning tx.
Besides tests I had a wallet with conflicting orders which I couldn't open previously because of
InconsistentOrderDuplicateNonce
which is now resolved.