From c8cbcf650cdd35645a169e8e097322b0b96a36d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Landabaso=20D=C3=ADaz?= Date: Fri, 20 Sep 2024 14:25:48 +0200 Subject: [PATCH 1/2] fix: prevent throwing on duplicate txIds during descriptor update in discovery This fix removes the error thrown when a `txId` has already been pushed or is part of the discovery object. Instead of throwing, it now checks whether the `txId` is already present in the `outputData.txIds` array and only pushes the `txId` if it's not already included. This prevents from throwing when auto-sending to owned outputs. --- package-lock.json | 94 ++++++++++++++++++----------------------------- package.json | 6 +-- src/discovery.ts | 8 ++-- 3 files changed, 41 insertions(+), 67 deletions(-) diff --git a/package-lock.json b/package-lock.json index 23a689f..50a3541 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "@bitcoinerlab/discovery", - "version": "1.2.5", + "version": "1.2.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@bitcoinerlab/discovery", - "version": "1.2.5", + "version": "1.2.6", "license": "MIT", "dependencies": { - "@bitcoinerlab/descriptors": "^2.1.0", - "@bitcoinerlab/explorer": "^0.3.0", + "@bitcoinerlab/descriptors": "^2.2.0", + "@bitcoinerlab/explorer": "^0.3.2", "@bitcoinerlab/secp256k1": "^1.1.1", "@types/memoizee": "^0.4.8", "bitcoinjs-lib": "^6.1.5", @@ -745,12 +745,12 @@ } }, "node_modules/@bitcoinerlab/descriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@bitcoinerlab/descriptors/-/descriptors-2.1.0.tgz", - "integrity": "sha512-VSdw07ASLfs3HZzTW4D65ONpSUOstGVhYuEq6bGTW0RexVHwgh90Cr0L53e/Uh+U7uwhjPgUhCXcTgSlvoXPeA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@bitcoinerlab/descriptors/-/descriptors-2.2.0.tgz", + "integrity": "sha512-z9GOZYT5jO8oE4aq8XF0czGW1W9JrJXdslUaCfUMEMo5KnygKZhOFXZCHEvtdrEXBACURh1+b/MVhy3pH9Pi7g==", "dependencies": { - "@bitcoinerlab/miniscript": "^1.2.1", - "@bitcoinerlab/secp256k1": "^1.0.5", + "@bitcoinerlab/miniscript": "^1.4.0", + "@bitcoinerlab/secp256k1": "^1.1.1", "bip32": "^4.0.0", "bitcoinjs-lib": "^6.1.3", "ecpair": "^2.1.0", @@ -767,14 +767,12 @@ } }, "node_modules/@bitcoinerlab/explorer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@bitcoinerlab/explorer/-/explorer-0.3.0.tgz", - "integrity": "sha512-Inw106HLfvF8H7xWeKbLvFJy9zm0vH+MiE+cVpdUI2Hvo4BpSR1ovjfN8iWIFMAdXSUdjb65RehjK37KKdp2+w==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@bitcoinerlab/explorer/-/explorer-0.3.2.tgz", + "integrity": "sha512-tqApM8ywwFHuoah/VrmA+wdWwOpXy1h+zC3rt+jowc5nHz5RjjaqPllP10nimNYCMSCoG8hBTT15pg8iKgL4aQ==", "dependencies": { "bitcoinjs-lib": "^6.1.3", - "electrum-client": "github:BlueWallet/rn-electrum-client#47acb51149e97fab249c3f8a314f708dbee4fb6e", - "net": "^1.0.2", - "tls": "^0.0.1" + "electrum-client": "github:BlueWallet/rn-electrum-client#1bfe3cc4249d5440b816baac942b0cfa921eebf9" } }, "node_modules/@bitcoinerlab/miniscript": { @@ -1395,9 +1393,9 @@ } }, "node_modules/@scure/base": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.7.tgz", - "integrity": "sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", "funding": { "url": "https://paulmillr.com/funding/" } @@ -2707,12 +2705,12 @@ "dev": true }, "node_modules/electrum-client": { - "version": "2.0.0", - "resolved": "git+ssh://git@github.com/BlueWallet/rn-electrum-client.git#47acb51149e97fab249c3f8a314f708dbee4fb6e", - "integrity": "sha512-u5KKZ1eMRPhi5jZB9l1pNUGN4SKVk+Cv0iCMvIaJOLYGabMzMY+lAVzOioxRIueqBvdQgM20kymw+T0JTw6GUQ==", + "version": "3.1.0", + "resolved": "git+ssh://git@github.com/BlueWallet/rn-electrum-client.git#1bfe3cc4249d5440b816baac942b0cfa921eebf9", + "integrity": "sha512-91uT4Ty4YNYvmxgmF3p+GCdygbXrsReFwVpIbkk+GQ2uUNRwUeQwVr8dK/GvnQbRbdk4euQuKubaju3mdQR+SQ==", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=18" } }, "node_modules/emittery": { @@ -4696,11 +4694,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/net": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/net/-/net-1.0.2.tgz", - "integrity": "sha512-kbhcj2SVVR4caaVnGLJKmlk2+f+oLkjqdKeQlmUtz6nGzOpbcobwVIeSURNgraV/v3tlmGIX82OcPCl0K6RbHQ==" - }, "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -5631,11 +5624,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tls": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tls/-/tls-0.0.1.tgz", - "integrity": "sha512-GzHpG+hwupY8VMR6rYsnAhTHqT/97zT45PG8WD5eTT1lq+dFE0nN+1PYpsoBcHJgSmTz5ceK2Cv88IkPmIPOtQ==" - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -6558,12 +6546,12 @@ } }, "@bitcoinerlab/descriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@bitcoinerlab/descriptors/-/descriptors-2.1.0.tgz", - "integrity": "sha512-VSdw07ASLfs3HZzTW4D65ONpSUOstGVhYuEq6bGTW0RexVHwgh90Cr0L53e/Uh+U7uwhjPgUhCXcTgSlvoXPeA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@bitcoinerlab/descriptors/-/descriptors-2.2.0.tgz", + "integrity": "sha512-z9GOZYT5jO8oE4aq8XF0czGW1W9JrJXdslUaCfUMEMo5KnygKZhOFXZCHEvtdrEXBACURh1+b/MVhy3pH9Pi7g==", "requires": { - "@bitcoinerlab/miniscript": "^1.2.1", - "@bitcoinerlab/secp256k1": "^1.0.5", + "@bitcoinerlab/miniscript": "^1.4.0", + "@bitcoinerlab/secp256k1": "^1.1.1", "bip32": "^4.0.0", "bitcoinjs-lib": "^6.1.3", "ecpair": "^2.1.0", @@ -6572,14 +6560,12 @@ } }, "@bitcoinerlab/explorer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@bitcoinerlab/explorer/-/explorer-0.3.0.tgz", - "integrity": "sha512-Inw106HLfvF8H7xWeKbLvFJy9zm0vH+MiE+cVpdUI2Hvo4BpSR1ovjfN8iWIFMAdXSUdjb65RehjK37KKdp2+w==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@bitcoinerlab/explorer/-/explorer-0.3.2.tgz", + "integrity": "sha512-tqApM8ywwFHuoah/VrmA+wdWwOpXy1h+zC3rt+jowc5nHz5RjjaqPllP10nimNYCMSCoG8hBTT15pg8iKgL4aQ==", "requires": { "bitcoinjs-lib": "^6.1.3", - "electrum-client": "github:BlueWallet/rn-electrum-client#47acb51149e97fab249c3f8a314f708dbee4fb6e", - "net": "^1.0.2", - "tls": "^0.0.1" + "electrum-client": "github:BlueWallet/rn-electrum-client#1bfe3cc4249d5440b816baac942b0cfa921eebf9" } }, "@bitcoinerlab/miniscript": { @@ -7053,9 +7039,9 @@ } }, "@scure/base": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.7.tgz", - "integrity": "sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==" + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==" }, "@sinclair/typebox": { "version": "0.27.8", @@ -8014,9 +8000,9 @@ "dev": true }, "electrum-client": { - "version": "git+ssh://git@github.com/BlueWallet/rn-electrum-client.git#47acb51149e97fab249c3f8a314f708dbee4fb6e", - "integrity": "sha512-u5KKZ1eMRPhi5jZB9l1pNUGN4SKVk+Cv0iCMvIaJOLYGabMzMY+lAVzOioxRIueqBvdQgM20kymw+T0JTw6GUQ==", - "from": "electrum-client@github:BlueWallet/rn-electrum-client#47acb51149e97fab249c3f8a314f708dbee4fb6e" + "version": "git+ssh://git@github.com/BlueWallet/rn-electrum-client.git#1bfe3cc4249d5440b816baac942b0cfa921eebf9", + "integrity": "sha512-91uT4Ty4YNYvmxgmF3p+GCdygbXrsReFwVpIbkk+GQ2uUNRwUeQwVr8dK/GvnQbRbdk4euQuKubaju3mdQR+SQ==", + "from": "electrum-client@github:BlueWallet/rn-electrum-client#1bfe3cc4249d5440b816baac942b0cfa921eebf9" }, "emittery": { "version": "0.13.1", @@ -9482,11 +9468,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "net": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/net/-/net-1.0.2.tgz", - "integrity": "sha512-kbhcj2SVVR4caaVnGLJKmlk2+f+oLkjqdKeQlmUtz6nGzOpbcobwVIeSURNgraV/v3tlmGIX82OcPCl0K6RbHQ==" - }, "next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -10143,11 +10124,6 @@ "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", "dev": true }, - "tls": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tls/-/tls-0.0.1.tgz", - "integrity": "sha512-GzHpG+hwupY8VMR6rYsnAhTHqT/97zT45PG8WD5eTT1lq+dFE0nN+1PYpsoBcHJgSmTz5ceK2Cv88IkPmIPOtQ==" - }, "tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", diff --git a/package.json b/package.json index 54968d0..4783eb6 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@bitcoinerlab/discovery", "description": "A TypeScript library for retrieving Bitcoin funds from ranged descriptors, leveraging @bitcoinerlab/explorer for standardized access to multiple blockchain explorers.", "homepage": "https://github.com/bitcoinerlab/discovery", - "version": "1.2.5", + "version": "1.2.6", "author": "Jose-Luis Landabaso", "license": "MIT", "prettier": "@bitcoinerlab/configs/prettierConfig.json", @@ -43,8 +43,8 @@ "dist" ], "dependencies": { - "@bitcoinerlab/descriptors": "^2.1.0", - "@bitcoinerlab/explorer": "^0.3.0", + "@bitcoinerlab/descriptors": "^2.2.0", + "@bitcoinerlab/explorer": "^0.3.2", "@bitcoinerlab/secp256k1": "^1.1.1", "@types/memoizee": "^0.4.8", "bitcoinjs-lib": "^6.1.5", diff --git a/src/discovery.ts b/src/discovery.ts index 698671e..781e9c0 100644 --- a/src/discovery.ts +++ b/src/discovery.ts @@ -1342,11 +1342,9 @@ export function DiscoveryFactory( throw new Error( `unset index ${index} for descriptor ${descriptor}` ); - if (outputData.txIds.includes(txId)) - throw new Error( - `txId ${txId} was already pushed or part of the discovery object` - ); - outputData.txIds.push(txId); + //Note that update is called twice (for inputs and outputs), so + //don't push twice when auto-sending from same utxo to same output + if (!outputData.txIds.includes(txId)) outputData.txIds.push(txId); if (!txMap[txId]) txMap[txId] = txData; //Only add it once }; From 9245a5926f50645fc7304377733e7397102a4b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Landabaso=20D=C3=ADaz?= Date: Fri, 20 Sep 2024 16:21:21 +0200 Subject: [PATCH 2/2] tests: reduce rate limits on Esplora to allow passing tests on complex wallets --- test/integration/discovery.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/discovery.test.ts b/test/integration/discovery.test.ts index 0fc516b..33d89dc 100644 --- a/test/integration/discovery.test.ts +++ b/test/integration/discovery.test.ts @@ -31,6 +31,7 @@ for (const network of [networks.bitcoin]) { explorer: new EsploraExplorer({ url: 'https://blockstream.info/api/', requestQueueParams: { + maxConcurrentTasks: 10 //maxConcurrentTasks: 30 //maxConcurrentTasks: 5 //default is 10 //maxAttemptsForHardErrors: 10 //default is 5