Skip to content

Commit c9c38f0

Browse files
OttoAllmendingerllm-git
andcommitted
feat(utxo-staking): add test case demonstrating bug #71
This adds a test case to demonstrate an issue where bitcoinjs-lib incorrectly allows finalization of an invalid transaction. Shows that the following systems correctly reject the transaction: * utxolib * wasm-miniscript * bitcoind Issue: BTC-71 Co-authored-by: llm-git <[email protected]>
1 parent cebc992 commit c9c38f0

File tree

1 file changed

+79
-0
lines changed
  • modules/utxo-staking/test/unit/babylon

1 file changed

+79
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import * as fs from 'fs';
2+
import assert from 'assert';
3+
4+
import * as bitcoinjs from 'bitcoinjs-lib';
5+
import * as utxolib from '@bitgo/utxo-lib';
6+
import * as wasmMiniscript from '@bitgo/wasm-miniscript';
7+
8+
// demonstrate https://github.com/babylonlabs-io/btc-staking-ts/issues/71
9+
describe('btc-staking-ts bug #71', function () {
10+
let buf: Buffer;
11+
before('load half-signed transaction', async function () {
12+
const fixture = JSON.parse(
13+
await fs.promises.readFile(__dirname + '/../../fixtures/babylon/txTree.testnet.json', 'utf-8')
14+
);
15+
const base64 = fixture.slashingSignedBase64;
16+
assert(typeof base64 === 'string');
17+
buf = Buffer.from(base64, 'base64');
18+
});
19+
20+
it('can finalize with bitcoinjs-lib', function () {
21+
const psbt = bitcoinjs.Psbt.fromBuffer(buf);
22+
// this does not throw because of a bug in bitcoinjs-lib
23+
psbt.finalizeAllInputs();
24+
});
25+
26+
it('cannot finalize with utxolib', function () {
27+
const psbt = utxolib.Psbt.fromBuffer(buf);
28+
assert.throws(() => {
29+
psbt.finalizeAllInputs();
30+
}, /Error: Can not finalize input #0/);
31+
});
32+
33+
it('cannot finalize with wasm-miniscript', function () {
34+
const psbt = wasmMiniscript.Psbt.deserialize(buf);
35+
assert.throws(() => {
36+
psbt.finalize();
37+
}, /CouldNotSatisfyTr/);
38+
});
39+
40+
it('cannot finalize with bitcoind', async function (this: Mocha.Context) {
41+
let cookie: string;
42+
try {
43+
cookie = await fs.promises.readFile(process.env.HOME + '/.bitcoin/regtest/.cookie', 'utf-8');
44+
} catch (e) {
45+
if (e.code === 'ENOENT') {
46+
console.log('No cookie file found, skipping test');
47+
this.skip();
48+
}
49+
throw e;
50+
}
51+
// make regtest JSON-RPC request with cookie
52+
const url = 'http://localhost:18443';
53+
const headers = {
54+
'Content-Type': 'application/json',
55+
Authorization: 'Basic ' + Buffer.from(cookie, 'utf-8').toString('base64'),
56+
};
57+
58+
// Create the request payload for finalizepsbt RPC call
59+
const body = JSON.stringify({
60+
jsonrpc: '1.0',
61+
id: 'bitgo-test',
62+
method: 'finalizepsbt',
63+
params: [buf.toString('base64')],
64+
});
65+
66+
// Make the RPC request
67+
const response = await fetch(url, {
68+
method: 'POST',
69+
headers,
70+
body,
71+
});
72+
73+
assert.deepStrictEqual((await response.json()).result, {
74+
// the response psbt is the same as the input psbt - not finalized
75+
psbt: buf.toString('base64'),
76+
complete: false,
77+
});
78+
});
79+
});

0 commit comments

Comments
 (0)