From 61946ff703c445be041953e0f3fca5b667764720 Mon Sep 17 00:00:00 2001 From: Eric Taylor Date: Mon, 23 Sep 2024 08:38:56 -0600 Subject: [PATCH] feat: breakout spend reducers filters --- .../spend-reducers/useSpendableLockedUTXOs.ts | 57 +++++++++++-------- .../spend-reducers/useUnlockedUTXOs.ts | 49 +++++++++------- 2 files changed, 60 insertions(+), 46 deletions(-) diff --git a/src/vms/pvm/etna-builder/spend-reducers/useSpendableLockedUTXOs.ts b/src/vms/pvm/etna-builder/spend-reducers/useSpendableLockedUTXOs.ts index 5b59f08cb..da42cf8a9 100644 --- a/src/vms/pvm/etna-builder/spend-reducers/useSpendableLockedUTXOs.ts +++ b/src/vms/pvm/etna-builder/spend-reducers/useSpendableLockedUTXOs.ts @@ -17,7 +17,38 @@ import { } from '../../../../utils'; import { verifySignaturesMatch } from '../../../utils/calculateSpend/utils'; import { IncorrectStakeableLockOutError } from './errors'; -import type { SpendReducerFunction } from './types'; +import type { SpendReducerFunction, SpendReducerState } from './types'; + +/** + * Is responsible for filtering out the usable UTXOs from the list of UTXOs. + * + * @internal - Only exported for testing. + */ +export const getUsableUTXOsFilter = + (state: SpendReducerState) => + (utxo: Utxo): utxo is Utxo> => { + // 1a. Ensure UTXO output is a StakeableLockOut. + if (!isStakeableLockOut(utxo.output)) { + return false; + } + + // 1b. Ensure UTXO is stakeable. + if (!(state.spendOptions.minIssuanceTime < utxo.output.getLocktime())) { + return false; + } + + // 1c. Ensure transferOut is a TransferOutput. + if (!isTransferOut(utxo.output.transferOut)) { + throw IncorrectStakeableLockOutError; + } + + // 1d. Filter out UTXOs that aren't needed for staking. + if ((state.toStake.get(utxo.assetId.value()) ?? 0n) === 0n) { + return false; + } + + return true; + }; export const useSpendableLockedUTXOs: SpendReducerFunction = ( state, @@ -26,29 +57,7 @@ export const useSpendableLockedUTXOs: SpendReducerFunction = ( // 1. Filter out the UTXOs that are not usable. const usableUTXOs: Utxo>[] = state.utxos // Filter out non stakeable lockouts and lockouts that are not stakeable yet. - .filter((utxo): utxo is Utxo> => { - // 1a. Ensure UTXO output is a StakeableLockOut. - if (!isStakeableLockOut(utxo.output)) { - return false; - } - - // 1b. Ensure UTXO is stakeable. - if (!(state.spendOptions.minIssuanceTime < utxo.output.getLocktime())) { - return false; - } - - // 1c. Ensure there are funds to stake. - if ((state.toStake.get(utxo.assetId.value()) ?? 0n) === 0n) { - return false; - } - - // 1d. Ensure transferOut is a TransferOutput. - if (!isTransferOut(utxo.output.transferOut)) { - throw IncorrectStakeableLockOutError; - } - - return true; - }); + .filter(getUsableUTXOsFilter(state)); // 2. Verify signatures match. const verifiedUsableUTXOs = verifySignaturesMatch( diff --git a/src/vms/pvm/etna-builder/spend-reducers/useUnlockedUTXOs.ts b/src/vms/pvm/etna-builder/spend-reducers/useUnlockedUTXOs.ts index 796c50d54..8b9c4be37 100644 --- a/src/vms/pvm/etna-builder/spend-reducers/useUnlockedUTXOs.ts +++ b/src/vms/pvm/etna-builder/spend-reducers/useUnlockedUTXOs.ts @@ -15,7 +15,32 @@ import { } from '../../../../utils'; import { verifySignaturesMatch } from '../../../utils/calculateSpend/utils'; import { IncorrectStakeableLockOutError } from './errors'; -import type { SpendReducerFunction } from './types'; +import type { SpendReducerFunction, SpendReducerState } from './types'; + +/** + * Is responsible for filtering out the usable UTXOs from the list of UTXOs. + * + * @internal - Only exported for testing. + */ +export const getUsableUTXOsFilter = + (state: SpendReducerState) => + ( + utxo: Utxo, + ): utxo is Utxo> => { + if (isTransferOut(utxo.output)) { + return true; + } + + if (isStakeableLockOut(utxo.output)) { + if (!isTransferOut(utxo.output.transferOut)) { + throw IncorrectStakeableLockOutError; + } + + return utxo.output.getLocktime() < state.spendOptions.minIssuanceTime; + } + + return false; + }; export const useUnlockedUTXOs: SpendReducerFunction = ( state, @@ -26,27 +51,7 @@ export const useUnlockedUTXOs: SpendReducerFunction = ( const usableUTXOs: Utxo>[] = state.utxos // Filter out non stakeable lockouts and lockouts that are not stakeable yet. - .filter( - ( - utxo, - ): utxo is Utxo> => { - if (isTransferOut(utxo.output)) { - return true; - } - - if (isStakeableLockOut(utxo.output)) { - if (!isTransferOut(utxo.output.transferOut)) { - throw IncorrectStakeableLockOutError; - } - - return ( - utxo.output.getLocktime() < state.spendOptions.minIssuanceTime - ); - } - - return false; - }, - ); + .filter(getUsableUTXOsFilter(state)); // 2. Verify signatures match. const verifiedUsableUTXOs = verifySignaturesMatch(