Skip to content

Commit

Permalink
FIX: better bitcoinscript error handling (closes BlueWallet#2682)
Browse files Browse the repository at this point in the history
  • Loading branch information
Overtorment committed Feb 24, 2021
1 parent f3ceb7e commit 79ad7bd
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 20 deletions.
6 changes: 2 additions & 4 deletions class/wallets/legacy-wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -452,17 +452,15 @@ export class LegacyWallet extends AbstractWallet {
* @returns {boolean|string} Either p2pkh address or false
*/
static scriptPubKeyToAddress(scriptPubKey) {
const scriptPubKey2 = Buffer.from(scriptPubKey, 'hex');
let ret;
try {
ret = bitcoin.payments.p2pkh({
const scriptPubKey2 = Buffer.from(scriptPubKey, 'hex');
return bitcoin.payments.p2pkh({
output: scriptPubKey2,
network: bitcoin.networks.bitcoin,
}).address;
} catch (_) {
return false;
}
return ret;
}

weOwnAddress(address) {
Expand Down
20 changes: 11 additions & 9 deletions class/wallets/segwit-bech32-wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ export class SegwitBech32Wallet extends LegacyWallet {
}

static witnessToAddress(witness) {
const pubKey = Buffer.from(witness, 'hex');
return bitcoin.payments.p2wpkh({
pubkey: pubKey,
network: bitcoin.networks.bitcoin,
}).address;
try {
const pubKey = Buffer.from(witness, 'hex');
return bitcoin.payments.p2wpkh({
pubkey: pubKey,
network: bitcoin.networks.bitcoin,
}).address;
} catch (_) {
return false;
}
}

/**
Expand All @@ -40,17 +44,15 @@ export class SegwitBech32Wallet extends LegacyWallet {
* @returns {boolean|string} Either bech32 address or false
*/
static scriptPubKeyToAddress(scriptPubKey) {
const scriptPubKey2 = Buffer.from(scriptPubKey, 'hex');
let ret;
try {
ret = bitcoin.payments.p2wpkh({
const scriptPubKey2 = Buffer.from(scriptPubKey, 'hex');
return bitcoin.payments.p2wpkh({
output: scriptPubKey2,
network: bitcoin.networks.bitcoin,
}).address;
} catch (_) {
return false;
}
return ret;
}

/**
Expand Down
14 changes: 8 additions & 6 deletions class/wallets/segwit-p2sh-wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ export class SegwitP2SHWallet extends LegacyWallet {
static typeReadable = 'SegWit (P2SH)';

static witnessToAddress(witness) {
const pubKey = Buffer.from(witness, 'hex');
return pubkeyToP2shSegwitAddress(pubKey);
try {
const pubKey = Buffer.from(witness, 'hex');
return pubkeyToP2shSegwitAddress(pubKey);
} catch (_) {
return false;
}
}

/**
Expand All @@ -32,17 +36,15 @@ export class SegwitP2SHWallet extends LegacyWallet {
* @returns {boolean|string} Either p2sh address or false
*/
static scriptPubKeyToAddress(scriptPubKey) {
const scriptPubKey2 = Buffer.from(scriptPubKey, 'hex');
let ret;
try {
ret = bitcoin.payments.p2sh({
const scriptPubKey2 = Buffer.from(scriptPubKey, 'hex');
return bitcoin.payments.p2sh({
output: scriptPubKey2,
network: bitcoin.networks.bitcoin,
}).address;
} catch (_) {
return false;
}
return ret;
}

getAddress() {
Expand Down
7 changes: 6 additions & 1 deletion screen/transactions/CPFP.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,12 @@ export default class CPFP extends Component {
newFeeRate: '',
nonReplaceable: false,
});
await this.checkPossibilityOfCPFP();
try {
await this.checkPossibilityOfCPFP();
} catch (_) {
// if anything goes wrong we just show "this is not bumpable" message
this.setState({ nonReplaceable: true, isLoading: false });
}
}

async checkPossibilityOfCPFP() {
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/hd-segwit-p2sh-wallet.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,38 @@ it('can create a Segwit HD (BIP49)', async function () {
it('can convert witness to address', () => {
let address = SegwitP2SHWallet.witnessToAddress('035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8');
assert.strictEqual(address, '34ZVGb3gT8xMLT6fpqC6dNVqJtJmvdjbD7');
address = SegwitP2SHWallet.witnessToAddress();
assert.strictEqual(address, false);
address = SegwitP2SHWallet.witnessToAddress('trololo');
assert.strictEqual(address, false);

address = SegwitP2SHWallet.scriptPubKeyToAddress('a914e286d58e53f9247a4710e51232cce0686f16873c87');
assert.strictEqual(address, '3NLnALo49CFEF4tCRhCvz45ySSfz3UktZC');
address = SegwitP2SHWallet.scriptPubKeyToAddress();
assert.strictEqual(address, false);
address = SegwitP2SHWallet.scriptPubKeyToAddress('trololo');
assert.strictEqual(address, false);

address = SegwitBech32Wallet.witnessToAddress('035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8');
assert.strictEqual(address, 'bc1quhnve8q4tk3unhmjts7ymxv8cd6w9xv8wy29uv');
address = SegwitBech32Wallet.witnessToAddress();
assert.strictEqual(address, false);
address = SegwitBech32Wallet.witnessToAddress('trololo');
assert.strictEqual(address, false);

address = SegwitBech32Wallet.scriptPubKeyToAddress('00144d757460da5fcaf84cc22f3847faaa1078e84f6a');
assert.strictEqual(address, 'bc1qf46hgcx6tl90snxz9uuy0742zpuwsnm27ysdh7');
address = SegwitBech32Wallet.scriptPubKeyToAddress();
assert.strictEqual(address, false);
address = SegwitBech32Wallet.scriptPubKeyToAddress('trololo');
assert.strictEqual(address, false);

address = LegacyWallet.scriptPubKeyToAddress('76a914d0b77eb1502c81c4093da9aa6eccfdf560cdd6b288ac');
assert.strictEqual(address, '1L2bNMGRQQLT2AVUek4K9L7sn3SSMioMgE');
address = LegacyWallet.scriptPubKeyToAddress();
assert.strictEqual(address, false);
address = LegacyWallet.scriptPubKeyToAddress('trololo');
assert.strictEqual(address, false);
});

it('Segwit HD (BIP49) can generate addressess only via ypub', function () {
Expand Down

0 comments on commit 79ad7bd

Please sign in to comment.