Skip to content

Commit

Permalink
Adaptations in Weight Calculation Methods
Browse files Browse the repository at this point in the history
This update ensure that `@bitcoinerlab/coinselect` takes full advantage of the recent improvements in the `@bitcoinerlab/descriptors` package, particularly the new weight calculation methods. This alignment enhances the performance of coin selection and transaction size estimation since it now relies on smarter caching strategies implemented in `@bitcoinerlab/descriptors`.

It aligns with the recent enhancements and new functionalities in weight calculation methods introduced in `@bitcoinerlab/descriptors` ([PR #32](bitcoinerlab/descriptors#32)).

**Key Changes:**
1. **Package Version and Dependencies:**
   - Upgraded `@bitcoinerlab/coinselect` from version `1.1.0` to `1.2.0`.
   - Updated the dependency on `@bitcoinerlab/descriptors` to version `2.1.0` to leverage the latest enhancements.

2. **Code Refactoring:**
   - Removed local implementations of weight calculations (`inputWeight` and `outputWeight`) and replaced them with the updated methods from `@bitcoinerlab/descriptors`.
   - Simplified and streamlined the code by removing redundant functions and logic, relying on the improved functionalities in the `descriptors` package.

3. **Validation and Dust Calculation Adjustments:**
   - Updated the validation logic to incorporate changes in dust calculation and fee rate validation.
   - Ensured compatibility with the new weight calculation methods in handling UTXOs and transaction outputs.

4. **Test Suite Enhancements:**
   - Revised test cases to align with the updated logic and methods.

Updates and modifications have been appropriately commented and documented within the code.
  • Loading branch information
landabaso committed Dec 9, 2023
1 parent 0381888 commit e33e200
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 330 deletions.
36 changes: 25 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bitcoinerlab/coinselect",
"version": "1.1.0",
"version": "1.2.0",
"author": "Jose-Luis Landabaso",
"license": "MIT",
"description": "A TypeScript library for Bitcoin transaction management, based on Bitcoin Descriptors for defining inputs and outputs. It facilitates optimal UTXO selection and transaction size calculation.",
Expand Down Expand Up @@ -52,6 +52,6 @@
"regtest-client": "^0.2.1"
},
"dependencies": {
"@bitcoinerlab/descriptors": "^2.0.3"
"@bitcoinerlab/descriptors": "^2.1.0"
}
}
4 changes: 3 additions & 1 deletion src/algos/maxFunds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { DUST_RELAY_FEE_RATE, OutputWithValue } from '../index';
import {
validateFeeRate,
validateOutputWithValues,
validateDust,
validatedFeeAndVsize
} from '../validation';
import { vsize } from '../vsize';
Expand Down Expand Up @@ -38,7 +39,8 @@ export function maxFunds({
dustRelayFeeRate?: number;
}) {
validateOutputWithValues(utxos);
targets.length === 0 || validateOutputWithValues(targets);
if (targets.length) validateOutputWithValues(targets);
validateDust(targets);
validateFeeRate(feeRate);
validateFeeRate(dustRelayFeeRate);

Expand Down
10 changes: 7 additions & 3 deletions src/coinselect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import {
} from './validation';
import { addUntilReach } from './algos/addUntilReach';
import { avoidChange } from './algos/avoidChange';
import { inputWeight } from './vsize';
import { isSegwitTx } from './segwit';
import { isSegwitTx } from './vsize';

// order by descending value, minus the inputs approximate fee
function utxoTransferredValue(
Expand All @@ -19,7 +18,12 @@ function utxoTransferredValue(
) {
return (
outputAndValue.value -
(feeRate * inputWeight(outputAndValue.output, isSegwitTx)) / 4
(feeRate *
outputAndValue.output.inputWeight(
isSegwitTx,
'DANGEROUSLY_USE_FAKE_SIGNATURES'
)) /
4
);
}

Expand Down
12 changes: 8 additions & 4 deletions src/dust.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import type { OutputInstance } from '@bitcoinerlab/descriptors';
import { inputWeight, outputWeight } from './vsize';
import { isSegwit } from './segwit';
import { DUST_RELAY_FEE_RATE } from './index';

/**
Expand Down Expand Up @@ -52,11 +50,17 @@ export function dustThreshold(
*/
dustRelayFeeRate: number = DUST_RELAY_FEE_RATE
) {
const isSegwitOutput = isSegwit(output);
const isSegwitOutput = output.isSegwit();
if (isSegwitOutput === undefined) throw new Error(`Unknown output type`);
return Math.ceil(
dustRelayFeeRate *
Math.ceil(
(outputWeight(output) + inputWeight(output, isSegwitOutput)) / 4
(output.outputWeight() +
output.inputWeight(
isSegwitOutput,
'DANGEROUSLY_USE_FAKE_SIGNATURES'
)) /
4
)
);
}
Expand Down
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import type { OutputInstance } from '@bitcoinerlab/descriptors';
export { coinselect } from './coinselect';
export { vsize } from './vsize';
export { dustThreshold } from './dust';
export { inputWeight, outputWeight } from './vsize';
export { maxFunds } from './algos/maxFunds';
export { addUntilReach } from './algos/addUntilReach';
export { avoidChange } from './algos/avoidChange';
Expand Down
57 changes: 0 additions & 57 deletions src/segwit.ts

This file was deleted.

8 changes: 6 additions & 2 deletions src/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,13 @@ export function validatedFeeAndVsize(
targets.map(t => t.output)
);
const finalFeeRate = fee / vsizeResult;
if (finalFeeRate < feeRate)
// Don't compare fee rates because values are picked based on comparing fees (multiplications)
// Don't mix * / operators:
// F.ex.: 100/27 !== 100*(1/27)
// Instead, compare final fee
if (fee < Math.ceil(vsizeResult * feeRate))
throw new Error(
`Final fee rate ${finalFeeRate} lower than required ${feeRate}`
`Final fee ${fee} lower than required ${Math.ceil(vsizeResult * feeRate)}`
);
validateFeeRate(finalFeeRate);
return { fee, vsize: vsizeResult };
Expand Down
Loading

0 comments on commit e33e200

Please sign in to comment.