(Fix) Duplicated txs (#508)
* Verify that the last tx was executed before attempting to execute current tx * fix merge bug * Properly calculate tx nonce * rename to a more explanatory name
This commit is contained in:
parent
165a088b1b
commit
30f3483119
|
@ -25,24 +25,31 @@ import {
|
||||||
import { getErrorMessage } from '~/test/utils/ethereumErrors'
|
import { getErrorMessage } from '~/test/utils/ethereumErrors'
|
||||||
import { ZERO_ADDRESS } from '~/logic/wallets/ethAddresses'
|
import { ZERO_ADDRESS } from '~/logic/wallets/ethAddresses'
|
||||||
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
||||||
|
import type { TransactionProps } from '~/routes/safe/store/models/transaction'
|
||||||
|
|
||||||
const getLastPendingTxNonce = async (safeAddress: string): Promise<number> => {
|
const getLastTx = async (safeAddress: string): Promise<TransactionProps> => {
|
||||||
let nonce
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const url = buildTxServiceUrl(safeAddress)
|
const url = buildTxServiceUrl(safeAddress)
|
||||||
|
|
||||||
const response = await axios.get(url, { params: { limit: 1 } })
|
const response = await axios.get(url, { params: { limit: 1 } })
|
||||||
const lastTx = response.data.results[0]
|
|
||||||
|
|
||||||
nonce = lastTx.nonce + 1
|
return response.data.results[0]
|
||||||
} catch (err) {
|
} catch (e) {
|
||||||
// use current's safe nonce as fallback
|
console.error('failed to retrieve last Tx from server', e)
|
||||||
const safeInstance = await getGnosisSafeInstanceAt(safeAddress)
|
return null
|
||||||
nonce = (await safeInstance.nonce()).toString()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nonce
|
const getSafeNonce = async (safeAddress: string): Promise<string> => {
|
||||||
|
// use current's safe nonce as fallback
|
||||||
|
const safeInstance = await getGnosisSafeInstanceAt(safeAddress)
|
||||||
|
return (await safeInstance.nonce()).toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
const getNewTxNonce = async (txNonce, lastTx, safeAddress) => {
|
||||||
|
if (!Number.isInteger(Number.parseInt(txNonce, 10))) {
|
||||||
|
return lastTx === null ? getSafeNonce(safeAddress) : lastTx.nonce + 1
|
||||||
|
}
|
||||||
|
return txNonce
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateTransactionArgs = {
|
type CreateTransactionArgs = {
|
||||||
|
@ -78,10 +85,9 @@ const createTransaction = ({
|
||||||
const from = userAccountSelector(state)
|
const from = userAccountSelector(state)
|
||||||
const safeInstance = await getGnosisSafeInstanceAt(safeAddress)
|
const safeInstance = await getGnosisSafeInstanceAt(safeAddress)
|
||||||
const threshold = await safeInstance.getThreshold()
|
const threshold = await safeInstance.getThreshold()
|
||||||
const nonce = !Number.isInteger(Number.parseInt(txNonce, 10))
|
const lastTx = await getLastTx(safeAddress)
|
||||||
? await getLastPendingTxNonce(safeAddress)
|
const nonce = await getNewTxNonce(txNonce, lastTx, safeAddress)
|
||||||
: txNonce
|
const isExecution = (lastTx && lastTx.isExecuted && threshold.toNumber() === 1) || shouldExecute
|
||||||
const isExecution = threshold.toNumber() === 1 || shouldExecute
|
|
||||||
|
|
||||||
// https://gnosis-safe.readthedocs.io/en/latest/contracts/signatures.html#pre-validated-signatures
|
// https://gnosis-safe.readthedocs.io/en/latest/contracts/signatures.html#pre-validated-signatures
|
||||||
const sigs = `0x000000000000000000000000${from.replace(
|
const sigs = `0x000000000000000000000000${from.replace(
|
||||||
|
|
Loading…
Reference in New Issue