Skip to content
This repository has been archived by the owner on Mar 16, 2023. It is now read-only.

Commit

Permalink
feat(sdk): let the sdk pick random number of notes if null
Browse files Browse the repository at this point in the history
  • Loading branch information
LeilaWang committed Feb 13, 2020
1 parent 4d13706 commit 0bcb489
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 35 deletions.
Expand Up @@ -6,7 +6,7 @@ export default function pickNotesFromBalanceQuery(requestedFields) {
$assetId: String!,
$amount: Int!,
$owner: String!,
$numberOfNotes: Int!
$numberOfNotes: Int
$domain: String!
$currentAddress: String!
) {
Expand Down
@@ -1,7 +1,6 @@
import asyncMap from '~/utils/asyncMap';
import NoteService from '~/background/services/NoteService';
import Web3Service from '~/helpers/Web3Service';
import settings from '~/background/utils/settings';
import getViewingKeyFromMetadata from './getViewingKeyFromMetadata';

export default async function pickNotesFromBalance(args) {
Expand All @@ -24,7 +23,7 @@ export default async function pickNotesFromBalance(args) {
assetId,
amount,
{
numberOfNotes: numberOfNotes || await settings('NUMBER_OF_INPUT_NOTES'),
numberOfNotes,
},
);

Expand Down
@@ -1,8 +1,12 @@
import expectErrorResponse from '~testHelpers/expectErrorResponse';
import {
NUMBER_OF_INPUT_NOTES,
} from '~/config/settings';
import generateSortedValues from '../utils/generateSortedValues';
import pickNotes from '../utils/pickNotes';
import getStartIndex from '../utils/pickNotes/getStartIndex';
import pickKeysByValues from '../utils/pickNotes/pickKeysByValues';
import * as validate from '../utils/pickNotes/validate';
import * as pickValues from '../utils/pickNotes/pickValues';

describe('getStartIndex', () => {
Expand Down Expand Up @@ -107,6 +111,43 @@ describe('pickNotes', () => {
]);
});

it('pick random number of notes if numberOfNotes is not undefined', () => {
const validateSpy = jest.spyOn(validate, 'default');

const noteValues = {
0: ['n:1'],
1: ['n:2'],
2: ['n:3'],
4: ['n:6'],
8: ['n:4'],
};
const sortedValues = generateSortedValues(noteValues);

const notes1 = pickNotes({
noteValues,
sortedValues,
minSum: 6,
});
expect(NUMBER_OF_INPUT_NOTES >= 2).toBe(true);
expect(notes1.length).toBe(NUMBER_OF_INPUT_NOTES);
expect(validateSpy).toHaveBeenCalledTimes(1);

const notes2 = pickNotes({
noteValues,
sortedValues,
minSum: 13,
});
expect(notes2.length >= 3).toBe(true);
expect(validateSpy).toHaveBeenCalledTimes(3);

const notes3 = pickNotes({
noteValues,
sortedValues,
minSum: 15,
});
expect(notes3.length >= 4).toBe(true);
});

it('throw error if there is no note combinations >= min sum', () => {
expectErrorResponse(() => pickNotes({
noteValues: {
Expand Down
10 changes: 5 additions & 5 deletions packages/extension/src/background/services/NoteService/index.js
Expand Up @@ -52,11 +52,11 @@ export default {
assetId,
minSum,
{
numberOfNotes = 1,
numberOfNotes = null,
allowLessNumberOfNotes = true,
} = {},
) => {
if (numberOfNotes <= 0) {
if (numberOfNotes !== null && numberOfNotes <= 0) {
return null;
}

Expand All @@ -71,7 +71,7 @@ export default {
if (balance < minSum) {
return argsError('note.pick.sum', {
messageOptions: {
count: numberOfNotes,
count: numberOfNotes || '',
},
balance,
numberOfNotes,
Expand Down Expand Up @@ -101,11 +101,11 @@ export default {
assetId,
minSum,
{
numberOfNotes = 1,
numberOfNotes = null,
allowLessNumberOfNotes = true,
} = {},
) => {
if (numberOfNotes <= 0) {
if (numberOfNotes !== null && numberOfNotes <= 0) {
return [];
}

Expand Down
@@ -1,3 +1,9 @@
import {
NUMBER_OF_INPUT_NOTES,
} from '~/config/settings';
import {
randomInt,
} from '~/utils/random';
import validate from './validate';
import getStartIndex from './getStartIndex';
import pickValues from './pickValues';
Expand All @@ -8,19 +14,32 @@ export default function pickNotes({
sortedValues,
noteValues,
minSum,
numberOfNotes: count = 1,
numberOfNotes = null,
allowLessNumberOfNotes = true,
}) {
if (!count) {
if (numberOfNotes !== null && numberOfNotes <= 0) {
return [];
}

validate({
sortedValues,
minSum,
numberOfNotes: count,
allowLessNumberOfNotes,
});
let count = numberOfNotes || NUMBER_OF_INPUT_NOTES;
while (count > 0) {
try {
validate({
sortedValues,
minSum,
numberOfNotes: count,
allowLessNumberOfNotes,
});
break;
} catch (error) {
count += randomInt(1, NUMBER_OF_INPUT_NOTES);
if (numberOfNotes !== null
|| count > sortedValues.length
) {
throw error;
}
}
}

if (sortedValues.length < count) {
const notes = [];
Expand Down
Expand Up @@ -6,19 +6,18 @@ import arraySum from './arraySum';
export default function validate({
sortedValues,
minSum,
numberOfNotes,
numberOfNotes = null,
allowLessNumberOfNotes = true,
}) {
if (!numberOfNotes) {
return [];
}

const maxSet = sortedValues.slice(-numberOfNotes);
const count = numberOfNotes === null
? sortedValues.length
: numberOfNotes;
const maxSet = sortedValues.slice(-count);
const maxSum = arraySum(maxSet);
if (minSum > maxSum) {
throw argsError('note.pick.minSum', {
messageOptions: {
count: numberOfNotes,
count: numberOfNotes || '',
},
numberOfNotes,
value: minSum,
Expand All @@ -30,7 +29,7 @@ export default function validate({
) {
throw argsError('note.pick.count', {
messageOptions: {
count: numberOfNotes,
count: numberOfNotes || '',
},
numberOfNotes,
totalNotes: sortedValues.length,
Expand Down
2 changes: 1 addition & 1 deletion packages/extension/src/config/settings.js
@@ -1,5 +1,5 @@
export const NOTES_PER_SYNC_REQUEST = 10;
export const SYNC_INTERVAL = 2000;

export const NUMBER_OF_INPUT_NOTES = 5;
export const NUMBER_OF_INPUT_NOTES = 2;
export const NUMBER_OF_OUTPUT_NOTES = 2;
Expand Up @@ -51,7 +51,7 @@ export default async function createNoteFromBalance({

const numberOfInputNotes = !Object.is(customNumberOfInputNotes, emptyIntValue)
? customNumberOfInputNotes
: await settings('NUMBER_OF_INPUT_NOTES');
: undefined;

const numberOfOutputNotes = !Object.is(customNumberOfOutputNotes, emptyIntValue)
? customNumberOfOutputNotes
Expand Down
11 changes: 2 additions & 9 deletions packages/extension/src/ui/pages/CreateNoteFromBalance.jsx
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import settings from '~/background/utils/settings';
import {
valueOf,
} from '~/utils/note';
Expand Down Expand Up @@ -42,8 +41,8 @@ const CreateNoteFromBalance = ({
currentAccount,
assetAddress,
amount: inputAmount,
numberOfInputNotes: customNumberOfInputNotes,
numberOfOutputNotes: customNumberOfOutputNotes,
numberOfInputNotes,
numberOfOutputNotes,
userAccess,
}) => {
const {
Expand All @@ -64,12 +63,6 @@ const CreateNoteFromBalance = ({
: [];
const sender = isGSNAvailable ? proxyContract : currentAddress;
const amount = parseInputAmount(inputAmount);
const numberOfInputNotes = !Object.is(customNumberOfInputNotes, emptyIntValue)
? customNumberOfInputNotes
: await settings('NUMBER_OF_INPUT_NOTES');
const numberOfOutputNotes = !Object.is(customNumberOfOutputNotes, emptyIntValue)
? customNumberOfOutputNotes
: await settings('NUMBER_OF_OUTPUT_NOTES');
const transactions = [
{
amount,
Expand Down

0 comments on commit 0bcb489

Please sign in to comment.