Skip to content

Commit

Permalink
chore: migrate nonce state (#5395)
Browse files Browse the repository at this point in the history
* chore: migrate nonce state

* try

* audit: ip

* clean up

* rm redux dep

* disable tests
  • Loading branch information
skylarbarrera authored Feb 9, 2024
1 parent 69b5606 commit 2622bbc
Show file tree
Hide file tree
Showing 18 changed files with 315 additions and 236 deletions.
1 change: 0 additions & 1 deletion CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ src/model/wallet.ts @skylarbarrera @jinchung

# redux
src/redux/gas.ts @skylarbarrera @benisgold @jinchung
src/redux/nonceManager.ts @derHowie @skylarbarrera @benisgold @jinchung

# navigation
src/navigation @skylarbarrera @benisgold
Expand Down
1 change: 0 additions & 1 deletion src/entities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export type {
export { NativeCurrencyKeys } from './nativeCurrencyTypes';
export type { NativeCurrencyKey } from './nativeCurrencyTypes';
export type Numberish = string | number;
export type { NonceManager } from './nonce';
export { default as ProtocolTypeNames, ProtocolType } from './protocolTypes';
export type { UniqueAsset } from './uniqueAssets';
export type {
Expand Down
12 changes: 0 additions & 12 deletions src/entities/nonce.ts

This file was deleted.

13 changes: 0 additions & 13 deletions src/handlers/localstorage/nonceManager.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ export { default as useForceUpdate } from './useForceUpdate';
export { default as useOnAvatarPress } from './useOnAvatarPress';
export { default as useAdditionalAssetData } from './useAdditionalAssetData';
export { default as useImportingWallet } from './useImportingWallet';
export { default as useCurrentNonce } from './useCurrentNonce';
export { default as usePersistentAspectRatio } from './usePersistentAspectRatio';
export { default as useFeesPanelInputRefs } from './useFeesPanelInputRefs';
export { default as useHardwareBack, useHardwareBackOnFocus } from './useHardwareBack';
Expand Down
39 changes: 0 additions & 39 deletions src/hooks/useCurrentNonce.ts
Original file line number Diff line number Diff line change
@@ -1,39 +0,0 @@
import { useCallback } from 'react';
import { useSelector } from 'react-redux';
import { EthereumAddress } from '@/entities';
import { getProviderForNetwork } from '@/handlers/web3';
import { Network } from '@/helpers/networkTypes';
import { AppState } from '@/redux/store';
import logger from '@/utils/logger';

export default function useCurrentNonce(accountAddress: EthereumAddress, network?: Network) {
const nonceInState = useSelector((state: AppState) => {
if (!network || !accountAddress) return undefined;
return state.nonceManager[accountAddress.toLowerCase()]?.[network]?.nonce;
});
const getNextNonce = useCallback(async () => {
try {
if (!network || !accountAddress) return undefined;
const provider = await getProviderForNetwork(network);
const transactionCount = await provider.getTransactionCount(accountAddress, 'pending');
const transactionIndex = transactionCount - 1;
const nextNonceBase = !nonceInState || transactionIndex > nonceInState ? transactionIndex : nonceInState;
const nextNonce = nextNonceBase + 1;

logger.log('Use current nonce: ', {
accountAddress,
network,
nextNonce,
nonceInState,
transactionCount,
});

return nextNonce;
} catch (e) {
logger.log('Error determining next nonce: ', e);
return undefined;
}
}, [accountAddress, network, nonceInState]);

return getNextNonce;
}
31 changes: 16 additions & 15 deletions src/hooks/useENSRegistrationActionHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { avatarMetadataAtom } from '../components/ens-registration/RegistrationA
import { coverMetadataAtom } from '../components/ens-registration/RegistrationCover/RegistrationCover';
import { ENSActionParameters, RapActionTypes } from '../raps/common';
import usePendingTransactions from './usePendingTransactions';
import { useAccountSettings, useCurrentNonce, useENSRegistration, useWalletENSAvatar, useWallets } from '.';
import { useAccountSettings, useENSRegistration, useWalletENSAvatar, useWallets } from '.';
import { Records, RegistrationParameters } from '@/entities';
import { fetchResolver } from '@/handlers/ens';
import { saveNameFromLabelhash } from '@/handlers/localstorage/ens';
Expand All @@ -19,6 +19,8 @@ import { executeRap } from '@/raps';
import { timeUnits } from '@/references';
import Routes from '@/navigation/routesNames';
import { labelhash, logger } from '@/utils';
import { getNextNonce } from '@/state/nonces';
import { Network } from '@/networks/types';

const NOOP = () => null;

Expand Down Expand Up @@ -46,8 +48,7 @@ export default function useENSRegistrationActionHandler(
step: keyof typeof REGISTRATION_STEPS;
} = {} as any
) {
const { accountAddress, network } = useAccountSettings();
const getNextNonce = useCurrentNonce(accountAddress, network);
const { accountAddress } = useAccountSettings();
const { registrationParameters } = useENSRegistration();
const { navigate, goBack } = useNavigation();
const { getPendingTransactionByHash } = usePendingTransactions();
Expand Down Expand Up @@ -92,7 +93,7 @@ export default function useENSRegistrationActionHandler(
const salt = generateSalt();

const [nonce, rentPrice] = await Promise.all([
getNextNonce(),
getNextNonce({ network: Network.mainnet, address: accountAddress }),
getRentPrice(registrationParameters.name.replace(ENS_DOMAIN, ''), duration),
]);

Expand All @@ -116,7 +117,7 @@ export default function useENSRegistrationActionHandler(
callback;
});
},
[getNextNonce, registrationParameters, duration, accountAddress, isHardwareWallet, goBack]
[registrationParameters, duration, accountAddress, isHardwareWallet, goBack]
);

const speedUpCommitAction = useCallback(
Expand Down Expand Up @@ -147,7 +148,7 @@ export default function useENSRegistrationActionHandler(
}

const [nonce, rentPrice, changedRecords] = await Promise.all([
getNextNonce(),
getNextNonce({ network: Network.mainnet, address: accountAddress }),
getRentPrice(name.replace(ENS_DOMAIN, ''), duration),
uploadRecordImages(registrationParameters.changedRecords, {
avatar: avatarMetadata,
Expand All @@ -169,7 +170,7 @@ export default function useENSRegistrationActionHandler(

updateAvatarsOnNextBlock.current = true;
},
[accountAddress, avatarMetadata, coverMetadata, getNextNonce, registrationParameters, sendReverseRecord]
[accountAddress, avatarMetadata, coverMetadata, registrationParameters, sendReverseRecord]
);

const renewAction = useCallback(
Expand All @@ -182,7 +183,7 @@ export default function useENSRegistrationActionHandler(
return;
}

const nonce = await getNextNonce();
const nonce = await getNextNonce({ network: Network.mainnet, address: accountAddress });
const rentPrice = await getRentPrice(name.replace(ENS_DOMAIN, ''), duration);

const registerEnsRegistrationParameters: ENSActionParameters = {
Expand All @@ -194,7 +195,7 @@ export default function useENSRegistrationActionHandler(

await executeRap(wallet, RapActionTypes.renewENS, registerEnsRegistrationParameters, callback);
},
[duration, getNextNonce, registrationParameters]
[accountAddress, duration, registrationParameters]
);

const setNameAction = useCallback(
Expand All @@ -207,7 +208,7 @@ export default function useENSRegistrationActionHandler(
return;
}

const nonce = await getNextNonce();
const nonce = await getNextNonce({ network: Network.mainnet, address: accountAddress });

const registerEnsRegistrationParameters: ENSActionParameters = {
...formatENSActionParams(registrationParameters),
Expand All @@ -218,7 +219,7 @@ export default function useENSRegistrationActionHandler(

await executeRap(wallet, RapActionTypes.setNameENS, registerEnsRegistrationParameters, callback);
},
[accountAddress, getNextNonce, registrationParameters]
[accountAddress, registrationParameters]
);

const setRecordsAction = useCallback(
Expand All @@ -230,7 +231,7 @@ export default function useENSRegistrationActionHandler(
}

const [nonce, changedRecords, resolver] = await Promise.all([
getNextNonce(),
getNextNonce({ network: Network.mainnet, address: accountAddress }),
uploadRecordImages(registrationParameters.changedRecords, {
avatar: avatarMetadata,
header: coverMetadata,
Expand All @@ -251,7 +252,7 @@ export default function useENSRegistrationActionHandler(

updateAvatarsOnNextBlock.current = true;
},
[accountAddress, avatarMetadata, coverMetadata, getNextNonce, registrationParameters, sendReverseRecord]
[accountAddress, avatarMetadata, coverMetadata, registrationParameters, sendReverseRecord]
);

const transferAction = useCallback(
Expand All @@ -268,7 +269,7 @@ export default function useENSRegistrationActionHandler(
return;
}

const nonce = await getNextNonce();
const nonce = await getNextNonce({ network: Network.mainnet, address: accountAddress });

const transferEnsParameters: ENSActionParameters = {
...formatENSActionParams({
Expand All @@ -288,7 +289,7 @@ export default function useENSRegistrationActionHandler(

return { nonce: newNonce };
},
[accountAddress, getNextNonce, registrationParameters]
[accountAddress, registrationParameters]
);

const actions = useMemo(
Expand Down
6 changes: 1 addition & 5 deletions src/hooks/useLoadGlobalLateData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { getWalletBalances, WALLET_BALANCES_FROM_STORAGE } from '@/handlers/localstorage/walletBalances';
import { queryClient } from '@/react-query';
import { nonceManagerLoadState } from '@/redux/nonceManager';
import { AppState } from '@/redux/store';
import { promiseUtils } from '@/utils';
import logger from '@/utils/logger';
Expand All @@ -26,9 +25,6 @@ export default function useLoadGlobalLateData() {
logger.sentry('Load wallet global late data');
const promises = [];

// wallet nonces
const p1 = dispatch(nonceManagerLoadState());

// mainnet eth balances for all wallets
const p2 = loadWalletBalanceNamesToCache();

Expand All @@ -50,7 +46,7 @@ export default function useLoadGlobalLateData() {
// tx method names
const p7 = dispatch(transactionSignaturesLoadState());

promises.push(p1, p2, p3, p4, p5, p6, p7);
promises.push(p2, p3, p4, p5, p6, p7);

// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '(Promise<void> | ((dispatch: Dis... Remove this comment to see the full error message
return promiseUtils.PromiseAllWithFails(promises);
Expand Down
26 changes: 14 additions & 12 deletions src/redux/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { StaticJsonRpcProvider, TransactionResponse } from '@ethersproject/provi
import { isEmpty, isNil, mapValues, partition } from 'lodash';
import { Dispatch } from 'redux';
import { ThunkDispatch } from 'redux-thunk';
import { decrementNonce, incrementNonce } from './nonceManager';
import { AppGetState, AppState } from './store';
import {
NativeCurrencyKeys,
Expand Down Expand Up @@ -43,6 +42,7 @@ import { queryClient } from '@/react-query';
import { RainbowAddressAssets } from '@/resources/assets/types';
import { nftsQueryKey } from '@/resources/nfts';
import { getProvider } from 'e2e/helpers';
import { nonceStore } from '@/state/nonces';

const BACKUP_SHEET_DELAY_MS = android ? 10000 : 3000;

Expand Down Expand Up @@ -358,9 +358,9 @@ const checkForUpdatedNonce =
const [latestTx] = txSortedByDescendingNonce;
const addressFrom = latestTx?.address_from;
const nonce = latestTx?.nonce;
if (addressFrom && nonce) {
// @ts-ignore-next-line
dispatch(incrementNonce(addressFrom!, nonce, network));
if (!isNil(addressFrom) && nonce) {
const { setNonce } = nonceStore.getState();
setNonce({ address: addressFrom, currentNonce: nonce, network });
}
}
};
Expand Down Expand Up @@ -587,11 +587,9 @@ export const dataAddNewTransaction =

loggr.debug('dataAddNewTransaction: adding pending transactions', {}, loggr.DebugContext.f2c);

if (parsedTransaction.from && parsedTransaction.nonce) {
dispatch(
// @ts-ignore-next-line
incrementNonce(parsedTransaction.from, parsedTransaction.nonce, parsedTransaction.network)
);
if (parsedTransaction.from && parsedTransaction.nonce && parsedTransaction.network) {
const { setNonce } = nonceStore.getState();
setNonce({ address: parsedTransaction.from, currentNonce: parsedTransaction.nonce, network: parsedTransaction.network });
}
if (!disableTxnWatcher || network !== Network.mainnet || parsedTransaction?.network) {
loggr.debug('dataAddNewTransaction: watching new pending transactions', {}, loggr.DebugContext.f2c);
Expand Down Expand Up @@ -714,9 +712,13 @@ export const dataWatchPendingTransactions =
pendingTransactionData = await getTransactionFlashbotStatus(updatedPendingTransaction, txHash);
if (pendingTransactionData && !pendingTransactionData.pending) {
txStatusesDidChange = true;
// decrement the nonce since it was dropped
// @ts-ignore-next-line
dispatch(decrementNonce(tx.from!, tx.nonce!, Network.mainnet));
if (tx.from && tx.network) {
const { setNonce, nonces } = nonceStore.getState();
const currentNonce = nonces[tx.from!][tx.network].currentNonce;
if (currentNonce) {
setNonce({ address: tx.from, currentNonce: currentNonce - 1, network: tx.network });
}
}
}
}
if (pendingTransactionData) {
Expand Down
Loading

0 comments on commit 2622bbc

Please sign in to comment.