mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-23 15:20:55 +01:00
Merge pull request #3134 from BlueWallet/fix-better-utxo-selection
REF: smarter utxo selection (closes #3085)
This commit is contained in:
commit
7e99b5b7fe
4 changed files with 47 additions and 6 deletions
|
@ -5,7 +5,7 @@ import { AbstractWallet } from './abstract-wallet';
|
|||
import { HDSegwitBech32Wallet } from '..';
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
const BlueElectrum = require('../../blue_modules/BlueElectrum');
|
||||
const coinSelectAccumulative = require('coinselect/accumulative');
|
||||
const coinSelect = require('coinselect');
|
||||
const coinSelectSplit = require('coinselect/split');
|
||||
|
||||
/**
|
||||
|
@ -337,7 +337,7 @@ export class LegacyWallet extends AbstractWallet {
|
|||
coinselect(utxos, targets, feeRate, changeAddress) {
|
||||
if (!changeAddress) throw new Error('No change address provided');
|
||||
|
||||
let algo = coinSelectAccumulative;
|
||||
let algo = coinSelect;
|
||||
// if targets has output without a value, we want send MAX to it
|
||||
if (targets.some(i => !('value' in i))) {
|
||||
algo = coinSelectSplit;
|
||||
|
|
|
@ -528,7 +528,7 @@ describe('BlueWallet UI Tests', () => {
|
|||
await yo('TransactionValue');
|
||||
expect(element(by.id('TransactionValue'))).toHaveText('0.0001');
|
||||
const transactionFee = await extractTextFromElementById('TransactionFee');
|
||||
assert.ok(transactionFee.startsWith('Fee: 0.00000748 BTC'), 'Unexpected tx fee: ' + transactionFee);
|
||||
assert.ok(transactionFee.startsWith('Fee: 0.00000452 BTC'), 'Unexpected tx fee: ' + transactionFee);
|
||||
await element(by.id('TransactionDetailsButton')).tap();
|
||||
|
||||
let txhex = await extractTextFromElementById('TxhexInput');
|
||||
|
@ -540,7 +540,7 @@ describe('BlueWallet UI Tests', () => {
|
|||
assert.strictEqual(transaction.outs[0].value, 10000);
|
||||
|
||||
// checking fee rate:
|
||||
const totalIns = 100000 + 5526; // we hardcode it since we know it in advance
|
||||
const totalIns = 100000; // we hardcode it since we know it in advance
|
||||
const totalOuts = transaction.outs.map(el => el.value).reduce((a, b) => a + b, 0);
|
||||
assert.strictEqual(Math.round((totalIns - totalOuts) / (txhex.length / 2)), feeRate);
|
||||
assert.strictEqual(transactionFee.split(' ')[1] * 100000000, totalIns - totalOuts);
|
||||
|
|
|
@ -110,10 +110,10 @@ describe('Legacy HD (BIP44)', () => {
|
|||
hd._getInternalAddressByIndex(hd.next_free_change_address_index),
|
||||
);
|
||||
let tx = bitcoin.Transaction.fromHex(txNew.tx.toHex());
|
||||
assert.strictEqual(tx.ins.length, 4);
|
||||
assert.strictEqual(tx.ins.length, 3);
|
||||
assert.strictEqual(tx.outs.length, 2);
|
||||
assert.strictEqual(tx.outs[0].value, 80000); // payee
|
||||
assert.strictEqual(tx.outs[1].value, 19330); // change
|
||||
assert.strictEqual(tx.outs[1].value, 9478); // change
|
||||
let toAddress = bitcoin.address.fromOutputScript(tx.outs[0].script);
|
||||
const changeAddress = bitcoin.address.fromOutputScript(tx.outs[1].script);
|
||||
assert.strictEqual('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', toAddress);
|
||||
|
|
|
@ -53,6 +53,47 @@ describe('Legacy wallet', () => {
|
|||
assert.strictEqual('bc1q3rl0mkyk0zrtxfmqn9wpcd3gnaz00yv9yp0hxe', bitcoin.address.fromOutputScript(tx.outs[1].script)); // to address
|
||||
});
|
||||
|
||||
it('can create transaction with better UTXO selection', async () => {
|
||||
const l = new LegacyWallet();
|
||||
l.setSecret('L4ccWrPMmFDZw4kzAKFqJNxgHANjdy6b7YKNXMwB4xac4FLF3Tov');
|
||||
|
||||
const utxos = [
|
||||
{
|
||||
txid: 'cc44e933a094296d9fe424ad7306f16916253a3d154d52e4f1a757c18242cec4',
|
||||
vout: 0,
|
||||
value: 1000,
|
||||
txhex:
|
||||
'0200000000010161890cd52770c150da4d7d190920f43b9f88e7660c565a5a5ad141abb6de09de00000000000000008002a0860100000000001976a91426e01119d265aa980390c49eece923976c218f1588ac3e17000000000000160014c1af8c9dd85e0e55a532a952282604f820746fcd02473044022072b3f28808943c6aa588dd7a4e8f29fad7357a2814e05d6c5d767eb6b307b4e6022067bc6a8df2dbee43c87b8ce9ddd9fe678e00e0f7ae6690d5cb81eca6170c47e8012102e8fba5643e15ab70ec79528833a2c51338c1114c4eebc348a235b1a3e13ab07100000000',
|
||||
},
|
||||
{
|
||||
txid: 'cc44e933a094296d9fe424ad7306f16916253a3d154d52e4f1a757c18242cec4',
|
||||
vout: 1,
|
||||
value: 1000,
|
||||
txhex:
|
||||
'0200000000010161890cd52770c150da4d7d190920f43b9f88e7660c565a5a5ad141abb6de09de00000000000000008002a0860100000000001976a91426e01119d265aa980390c49eece923976c218f1588ac3e17000000000000160014c1af8c9dd85e0e55a532a952282604f820746fcd02473044022072b3f28808943c6aa588dd7a4e8f29fad7357a2814e05d6c5d767eb6b307b4e6022067bc6a8df2dbee43c87b8ce9ddd9fe678e00e0f7ae6690d5cb81eca6170c47e8012102e8fba5643e15ab70ec79528833a2c51338c1114c4eebc348a235b1a3e13ab07100000000',
|
||||
},
|
||||
|
||||
{
|
||||
txid: 'cc44e933a094296d9fe424ad7306f16916253a3d154d52e4f1a757c18242cec4',
|
||||
vout: 2,
|
||||
value: 69000000,
|
||||
txhex:
|
||||
'0200000000010161890cd52770c150da4d7d190920f43b9f88e7660c565a5a5ad141abb6de09de00000000000000008002a0860100000000001976a91426e01119d265aa980390c49eece923976c218f1588ac3e17000000000000160014c1af8c9dd85e0e55a532a952282604f820746fcd02473044022072b3f28808943c6aa588dd7a4e8f29fad7357a2814e05d6c5d767eb6b307b4e6022067bc6a8df2dbee43c87b8ce9ddd9fe678e00e0f7ae6690d5cb81eca6170c47e8012102e8fba5643e15ab70ec79528833a2c51338c1114c4eebc348a235b1a3e13ab07100000000',
|
||||
},
|
||||
];
|
||||
// ^^ only non-segwit inputs need full transaction txhex
|
||||
|
||||
const { psbt } = l.createTransaction(
|
||||
utxos,
|
||||
[{ value: 60000000, address: '1GX36PGBUrF8XahZEGQqHqnJGW2vCZteoB' }],
|
||||
1,
|
||||
l.getAddress(),
|
||||
0,
|
||||
true,
|
||||
);
|
||||
assert.strictEqual(psbt.data.inputs.length, 1);
|
||||
});
|
||||
|
||||
it("throws error if you can't create wallet from this entropy", async () => {
|
||||
const l = new LegacyWallet();
|
||||
const zeroes = [...Array(32)].map(() => 0);
|
||||
|
|
Loading…
Add table
Reference in a new issue