Skip to content

Commit 934c855

Browse files
committed
feat(cip2): add support for custom random fn
1 parent aacfd7b commit 934c855

File tree

4 files changed

+28
-7
lines changed

4 files changed

+28
-7
lines changed

Diff for: packages/cip2/src/RoundRobinRandomImprove/change.ts

+15-4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ interface ChangeComputationArgs {
1414
estimateTxFee: EstimateTxFeeWithOriginalOutputs;
1515
computeMinimumCoinQuantity: ComputeMinimumCoinQuantity;
1616
tokenBundleSizeExceedsLimit: TokenBundleSizeExceedsLimit;
17+
random: typeof Math.random;
1718
}
1819

1920
interface ChangeComputationResult {
@@ -167,10 +168,13 @@ const computeRequestedAssetChangeBundles = (
167168
* Picks one UTxO from remaining set and puts it to the selected set.
168169
* Precondition: utxoRemaining.length > 0
169170
*/
170-
const pickExtraRandomUtxo = ({ utxoRemaining, utxoSelected }: UtxoSelection): UtxoSelection => {
171+
const pickExtraRandomUtxo = (
172+
{ utxoRemaining, utxoSelected }: UtxoSelection,
173+
random: typeof Math.random
174+
): UtxoSelection => {
171175
const remainingUtxoOfOnlyCoin = utxoRemaining.filter(([_, { value }]) => !value.assets);
172176
const pickFrom = remainingUtxoOfOnlyCoin.length > 0 ? remainingUtxoOfOnlyCoin : utxoRemaining;
173-
const pickIdx = Math.floor(Math.random() * pickFrom.length);
177+
const pickIdx = Math.floor(random() * pickFrom.length);
174178
const newUtxoSelected = [...utxoSelected, pickFrom[pickIdx]];
175179
const originalIdx = utxoRemaining.indexOf(pickFrom[pickIdx]);
176180
const newUtxoRemaining = [...utxoRemaining.slice(0, originalIdx), ...utxoRemaining.slice(originalIdx + 1)];
@@ -218,6 +222,7 @@ const computeChangeBundles = ({
218222
uniqueOutputAssetIDs,
219223
implicitCoin,
220224
computeMinimumCoinQuantity,
225+
random,
221226
fee = 0n
222227
}: {
223228
utxoSelection: UtxoSelection;
@@ -226,6 +231,7 @@ const computeChangeBundles = ({
226231
implicitCoin: Required<Cardano.ImplicitCoin>;
227232
computeMinimumCoinQuantity: ComputeMinimumCoinQuantity;
228233
fee?: bigint;
234+
random: typeof Math.random;
229235
}): UtxoSelection & { changeBundles: Cardano.Value[] } => {
230236
const requestedAssetChangeBundles = computeRequestedAssetChangeBundles(
231237
utxoSelection.utxoSelected,
@@ -251,8 +257,9 @@ const computeChangeBundles = ({
251257
fee,
252258
implicitCoin,
253259
outputValues,
260+
random,
254261
uniqueOutputAssetIDs,
255-
utxoSelection: pickExtraRandomUtxo(utxoSelection)
262+
utxoSelection: pickExtraRandomUtxo(utxoSelection, random)
256263
});
257264
}
258265
// This is not a great error type for this, because the spec says
@@ -294,12 +301,14 @@ export const computeChangeAndAdjustForFee = async ({
294301
outputValues,
295302
uniqueOutputAssetIDs,
296303
implicitCoin,
304+
random,
297305
utxoSelection
298306
}: ChangeComputationArgs): Promise<ChangeComputationResult> => {
299307
const changeInclFee = computeChangeBundles({
300308
computeMinimumCoinQuantity,
301309
implicitCoin,
302310
outputValues,
311+
random,
303312
uniqueOutputAssetIDs,
304313
utxoSelection
305314
});
@@ -325,9 +334,10 @@ export const computeChangeAndAdjustForFee = async ({
325334
estimateTxFee,
326335
implicitCoin,
327336
outputValues,
337+
random,
328338
tokenBundleSizeExceedsLimit,
329339
uniqueOutputAssetIDs,
330-
utxoSelection: pickExtraRandomUtxo(changeInclFee)
340+
utxoSelection: pickExtraRandomUtxo(changeInclFee, random)
331341
});
332342
}
333343

@@ -336,6 +346,7 @@ export const computeChangeAndAdjustForFee = async ({
336346
fee,
337347
implicitCoin,
338348
outputValues,
349+
random,
339350
uniqueOutputAssetIDs,
340351
utxoSelection: { utxoRemaining: changeInclFee.utxoRemaining, utxoSelected: changeInclFee.utxoSelected }
341352
});

Diff for: packages/cip2/src/RoundRobinRandomImprove/index.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ import { computeChangeAndAdjustForFee } from './change';
55
import { cslUtil } from '@cardano-sdk/core';
66
import { roundRobinSelection } from './roundRobin';
77

8-
export const roundRobinRandomImprove = (): InputSelector => ({
8+
interface RoundRobinRandomImproveOptions {
9+
random?: typeof Math.random;
10+
}
11+
12+
export const roundRobinRandomImprove = ({
13+
random = Math.random
14+
}: RoundRobinRandomImproveOptions = {}): InputSelector => ({
915
select: async ({
1016
utxo: utxoSet,
1117
outputs: outputSet,
@@ -23,6 +29,7 @@ export const roundRobinRandomImprove = (): InputSelector => ({
2329
const roundRobinSelectionResult = roundRobinSelection({
2430
implicitCoin,
2531
outputs,
32+
random,
2633
uniqueOutputAssetIDs,
2734
utxo
2835
});
@@ -38,6 +45,7 @@ export const roundRobinRandomImprove = (): InputSelector => ({
3845
}),
3946
implicitCoin,
4047
outputValues: toValues(outputs),
48+
random,
4149
tokenBundleSizeExceedsLimit,
4250
uniqueOutputAssetIDs,
4351
utxoSelection: roundRobinSelectionResult

Diff for: packages/cip2/src/RoundRobinRandomImprove/roundRobin.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export const roundRobinSelection = ({
6666
utxo: utxosWithValue,
6767
outputs: outputsWithValue,
6868
uniqueOutputAssetIDs,
69+
random,
6970
implicitCoin
7071
}: RoundRobinRandomImproveArgs): UtxoSelection => {
7172
// The subset of the UTxO that has already been selected:
@@ -81,7 +82,7 @@ export const roundRobinSelection = ({
8182
// this token from the remaining UTxO set:
8283
const utxo = filterUtxo(utxoRemaining);
8384
if (utxo.length > 0) {
84-
const inputIdx = Math.floor(Math.random() * utxo.length);
85+
const inputIdx = Math.floor(random() * utxo.length);
8586
const input = utxo[inputIdx];
8687
if (improvesSelection(utxoSelected, input, minimumTarget, getTotalSelectedQuantity)) {
8788
utxoSelected.push(input);

Diff for: packages/cip2/src/RoundRobinRandomImprove/util.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export interface RoundRobinRandomImproveArgs {
88
outputs: Cardano.TxOut[];
99
uniqueOutputAssetIDs: Cardano.AssetId[];
1010
implicitCoin: Required<Cardano.ImplicitCoin>;
11+
random: typeof Math.random;
1112
}
1213

1314
export interface UtxoSelection {
@@ -24,7 +25,7 @@ export const preprocessArgs = (
2425
availableUtxo: Set<Cardano.Utxo>,
2526
outputSet: Set<Cardano.TxOut>,
2627
partialImplicitCoin: Cardano.ImplicitCoin = noImplicitCoin
27-
): RoundRobinRandomImproveArgs => {
28+
): Omit<RoundRobinRandomImproveArgs, 'random'> => {
2829
const outputs = [...outputSet];
2930
const uniqueOutputAssetIDs = uniq(outputs.flatMap(({ value: { assets } }) => [...(assets?.keys() || [])]));
3031
const implicitCoin: Required<Cardano.ImplicitCoin> = {

0 commit comments

Comments
 (0)