Skip to content

Commit 1ea2143

Browse files
feat(abstract-utxo): add support for taproot in VirtualSize
Issue: BTC-1786
1 parent 898ecd8 commit 1ea2143

File tree

2 files changed

+35
-25
lines changed

2 files changed

+35
-25
lines changed

modules/abstract-utxo/src/core/descriptor/VirtualSize.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ function getScriptPubKeyLength(descType: string): number {
1717
case 'Pkh':
1818
return 25;
1919
case 'Wsh':
20-
// https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wsh
20+
case 'Tr':
21+
// P2WSH: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wsh
22+
// P2TR: https://github.com/bitcoin/bips/blob/58ffd93812ff25e87d53d1f202fbb389fdfb85bb/bip-0341.mediawiki#script-validation-rules
23+
// > A Taproot output is a native SegWit output (see BIP141) with version number 1, and a 32-byte witness program.
24+
// 32 bytes for the hash, 1 byte for the version, 1 byte for the push opcode
2125
return 34;
2226
case 'Bare':
2327
throw new Error('cannot determine scriptPubKey length for Bare descriptor');

modules/abstract-utxo/test/core/descriptor/psbt/VirtualSize.ts

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import * as assert from 'assert';
1+
import assert from 'assert';
22

33
import {
44
getChangeOutputVSizesForDescriptor,
55
getInputVSizesForDescriptors,
66
getVirtualSize,
77
} from '../../../../src/core/descriptor/VirtualSize';
8-
import { getDescriptor, getDescriptorMap } from '../descriptor.utils';
8+
import { DescriptorTemplate, getDescriptor, getDescriptorMap } from '../descriptor.utils';
99

1010
describe('VirtualSize', function () {
1111
describe('getInputVSizesForDescriptorWallet', function () {
@@ -38,29 +38,35 @@ describe('VirtualSize', function () {
3838
});
3939
});
4040

41-
describe('getVirtualSize', function () {
42-
it('returns expected virtual size', function () {
43-
assert.deepStrictEqual(
44-
getVirtualSize(
45-
{
46-
inputs: [{ descriptorName: 'internal' }],
47-
outputs: [{ script: Buffer.alloc(32) }],
48-
},
49-
getDescriptorMap('Wsh2Of3')
50-
),
51-
157
52-
);
41+
function describeWithTemplate(t: DescriptorTemplate, inputSize: number, outputSize: number) {
42+
describe(`getVirtualSize ${t}`, function () {
43+
it('returns expected virtual size', function () {
44+
assert.deepStrictEqual(
45+
getVirtualSize(
46+
{
47+
inputs: [{ descriptorName: 'internal' }],
48+
outputs: [{ script: Buffer.alloc(32) }],
49+
},
50+
getDescriptorMap(t)
51+
),
52+
outputSize
53+
);
5354

54-
const descriptor = getDescriptor('Wsh2Of3');
55+
const descriptor = getDescriptor(t);
5556

56-
assert.deepStrictEqual(
57-
getVirtualSize({
58-
/* as proof we can pass 10_000 inputs */
59-
inputs: Array.from({ length: 10_000 }).map(() => descriptor),
60-
outputs: [{ script: Buffer.alloc(32) }],
61-
}),
62-
1_050_052
63-
);
57+
const nInputs = 10_000;
58+
assert.deepStrictEqual(
59+
getVirtualSize({
60+
/* as proof we can pass 10_000 inputs */
61+
inputs: Array.from({ length: nInputs }).map(() => descriptor),
62+
outputs: [],
63+
}),
64+
inputSize * nInputs + 11
65+
);
66+
});
6467
});
65-
});
68+
}
69+
70+
describeWithTemplate('Wsh2Of3', 105, 157);
71+
describeWithTemplate('Tr2Of3-NoKeyPath', 109, 161);
6672
});

0 commit comments

Comments
 (0)