Commit 15f8d343 authored by cartcrom's avatar cartcrom Committed by GitHub

fix: update nonce deduplication logic (#6588)

* fix: update nonce-deduplication logic
* lint
parent 504e09d3
...@@ -82,7 +82,24 @@ const ActivityGroupWrapper = styled(Column)` ...@@ -82,7 +82,24 @@ const ActivityGroupWrapper = styled(Column)`
gap: 8px; gap: 8px;
` `
function combineActivities(localMap: ActivityMap = {}, remoteMap: ActivityMap = {}): Array<Activity> { /* Detects transactions from same account with the same nonce and different hash */
function wasTxCancelled(localActivity: Activity, remoteMap: ActivityMap, account: string): boolean {
// handles locally cached tx's that were stored before we started tracking nonces
if (!localActivity.nonce || localActivity.status !== TransactionStatus.Pending) return false
return Object.values(remoteMap).some((remoteTx) => {
if (!remoteTx) return false
// Cancellations are only possible when both nonce and tx.from are the same
if (remoteTx.nonce === localActivity.nonce && remoteTx.receipt?.from.toLowerCase() === account.toLowerCase()) {
// If the remote tx has a different hash than the local tx, the local tx was cancelled
return remoteTx.hash.toLowerCase() !== localActivity.hash.toLowerCase()
}
return false
})
}
function combineActivities(localMap: ActivityMap = {}, remoteMap: ActivityMap = {}, account: string): Array<Activity> {
const txHashes = [...new Set([...Object.keys(localMap), ...Object.keys(remoteMap)])] const txHashes = [...new Set([...Object.keys(localMap), ...Object.keys(remoteMap)])]
// Merges local and remote activities w/ same hash, preferring remote data // Merges local and remote activities w/ same hash, preferring remote data
...@@ -90,16 +107,12 @@ function combineActivities(localMap: ActivityMap = {}, remoteMap: ActivityMap = ...@@ -90,16 +107,12 @@ function combineActivities(localMap: ActivityMap = {}, remoteMap: ActivityMap =
const localActivity = (localMap?.[hash] ?? {}) as Activity const localActivity = (localMap?.[hash] ?? {}) as Activity
const remoteActivity = (remoteMap?.[hash] ?? {}) as Activity const remoteActivity = (remoteMap?.[hash] ?? {}) as Activity
// Check for nonce collision // TODO(WEB-2064): Display cancelled status in UI rather than completely hiding cancelled TXs
const isNonceCollision = if (wasTxCancelled(localActivity, remoteMap, account)) return acc
localActivity.nonce !== undefined &&
Object.keys(remoteMap).some((remoteHash) => remoteMap[remoteHash]?.nonce === localActivity.nonce)
if (!isNonceCollision) { // TODO(cartcrom): determine best logic for which fields to prefer from which sources
// TODO(cartcrom): determine best logic for which fields to prefer from which sources // i.e.prefer remote exact swap output instead of local estimated output
// i.e.prefer remote exact swap output instead of local estimated output acc.push({ ...localActivity, ...remoteActivity } as Activity)
acc.push({ ...localActivity, ...remoteActivity } as Activity)
}
return acc return acc
}, []) }, [])
...@@ -132,9 +145,9 @@ export function ActivityTab({ account }: { account: string }) { ...@@ -132,9 +145,9 @@ export function ActivityTab({ account }: { account: string }) {
const activityGroups = useMemo(() => { const activityGroups = useMemo(() => {
const remoteMap = parseRemoteActivities(data?.portfolios?.[0].assetActivities) const remoteMap = parseRemoteActivities(data?.portfolios?.[0].assetActivities)
const allActivities = combineActivities(localMap, remoteMap) const allActivities = combineActivities(localMap, remoteMap, account)
return createGroups(allActivities) return createGroups(allActivities)
}, [data?.portfolios, localMap]) }, [data?.portfolios, localMap, account])
if (!data && loading) if (!data && loading)
return ( return (
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment