-
-
Notifications
You must be signed in to change notification settings - Fork 273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/coin control ordering #15597
Feat/coin control ordering #15597
Conversation
🚀 Expo preview is ready!
|
5640b00
to
804e338
Compare
...views/wallet/send/Options/BitcoinOptions/CoinControl/UtxoSelectionList/UtxoSelectionList.tsx
Show resolved
Hide resolved
packages/suite/src/views/wallet/send/Options/BitcoinOptions/CoinControl/CoinControl.tsx
Show resolved
Hide resolved
} | ||
|
||
const sortFromNewestToOldest = (a: AccountUtxo, b: AccountUtxo) => { | ||
let valueA: number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to get rid of the let
by doing something like this:
const sortFromNewestToOldest: UtxoSortingFunction =
({ accountTransactions }) =>
(a: AccountUtxo, b: AccountUtxo) => {
if (a.blockHeight > 0 && b.blockHeight > 0) {
return b.blockHeight - a.blockHeight;
}
// Pending transactions do not have blockHeight, so we must use blockTime of the transaction instead.
const getBlockTime = (txid: string) => {
const transaction = accountTransactions.find(transaction => transaction.txid === txid);
return transaction?.blockTime ?? 0;
};
return new BigNumber(getBlockTime(b.txid)).comparedTo(new BigNumber(getBlockTime(a.txid)));
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kept the let
s there because it just seems easier with the secondary sorting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please reconsider if you decide to refactor secondary sorting by wrapping it from outside.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have tested it and it works. Good job! However I would like to see tests for the sorting function especially the complicated on (largest/newest) + some code polishing. |
d3a5f3e
to
1d0258e
Compare
Thanks, I shamelessly stole your commits. Apologies for not using fixups :( I only made changes to the third commit, though. The changes I made:
|
1d0258e
to
587e8d1
Compare
]; | ||
|
||
describe('sortUtxos', () => { | ||
it('should sort UTXOs by newest first', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test description should not start with should
. I believe we even have it in Notion somewhere (but I am lazy to search it).
it('should sort UTXOs by newest first', () => { | |
it('sorts UTXOs by newest first', () => { |
expect(sortedUtxos).toEqual([UTXOS[0], UTXOS[2], UTXOS[1], UTXOS[3]]); | ||
}); | ||
|
||
it('should sort UTXOs by largest first', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The (unit) test shall test only one thing. And the assertion shall be done in a way, it is clearly visible what is important (the amount of transaction). This way to work with test I have to go back and forth to see what hides behind UTXOS[1]
This is what I believe is much more readable, and maintainable:
it('sorts by size, largest first', () => {
const utxos = [
testMocks.getUtxo({ amount: '1', txid: 'txid1' }),
testMocks.getUtxo({ amount: '2', txid: 'txid2' }),
];
const sortedUtxos = sortUtxos(utxos, 'largestFirst', ACCOUNT_TRANSACTIONS);
expect(sortedUtxos.map(it => it.amount)).toEqual(['2', '1']);
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I like it, but I think this is more beneficial in the expect
clause than the input where some lines can be saved: 82fc888
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general I believe that being explicit in tests and make it clear what goes in and out is more important then saving some lines.
For example: UTXOS.slice(1, 4)
gives me no insight what is the given
state of the test.
I think all tests shall follow the pattern:
given
(input of the test)when
(what is tested)then
(assert of the output)
All technical details can be hidden and abstracted, but I think the input (what is tested case), the test subject (what piece is tested), and result (what is expected result) shall be visible on the very first sight.
To saving some lines maybe this can be shorted:
const utxos = [
testMocks.getUtxo({ amount: '2', txid: 'txid2' }),
testMocks.getUtxo({ amount: '2', txid: 'txid1', vout: 1 }),
testMocks.getUtxo({ amount: '2', txid: 'txid1', vout: 0 }),
];
to something like:
const utxos = [utxo_amount2_tx2_vout1, utxo_amount2_tx1_vout1, , utxo_amount2_tx1_vout0]
But I think its marginal.
Anyway, this is not the hill to die on, but I just wanted to explain my reasoning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, your explanation makes sense. I'd prefer not to change it here now that it is done, but I'll bear it in mind next time.
packages/suite/src/utils/wallet/__tests__/utxoSortingUtils.test.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here is another suggestion aa0c473
It is a draft, feel free to use it, or not. Up to you.
Espetially tests for newestFirst
and oldestFirst
are bit messy. But I wanted to show the principles.
@peter-sanderson please check 82fc888. If you approve, I will squash it all to the third commit. |
]); | ||
}); | ||
|
||
it('should return the original array if utxoSorting is undefined', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it('should return the original array if utxoSorting is undefined', () => { | |
it('returns the original array if utxoSorting is undefined', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 GJ! 🚀
82fc888
to
c1c198b
Compare
c1c198b
to
49f7088
Compare
Description
I tried to bear performance in mind.
Related Issue
Resolve #14545
Screenshots: